Advertisement
Guest User

Untitled

a guest
May 26th, 2019
391
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 97.91 KB | None | 0 0
  1.  
  2. /*jshint esversion: 6 */
  3. /*jslint browser: true */
  4. /*global window */
  5. /*global console */
  6. /*global HBInit */
  7.  
  8. // TODO: MOTM
  9. // red "🌿🔴[EFC Futsal] ◻️ discord.gg/jTn2ZDp" "code": "eu", "lat": 48.1371535, "lon": 11.5761235};
  10. // bleu "🌿🔵[EFC Futsal] ◻️ Sign up & Register" "code": "eu", "lat": 48.1371545, "lon": 11.5761245};
  11. // white "🌿⚪[EFC Futsal] ◻️ Play with friends" "code": "eu", "lat": 48.1371540, "lon": 11.5761240};
  12. // black "🌿⚫[EFC Futsal] ◻️ New Season 4" "code": "eu", "lat": 48.1371540, "lon": 11.5761240};
  13. // orange 🌿☢️[EFC Futsal] ◻️ Join us !" "code": "eu", "lat": 48.1371550, "lon": 11.5761250};
  14. var MAX_PLAYERS = 14;
  15.  
  16. let geo = {"code": "eu", "lat": 48.1371550, "lon": 11.5761250};
  17. var room = HBInit({ roomName: "🌿☢️[EFC Futsal] ◻️ Join us !",
  18. playerName: "EFC", maxPlayers: MAX_PLAYERS, public: true, geo });
  19.  
  20. let first_stadium_loaded = false;
  21. room.setDefaultStadium("Classic");
  22. room.setScoreLimit(3);
  23. room.setTimeLimit(3);
  24. room.setTeamsLock(true);
  25.  
  26.  
  27.  
  28.  
  29. class Player {
  30. constructor(name) {
  31. this.name = name;
  32. /*************************************
  33. ************ Individual stats**********
  34. **************************************/
  35. this.goals = 0; /* Number of goals */
  36. this.assists = 0; /* Number of assists */
  37. this.cs = 0; /* Number of cleensheets */
  38. this.ownGoals = 0; /* Number of own goals */
  39. this.wins = 0; /* Number of wins */
  40. this.loses = 0; /* Number of loses */
  41. this.motm = 0; /* Number of time a player is the man of the match */
  42. this.playedGk = 0;
  43.  
  44. this.badPasses = 0; /* Number of passes */
  45. this.goodPasses = 1; /* Number of passes that reached a team mate */
  46. this.passAcc = 0; /* Pass accuracy % */
  47. this.motmRatio = 0; /* Man of the match % */
  48. this.winsRatio = 0; /* Wins / Loses */
  49. this.csPG = 0; /* CS % per game */
  50. this.goalsPG = 0; /* Number of goals per game */
  51. this.assistsPG = 0; /* Number of assists per game */
  52. this.elo = 1000; /* ELO */
  53.  
  54. this.secsPlayed = 0; /* Number of mins played */
  55. this.minsPlayed = 0; /* Number of mins played */
  56. this.currentStreak = 0; /* Number of current matches won in a row */
  57. this.bestStreak = 0; /* Number of maximum amount of wins in a row */
  58. this.statsString1 = "";
  59. this.statsString2 = "";
  60. this.statsString3 = "";
  61. /*************************************
  62. ************ Haxball manager**********
  63. **************************************/
  64. this.price = 10;
  65. this.money = 100;
  66. this.currentBet = 0;
  67. this.winPred = 0;
  68. this.dreamTeam = {"gk": null, "dm": null, "am": null, "st": null};
  69. this.teamScore = 0;
  70.  
  71. /*************************************
  72. ************ Revelant to the room*****
  73. **************************************/
  74. this.team = 0;
  75. this.gotKicked = 0; /* Number of time this player got kicked by another player */
  76. this.kickedSomeone = 0; /* Number of time this player kicked someone */
  77. this.id = 0; /* Current player's id on the room */
  78. this.pw = 0; /* Password for player's account */
  79. this.isTrustedAdmin = 0; /* Whether he's a trusted admin */
  80. this.logged = 1; /* 0 if the player is not in the room, 1 if he's */
  81. this.isBanned = 0; /* Whether a player is banned */
  82. this.isPermaBanned = 0; /* Whether a player is banned permanently*/
  83. this.isRegistered = 0; /* Whether a player is registered (e.g. his stats will count) */
  84. this.auth = 0; /* Player's last auth */
  85. this.conn = 0; /* Player's last conn */
  86. this.isMuted = 0; /* Whether a player is muted */
  87. this.isAFK = false;
  88. }
  89.  
  90.  
  91. updateGoals(){
  92. if (gameStats.scorers.hasOwnProperty(this.name))
  93. this.goals += gameStats.scorers[this.name];
  94. }
  95. updateAssists(){
  96. if (gameStats.assisters.hasOwnProperty(this.name))
  97. this.assists += gameStats.assisters[this.name];
  98. }
  99. updateCs(){
  100. let [team, idteam] = this.team === 1 ? ["blueScore", 1] : ["redScore", 2];
  101. this.cs += gameStats[team] === 0 &&
  102. this.name === gameStats.Gks[idteam - 1];
  103. }
  104. updateOG(){
  105. if (gameStats.ownScorers.hasOwnProperty(this.name))
  106. this.ownGoals += gameStats.ownScorers[this.name];
  107. }
  108. updatePlayedGk(){
  109. this.playedGk += gameStats.Gks.includes(this.name);
  110. }
  111. updateWins(winningTeam){
  112. this.wins += this.team === winningTeam;
  113. }
  114.  
  115. updateLoses(losingTeam){
  116. this.loses += this.team === losingTeam;
  117. }
  118. updateWinRatio(){
  119. this.winsRatio = ((this.wins / (this.wins + this.loses)) * 100).toFixed(2) || 0;
  120. }
  121. updateGoalsPG(){
  122. this.goalsPG = (this.goals / (this.loses + this.wins)).toFixed(2) || 0;
  123. }
  124. updateAssistsPG(){
  125. this.assistsPG = (this.assists / (this.loses + this.wins)).toFixed(2) || 0;
  126. }
  127. updateCSPG(){
  128. this.csPG = ((this.cs / this.playedGk) * 100).toFixed(2) || 0;
  129. }
  130. updateCurrentStreak(won){
  131. this.currentStreak = won === this.team ? this.currentStreak + 1 : 0;
  132. }
  133.  
  134. updateBestStreak(){
  135. this.bestStreak = this.currentStreak >= this.bestStreak ?
  136. this.currentStreak : this.bestStreak;
  137. }
  138. updateSecsPlayed(){
  139. this.secsPlayed += Number(((this.team !== 0) / 60).toFixed(2));
  140. }
  141. updateMinsPlayed(){
  142. this.minsPlayed = Math.floor((this.secsPlayed / 60));
  143. }
  144.  
  145. updatePassAccuracy(){
  146. this.passAcc = ((this.goodPasses / (this.goodPasses + this.badPasses)) * 100).toFixed(2);
  147. }
  148. updateKickedSomeone(){
  149. this.kickedSomeone += this.isTrustedAdmin === 0;
  150. }
  151. updatePassword(m){
  152. this.pw = m;
  153. }
  154. updateMoney(won){
  155. let diff = won == this.winPred ? this.currentBet : -1 * this.currentBet;
  156. this.money += diff;
  157. room.sendChat("By your bet you got " + diff + " EFCOINS", this.id);
  158. this.currentBet = 0;
  159. this.winPred = 0;
  160. }
  161. disconnect(){
  162. this.logged = 0;
  163. this.isTrustedAdmin = 0;
  164. this.price = 0;
  165. }
  166.  
  167. statsToString(){
  168. this.statsString1 = " | Goals: " + this.goals + " | Assists: " + this.assists +
  169. " | Own goals: " + this.ownGoals + " | cs: " + this.cs +
  170. " | Wins: " + this.wins + " | Losses: " + this.loses;
  171.  
  172. this.statsString2 = " | MOTM: " + "[Soon]" +
  173. " | MOTMR: " + "[Soon]" + " | W/L %: " + this.winsRatio +
  174. " | Pass acc %: " + this.passAcc + " | Elo: " + this.elo;
  175.  
  176. this.statsString3 = " | GPG: " + this.goalsPG + " | APG: " + this.assistsPG +
  177. " | csPG %: " + this.csPG + " | Best streak: " + this.bestStreak +
  178. " | Mins: " + this.minsPlayed + "| EFCOINS: " + this.money;
  179. }
  180. displayStats(query_id){
  181. this.statsToString();
  182. room.sendChat(this.statsString1, query_id);
  183. room.sendChat(this.statsString2, query_id);
  184. room.sendChat(this.statsString3, query_id);
  185. this.statsString1 = this.statsString2 = this.statsString3 = "";
  186. }
  187. updateEGStats(){
  188. let winners = gameStats.redScore > gameStats.blueScore ? 1 : 2;
  189. let losers = 1 + (winners === 1);
  190. this.updateGoals();
  191. this.updateAssists();
  192. this.updateOG();
  193. this.updateWins(winners);
  194. this.updateLoses(winners - 1);
  195. this.updatePlayedGk();
  196.  
  197.  
  198. this.updateWinRatio();
  199. this.updateGoalsPG();
  200. this.updateAssistsPG();
  201. this.updateCSPG();
  202. this.updatePassAccuracy();
  203. this.updateCurrentStreak(winners);
  204. this.updateBestStreak(winners);
  205. this.updateCs();
  206. this.updateMoney(winners);
  207. }
  208. }
  209.  
  210.  
  211.  
  212.  
  213. class GameStats {
  214. constructor() {
  215. this.redScore = 0; /* Number of goals red team scored this match */
  216. this.blueScore = 0; /* Number of goals blue team scored this match */
  217. this.Gks = ["", ""]; /* Name of the gks */
  218. this.scorers = {}; /* {name: number_of_goals_scored} */
  219. this.assisters = {}; /* {name: number_of_assists} */
  220. this.ownScorers = {}; /* {name: number_of_own_goals} */
  221. this.redTeam = []; /* [name of the players in red team] */
  222. this.blueTeam = []; /* [name of the players in blue team] */
  223. this.matchsumup = [];
  224. this.isOvertime = false;
  225. this.hasStarted = false;
  226. this.rec = false;
  227. }
  228. updateScore(team){
  229. this.redScore += team === 1;
  230. this.blueScore += team === 2;
  231. }
  232.  
  233. updateGK(){
  234. var players = room.getPlayerList();
  235. var min = players[0];
  236. min.position = {x: room.getBallPosition().x + 60};
  237. var max = min;
  238.  
  239. for (var i = 1; i < players.length; i++) {
  240. if (players[i].position !== null){
  241. if (min.position.x > players[i].position.x) min = players[i];
  242. if (max.position.x < players[i].position.x) max = players[i];
  243. }
  244. }
  245. this.Gks = [min.name, max.name];
  246. }
  247. updateScorers(p, team){
  248. if (p !== undefined && p.team === team) updateObject(this.scorers, p);
  249. }
  250. updateAssisters(p, team){
  251. if (p !== undefined && p.team === team) updateObject(this.assisters, p);
  252. }
  253. updateOwnScorers(p, team){
  254. if (p.team !== team) updateObject(this.ownScorers, p);
  255. }
  256.  
  257. updateRedTeam(){
  258. this.redTeam = room.getPlayerList().filter(player => player.team === 1);
  259. }
  260. updateBlueTeam(){
  261. this.blueTeam = room.getPlayerList().filter(player => player.team === 2);
  262. }
  263. updateOvertime(){
  264. this.isOvertime = true;
  265. }
  266. sumMatch(p){
  267. if (lastMatchSumUp.length === 0) return;
  268. let last_match = lastMatchSumUp.length - 1;
  269. let last_match_length = lastMatchSumUp[last_match].length;
  270. for (var i = 0; i < last_match_length; i++){
  271. room.sendChat(lastMatchSumUp[last_match][i], p.id);
  272. }
  273. }
  274.  
  275. }
  276.  
  277.  
  278.  
  279. class GameControl {
  280. constructor(radiusBall) {
  281. this.radiusBall = radiusBall || 10;
  282. this.triggerDistance = this.radiusBall + 15 + 0.1;
  283. this.currentBallOwner = "";
  284. this.lastBallOwners = ["", ""]; /* [name: name] */
  285. this.passesInARow = {"red": 0, "blue": 0}; /* {team: max} */
  286. this.maxPassesInARow = 0;
  287. this.redPoss = 0;
  288. this.bluePoss = 0;
  289. this.smth = "";
  290. }
  291. resetBallOwner(){
  292. this.currentBallOwner = "";
  293. this.lastBallOwners = ["", ""];
  294. }
  295. updateBallOwner(){
  296. var ballPosition = room.getBallPosition();
  297. var players = room.getPlayerList();
  298. var distanceToBall;
  299. for (var i = 0; i < players.length; i++) {
  300. if (players[i].position != null) {
  301. distanceToBall = pointDistance(players[i].position, ballPosition);
  302. if (distanceToBall < this.triggerDistance) {
  303. this.currentBallOwner = players[i].name;
  304. }
  305. }
  306. }
  307. }
  308. updateLastBallOwners(){
  309. if (this.currentBallOwner !== "" &&
  310. this.currentBallOwner !== this.lastBallOwners[0]){
  311.  
  312. this.lastBallOwners[1] = this.lastBallOwners[0];
  313. this.lastBallOwners[0] = this.currentBallOwner; // last player who touched the ball
  314. }
  315. }
  316. updatePassesInARow(){
  317. if (gameStats.redTeam.length !== gameStats.blueTeam.length ||
  318. gameStats.redTeam.length < 2) return;
  319.  
  320. if (this.lastBallOwners[1] !== "" && this.smth !== this.currentBallOwner){
  321.  
  322. if (Stats[this.lastBallOwners[0]].team ===
  323. Stats[this.lastBallOwners[1]].team){
  324.  
  325. Stats[this.lastBallOwners[1]].goodPasses++;
  326.  
  327.  
  328. if (Stats[this.lastBallOwners[0]].team === 1){
  329. this.passesInARow.red += 1;
  330. this.updateMaxPassesInARow("blue");
  331. this.passesInARow.blue = 0;
  332. }
  333. else {
  334. this.passesInARow.blue += 1;
  335. this.updateMaxPassesInARow("red");
  336. this.passesInARow.red = 0;
  337.  
  338. }
  339. }
  340. else {
  341. Stats[this.lastBallOwners[1]].badPasses++;
  342. }
  343.  
  344. this.smth = this.currentBallOwner;
  345. }
  346. }
  347. updateMaxPassesInARow(team){
  348. this.maxPassesInARow = this.passesInARow[team] > this.maxPassesInARow ?
  349. this.passesInARow[team] : this.maxPassesInARow;
  350. }
  351. }
  352.  
  353.  
  354. class Records {
  355. constructor() {
  356. this.bestPassesInARow = 0;
  357. this.bestAccuracy = "";
  358. this.bestStreak = {}; /*{[team]: score};*/
  359. this.fastestWin = 0;
  360. this.longestMatch = 0;
  361. }
  362. updateBestPassesInARow(){
  363. this.bestPassesInARow = this.maxPassesInARow > this.bestPassesInARow ?
  364. this.passesInARow : this.bestPassesInARow;
  365.  
  366. }
  367. }
  368.  
  369. class ELO {
  370. constructor() {
  371. this.redAverage = 0;
  372. this.blueAverage = 0;
  373. this.redChanceToWin = 0;
  374. this.blueChanceToWin = 0;
  375. this.redRating = 0;
  376. this.blueRating = 0;
  377. }
  378. getAverageRank(team){
  379. let average = 0;
  380. for (var i = 0; i < team.length; i++) {
  381. average += Stats[team[i].name].elo;
  382. }
  383. return average / team.length;
  384. }
  385. updateTeamAverages(){
  386. this.redAverage = this.getAverageRank(gameStats.redTeam);
  387. this.blueAverage = this.getAverageRank(gameStats.blueTeam);
  388. }
  389. updateChancesToWin(){
  390. this.redChanceToWin = 1 / ( 1 + Math.pow(10, (this.blueAverage - this.redAverage) / 400));
  391. this.blueChanceToWin = 1 / ( 1 + Math.pow(10, (this.redAverage - this.blueAverage) / 400));
  392. }
  393. updateRating(rwin, bwin){
  394. this.redRating = Math.round(32 * (rwin - this.redChanceToWin));
  395. this.blueRating = Math.round(32 * (bwin - this.blueChanceToWin));
  396. }
  397. handleEloCalc(){
  398. this.updateTeamAverages();
  399. this.updateChancesToWin();
  400. }
  401. updateElo(){
  402. if (gameStats.redTeam.length === gameStats.blueTeam.length){
  403. let winners = gameStats.redScore > gameStats.blueScore;
  404. let pr, pb;
  405. this.updateRating(winners, !winners);
  406. for (var i = 0; i < gameStats.redTeam.length; i++) {
  407. pr = gameStats.redTeam[i].name;
  408. pb = gameStats.blueTeam[i].name;
  409.  
  410. Stats[pr].elo += this.redRating;
  411. Stats[pb].elo += this.blueRating;
  412. }
  413. }
  414. }
  415. }
  416.  
  417. /**************************************************************
  418. * ************************** ADMINS ************************
  419. ***************************************************************/
  420.  
  421. var headAdminsAuths = {
  422. "NzfxVorXRRJsvwtJdwCOhKkdoQxvKk_e-HOXVtMkaC0": "Mona1",
  423. "FD7dcGdmO0W4TdrP7T6m57xzcFtoDl05MOu5sxHdwx0": "Kang1",
  424.  
  425.  
  426. };
  427.  
  428. var roomAdminsAuth = {
  429. "NzfxVorXRRJsvwtJdwCOhKkdoQxvKk_e-HOXVtMkaC0": "Mona1",
  430. "FD7dcGdmO0W4TdrP7T6m57xzcFtoDl05MOu5sxHdwx0": "Kang1",
  431. "dOKIGfR8z70iF3KxsXS5zNkvg1Xaj-fC4ocgX9JrtNQ": "Common",
  432. "D2BOPzz1QJg0KOco6LHgPVwgrbZdCMjDC3AsVxswaMM": "DbK1"
  433.  
  434. };
  435.  
  436.  
  437. function getRandomInt(max) {
  438. return Math.floor(Math.random() * Math.floor(max));
  439. }
  440.  
  441.  
  442. var adminSelect = ["goals", "assists", "cs", "wins", "elo", "bestStreak", "minsPlayed", "money"];
  443.  
  444.  
  445. function updateAdmins() {
  446. var players = room.getPlayerList().filter((player) => player.id != 0);
  447. var admins = room.getPlayerList().filter((player) => player.id != 0 && player.admin == false);
  448. if (players.length == 0 || admins.length == 0 || players.length - admins.length >= 2) return;
  449. let select = adminSelect[getRandomInt(adminSelect.length - 1)];
  450.  
  451. admins.sort(function(a, b){
  452. return Stats[b.name][select] - Stats[a.name][select];
  453. });
  454. room.setPlayerAdmin(admins[0].id, true);
  455.  
  456. }
  457.  
  458. function updateSelectedAdmins(){
  459. var players = room.getPlayerList().filter((p) => p.id != 0 && p.admin === true);
  460. for (var i = 0; i < players.length; i++) {
  461. room.setPlayerAdmin(players[i].id,
  462. Stats[players[i].name].isTrustedAdmin >= 1);
  463. }
  464. }
  465.  
  466.  
  467. function superAdmin(p){
  468. if (headAdminsAuths.hasOwnProperty(Stats[p.name].auth)){
  469. var players = room.getPlayerList().filter((p) => p.admin === true);
  470. for (var i = 0; i < players.length; i++) {
  471. room.setPlayerAdmin(players[i].id,
  472. Stats[players[i].name].isTrustedAdmin >= 1);
  473. }
  474. room.setPlayerAdmin(p.id, true);
  475. Stats[p.name].isTrustedAdmin = 3;
  476. room.sendChat("You got level 3 admin ! ", p.id);
  477. }
  478. return false;
  479. }
  480.  
  481. function getAdmin(p, m){
  482. if (roomAdminsAuth.hasOwnProperty(Stats[p.name].auth)){
  483. room.setPlayerAdmin(p.id, true);
  484. Stats[p.name].isTrustedAdmin = 1;
  485. room.sendChat("You got level 1 admin ! ", p.id);
  486. }
  487. return false;
  488. }
  489.  
  490. function getAdmin2(p, m){
  491. if (headAdminsAuths.hasOwnProperty(Stats[p.name].auth)){
  492. room.setPlayerAdmin(p.id, true);
  493. Stats[p.name].isTrustedAdmin = 2;
  494. room.sendChat("You got level 2 admin ! ", p.id);
  495. }
  496. return false;
  497. }
  498.  
  499. function addAdmin(p, m){
  500. if (Stats[p.name].isTrustedAdmin >= 2){
  501. m = m.substr("!addadmin".length + 1);
  502. roomAdminsAuth[Stats[m].auth] = m;
  503. room.sendChat("Succes.", p.id);
  504. }
  505. return false;
  506. }
  507.  
  508.  
  509. /**************************************************************
  510. * ************************** ANTI SPAM ************************
  511. * Function to call: handleSpam in room.onPlayerChat with
  512. * lastWriters and player as argument.
  513. * Purpose: This will kick a player after he talks 5 times
  514. * in a row.
  515. * Based on: player's id.
  516. * To change the number of chats allowed in a row, change the
  517. * const MAX_CHAT_IN_A_ROW to what you want.
  518. * Global variables used:
  519. * lastWriters (array of int)
  520. * const int MAX_CHAT_IN_A_ROW
  521. * const string KICK_MESSAGE_SPAM
  522. ***************************************************************/
  523. var lastWriters = [];
  524. const MAX_CHAT_IN_A_ROW = 5;
  525. const KICK_MESSAGE_SPAM = "Stop spamming! Thanks.";
  526.  
  527. /**************************************************************
  528. * Function returning how much time the last player who wrote
  529. * in chat has previously written.
  530. ***************************************************************/
  531.  
  532. function checkSpam(lastWriters, p){
  533. let c = 0;
  534. for (var i = 0; i < lastWriters.length; i++){
  535. c += lastWriters[i] === p.id;
  536. }
  537. return c;
  538. }
  539.  
  540. /**************************************************************
  541. * Function updating the array by deleting the first element
  542. * and adding the last player who talked.
  543. ***************************************************************/
  544. function updateLastWriters(lastWriters, p){
  545. lastWriters.splice(0, 1);
  546. lastWriters.push(p.id);
  547.  
  548. }
  549.  
  550. /**************************************************************
  551. * Function updating the array and kicking a spammer with the
  552. * message KICK_MESSAGE_SPAM.
  553. * When the array's length is smaller than MAX_CHAT_IN_A_ROW
  554. * (so at the beginning of a room) it doesnt check spam
  555. * but simply fills it.
  556. ***************************************************************/
  557.  
  558.  
  559. function handleSpam(lastWriters, p){
  560. if (lastWriters.length === MAX_CHAT_IN_A_ROW){
  561. updateLastWriters(lastWriters, p);
  562. let res = checkSpam(lastWriters, p);
  563.  
  564. if (res === MAX_CHAT_IN_A_ROW){
  565. room.kickPlayer(p.id, KICK_MESSAGE_SPAM, 0);
  566. }
  567. }
  568. else {
  569. lastWriters.push(p.id);
  570. }
  571. }
  572.  
  573.  
  574. /**************************************************************
  575. * ************************** SWAP *****************************
  576. * Function to call: swap
  577. * If it's used as a command, the parameter has to be an admin player.
  578. * Otherwise this function can just be called with no param to work.
  579. * This function put the red (resp blue) team into blue (resp red).
  580. * Global variable used: None.
  581. ***************************************************************/
  582.  
  583.  
  584. function swap(player){
  585. if (player === undefined || player.admin){
  586. var p = room.getPlayerList().filter((player) => player.id != 0);
  587. for (let i = 0; i < p.length; i++){
  588. if (p[i].team !== 0){
  589. room.setPlayerTeam(p[i].id, 1 + (p[i].team === 1));
  590. }
  591. }
  592. }
  593. }
  594.  
  595.  
  596. /**************************************************************
  597. * ************************** PM *******************************
  598. * Function to call: sendPM.
  599. * Use: @player [message]
  600. * This function will send a private message to the player.
  601. * Global variable used: None.
  602. ***************************************************************/
  603.  
  604. function sendPM(p, m){
  605. if (m.startsWith("@") === true){
  606. let spacePos = m.search(" ");
  607. let name = m.substr(1, spacePos !== -1 ? spacePos - 1: m.length);
  608. let dest = room.getPlayerList().filter((p) => p.name === name);
  609. if (dest.length !== 0){
  610. m = m.substr(spacePos, m.length);
  611. room.sendChat("PM from " + p.name + ": " + m, dest[0].id);
  612. }
  613. return false;
  614. }
  615. return true;
  616. }
  617.  
  618. /**************************************************************
  619. * ************************** Resets ****************************
  620. * Functions to call: reset and resetWithSwap.
  621. * If it's used as a command, the parameter has to be an admin player.
  622. * Otherwise this function can just be called with no param to work.
  623. * These functions allow to reset the game by typing !rr
  624. * And to reset the game by switching teams by typing !rrs
  625. * Global variables used: None
  626. ***************************************************************/
  627.  
  628. function reset(p){
  629. if (p === undefined || p.admin === true){
  630. room.stopGame();
  631. room.startGame();
  632. }
  633. }
  634.  
  635. function resetWithSwap(p){
  636. if (p === undefined || p.admin === true){
  637. room.stopGame();
  638. swap();
  639. room.startGame();
  640. }
  641. }
  642. function resetWithTop(p){
  643. if (p === undefined || p.admin === true){
  644. room.stopGame();
  645. let specs = room.getPlayerList().filter((p) => p.id !== 0 && p.team === 0);
  646. if (specs.length !== 0){
  647. room.setPlayerTeam(specs[0], p.team === 1 ? 2 : 1);
  648. }
  649. room.startGame();
  650. }
  651. }
  652.  
  653. /**************************************************************
  654. * ************************** ACCOUNT **************************
  655. * Function to call: almost all of theses are commands.
  656. * These functions will simulate a way to have an account in the room.
  657. * To further details, read the documentation of each function.
  658. * There can be only one account per nickname.
  659. * Global variables used: Stats {name: p | p € class Player }
  660. ***************************************************************/
  661. var Stats = {};
  662. const saveStatsName = "Players_stats";
  663. var saveStatsN = 0;
  664. function loadStats(){
  665. if (localStorage.getItem(saveStatsName + saveStatsN)){
  666. let all = JSON.parse(localStorage.getItem(saveStatsName + saveStatsN));
  667. let noms = Object.keys(all);
  668. for (let i = 0; i < noms.length; i++){
  669. Stats[noms[i]] = new Player(noms[i]);
  670. Object.assign(Stats[noms[i]], all[noms[i]]);
  671. }
  672. }
  673. }
  674.  
  675.  
  676. function saveStatsFun(){
  677. var val = JSON.stringify(Stats);
  678. window.localStorage.setItem(saveStatsName + saveStatsN, val);
  679. }
  680.  
  681.  
  682. function deleteStatsFun(){
  683. saveStatsN++;
  684. Stats = {};
  685. }
  686.  
  687.  
  688. /**************************************************************
  689. * Function creating a new account for the player if this nick
  690. * never been to the room.
  691. * Also logs him and get his current id.
  692. ***************************************************************/
  693. function autoConnect(p){
  694. if (Stats.hasOwnProperty(p.name) === false){
  695. Stats[p.name] = new Player(p.name);
  696. Stats[p.name].auth = p.auth;
  697. }
  698. else {
  699. if (Stats[p.name].auth != 0 && p.auth !== Stats[p.name].auth){
  700. Stats[p.name].price = 1;
  701. room.sendChat("Your stats won't count because this nick is already taken by someone with a different id", p.id);
  702. }
  703. else if (Stats[p.name].auth == 0){
  704. Stats[p.name].auth = p.auth;
  705. }
  706. }
  707. Stats[p.name].logged = 1;
  708. Stats[p.name].id = p.id;
  709. Stats[p.name].conn = p.conn;
  710. }
  711.  
  712.  
  713.  
  714. function stats(p, m){
  715. m = m.substr("!stats".length + 1);
  716. if (Stats.hasOwnProperty(m)){
  717. Stats[m].displayStats(p.id);
  718. }
  719. else {
  720. room.sendChat("This player is not in our database.", p.id);
  721. }
  722. return false;
  723. }
  724.  
  725.  
  726. var msg_to_command = {
  727. "goals": "goals",
  728. "assists": "assists",
  729. "og": "ownGoals",
  730. "cs": "cs",
  731. "wins": "wins",
  732. "losses": "loses",
  733. "wl": "winsRatio",
  734. "passacc": "passAcc",
  735. "elo": "elo",
  736. "gpg": "goalsPG",
  737. "apg": "assistsPG",
  738. "cspg": "csPG",
  739. "streak": "bestStreak",
  740. "mins": "minsPlayed",
  741. "efcoins": "money",
  742. };
  743.  
  744.  
  745.  
  746.  
  747. function bestRanks(message){
  748. if (!msg_to_command.hasOwnProperty(message))
  749. return "This option does not exist (yet ?), sorry :(. See !rankhelp to further infos.";
  750.  
  751. let cmd = msg_to_command[message];
  752. let names = Object.keys(Stats);
  753. let score;
  754. let string = "";
  755. let overall = [];
  756. for (var i = 0; i < names.length; i++) {
  757. if (!Stats.hasOwnProperty(names[i])) continue;
  758. score = Stats[names[i]][cmd];
  759. if (score === 1000 || score === 0 ||
  760. (Stats[names[i]].wins + Stats[names[i]].loses) < 10) continue;
  761.  
  762. overall.push({name: names[i], value: score});
  763. }
  764. overall.sort(function(a,b){
  765. return b.value - a.value;
  766. });
  767. for (i = 0; i < overall.length; i++) {
  768. string += i + 1 + ") " + overall[i].name + ": " + overall[i].value + " | ";
  769. }
  770. return string;
  771. }
  772.  
  773.  
  774.  
  775. function ranking(p, m){
  776. let string = bestRanks(m.substr("!rank".length + 1));
  777. let line1 = string.substring(0, 120);
  778. let line2 = string.substring(120, 240);
  779. let line3 = string.substring(240, 360);
  780. room.sendChat(line1, p.id);
  781. room.sendChat(line2, p.id);
  782. room.sendChat(line3, p.id);
  783. return false;
  784. }
  785.  
  786. /**************************************************************
  787. * Function as a command: !bb
  788. * Kicks the player from the room with disconnecting him
  789. * (the disconnect thing is pretty useless since it is caught
  790. * in the onPlayerLeave anyway).
  791. ***************************************************************/
  792. function bb(p){
  793. Stats[p.name].disconnect();
  794. room.kickPlayer(p.id, "rip !", false);
  795. }
  796.  
  797.  
  798. /**************************************************************
  799. * ************************** MUTE ****************************
  800. * Global variable used: None
  801. ***************************************************************/
  802. function mute(p, m){
  803. if (p === undefined || Stats[p.name].isTrustedAdmin >= 1){
  804. m = m.substr("!mute".length + 1);
  805. if (Stats.hasOwnProperty(m)) {
  806. Stats[m].isMuted = 1;
  807. room.sendChat(m + " has been muted by " + p.name);
  808. }
  809. }
  810. return false;
  811. }
  812.  
  813. function muteById(p, m){
  814. m = idToName(m.substr("!muteid".length + 1));
  815. return mute(p, "!mute " + m);
  816. }
  817.  
  818.  
  819. function unmute(p, m){
  820. if (p === undefined || Stats[p.name].isTrustedAdmin >= 1){
  821. m = m.substr("!unmute".length + 1);
  822. if (Stats.hasOwnProperty(m)) {
  823. Stats[m].isMuted = 0;
  824. room.sendChat(m + " has been unmuted by " + p.name);
  825. room.sendChat(m + " has been unmuted by " + p.name, Stats[m].id);
  826. }
  827. }
  828. return false;
  829. }
  830.  
  831. function unmuteById(p, m){
  832. m = idToName(m.substr("!unmuteid".length + 1));
  833. return unmute(p, "!unmute " + m);
  834. }
  835.  
  836. function muteAll(p, m){
  837. if (p === undefined || Stats[p.name].isTrustedAdmin >= 1){
  838. var players = room.getPlayerList().filter((pl) => pl.admin === false &&
  839. pl.team === 0);
  840. for (var i = 0; i < players.length; i++) {
  841.  
  842. Stats[players[i].name].isMuted = 1;
  843. }
  844. room.sendChat("All non-admins specs have been muted");
  845. }
  846. }
  847.  
  848. function resetMutes(p){
  849. if (p === undefined || p.admin === true){
  850. var players = room.getPlayerList();
  851. for (var i = 1; i < players.length; i++) {
  852. Stats[players[i].name].isMuted = 0;
  853. }
  854. }
  855. return false;
  856. }
  857.  
  858. /**************************************************************
  859. * ************************** BANS ****************************
  860. * Function to call: almost all of theses are commands.
  861. * These functions are set in order to ban toxic people.
  862. * This includes simple bans, simple clearing bans but also
  863. * permaban that can be only disabled by the vps owner.
  864. * In order to make this last feature work, room.clearBans is
  865. * never used.
  866. * Global variables used: None.
  867. ***************************************************************/
  868.  
  869. function permaBan(p, m){
  870. if (p === undefined || Stats[p.name].isTrustedAdmin >= 2){
  871.  
  872. m = m.substr("!permaban".length + 1);
  873. if (Stats.hasOwnProperty(m) === true){
  874. room.sendChat(m + " has been banned permanently !");
  875. Stats[m].isBanned = true;
  876. Stats[m].isPermaBanned = 1;
  877. room.kickPlayer(Stats[m].id, "You have been permanently banned", 1);
  878. }
  879. }
  880. else {
  881. room.sendChat("PM from Host: Only trusted admin with the level 3 or higher are allowed to permaban.", p.id);
  882. }
  883. return false;
  884.  
  885. }
  886.  
  887.  
  888. function idToName(m){
  889. if (!m.isNaN){
  890. let player = room.getPlayer(m);
  891. if (player !== null)
  892. return player.name;
  893. }
  894. return m;
  895. }
  896.  
  897. function permaBanById(p, m){
  898. m = idToName(m.substr("!permabanid".length + 1));
  899. return permaBan(p, "!permaban " + m);
  900. }
  901.  
  902.  
  903. function unbanAll(player){
  904. if (player === undefined || Stats[player.name].isTrustedAdmin >= 1){
  905. for (var p in Stats) {
  906. if (Stats.hasOwnProperty(p) && Stats[p].isBanned === true &&
  907. Stats[p].isPermaBanned === 0) {
  908.  
  909. room.clearBan(Stats[p].id);
  910. Stats[p].isBanned = 0;
  911. }
  912. }
  913. room.sendChat("PM from Host: Bans have been cleared.");
  914. }
  915. return false;
  916. }
  917.  
  918. function unbanPlayer(p, m){
  919. if (p === undefined || Stats[p.name].isTrustedAdmin >= 1){
  920. m = m.substr("!unban".length + 1);
  921. if (Stats.hasOwnProperty(m) === true){
  922. room.clearBan(Stats[m].id);
  923. room.sendChat(m + " is free now !", p.id);
  924. Stats[m].isBanned = 0;
  925. }
  926. }
  927. return false;
  928. }
  929.  
  930.  
  931. var ragequitAuth = {};
  932.  
  933. function preventPlaying(p){
  934. if (Stats[p.name].kickedSomeone > 0 && p.team != 0){
  935. room.sendChat("This player must wait " +
  936. Stats[p.name].kickedSomeone + " more mins to play.");
  937. room.setPlayerTeam(p.id, 0);
  938. }
  939. else {
  940. Stats[p.name].kickedSomeone = 0;
  941. }
  942. }
  943.  
  944. function decreaseRqTime(){
  945. let players = room.getPlayerList().filter((p) => Stats[p.name].kickedSomeone != 0);
  946. for (var i = 0; i < players.length; i++) {
  947. Stats[players[i].name].kickedSomeone--;
  948. }
  949. }
  950.  
  951.  
  952.  
  953.  
  954. /**************************************************************
  955. * ********************* MISC COMMANDS *************************
  956. * Miscellaneous functions related to some pretty commands.
  957. * Global variable used: None.
  958. ***************************************************************/
  959.  
  960. /**************************************************************
  961. * Function displaying help in 2 lines in pm to the player.
  962. ***************************************************************/
  963. function helpFun(p){
  964. var help_string1 = "| !stats [nickname] | !rank [arg] | !rankhelp | !bethelp";
  965. var help_string2 = "| !bb | !swap | !rr | !rrs | !msup | @nickname pm | !discord | !disp";
  966. room.sendChat(help_string1, p.id);
  967. room.sendChat(help_string2, p.id);
  968. return false;
  969. }
  970.  
  971.  
  972. function rankHelp(p){
  973. room.sendChat("Type rank + one options among: ", p.id);
  974. room.sendChat(Object.keys(msg_to_command).join(" | "), p.id);
  975. return false;
  976. }
  977.  
  978. function betHelp(p){
  979. room.sendChat("💰💰 You can win HAXCOINS by betting on a team ! 💰💰", p.id);
  980. room.sendChat("💰💰 use !betwin [team] [haxcoins], Ex: !betwin r 20 or !betwin b 20 💰💰", p.id);
  981. room.sendChat("💰💰 You can only bet when a match started and before it reaches 20s. 💰💰", p.id);
  982. room.sendChat("💰💰 If your bet is correct, you earn the same ammount of efcoins you've bet, Otherwise, you lose it 💰💰", p.id);
  983. return false;
  984. }
  985.  
  986.  
  987. /**************************************************************
  988. * Function displaying the sum up of the last match in pm.
  989. ***************************************************************/
  990. function sumMatchCommand(p){
  991. gameStats.sumMatch(p);
  992. return false;
  993. }
  994.  
  995.  
  996. function givesDiscord(p){
  997. room.sendChat("https://discord.gg/jTn2ZDp", p.id);
  998. }
  999.  
  1000.  
  1001. let display = {
  1002. "admin": ["isTrustedAdmin", 1],
  1003. "mute": ["isMuted", true]
  1004. };
  1005.  
  1006. function displayHere(p, m){
  1007. m = m.substr("!disp".length + 1);
  1008. if (display.hasOwnProperty(m)){
  1009. let players = room.getPlayerList().filter((player) => player.id != 0);
  1010. let string = "PM from Host: ";
  1011. for (var i = 0; i < players.length; i++) {
  1012. if (Stats[players[i].name][m[0]] >= m[1])
  1013. string += players[i].name + " | ";
  1014. }
  1015. room.sendChat(string, p.id);
  1016. }
  1017. else {
  1018. room.sendChat("PM from Host: This arg does not exist, maps: " +
  1019. Object.keys(display).join(" | "), p.id);
  1020. }
  1021. return false;
  1022.  
  1023. }
  1024.  
  1025.  
  1026. function disconnectAll(){
  1027. for (let e in Stats){
  1028. if (Stats.hasOwnProperty(e) && Stats[e].logged != 0){
  1029. Stats[e].logged = 0;
  1030. Stats[e].isTrustedAdmin = 0;
  1031. }
  1032. }
  1033.  
  1034.  
  1035. }
  1036.  
  1037. function addPassword(p, m){
  1038. if (p === undefined || Stats[p.name].isTrustedAdmin >= 1){
  1039. m = m.substr("!addpw".length + 1);
  1040. room.setPassword(m);
  1041. room.sendChat(m + " is the new pw of the room", p.id);
  1042. }
  1043. return false;
  1044. }
  1045.  
  1046. function rmPassword(p){
  1047. if (p === undefined || Stats[p.name].isTrustedAdmin >= 1){
  1048. room.setPassword();
  1049. room.sendChat("The password have been cleared", p.id);
  1050. }
  1051. return false;
  1052. }
  1053.  
  1054.  
  1055. function changeMaps(p, m){
  1056. if (p === undefined || p.admin === true){
  1057. m = m.substr("!map".length + 1);
  1058. if (maps.hasOwnProperty(m)){
  1059. room.setCustomStadium(maps[m]);
  1060. return false;
  1061. }
  1062. room.sendChat("PM from Host: This map does not exist, maps: " +
  1063. Object.keys(maps).join(" | "), p.id);
  1064. }
  1065. }
  1066.  
  1067. function downloadBlob(fileName) {
  1068. let mimeType = 'application/octet-stream';
  1069. let data = room.stopRecording();
  1070. let blob = new Blob([data], {type: mimeType});
  1071. let url = window.URL.createObjectURL(blob);
  1072. downloadURL(url, fileName);
  1073. setTimeout(function() {
  1074. return window.URL.revokeObjectURL(url);
  1075. }, 1000);
  1076. }
  1077.  
  1078. function downloadURL(data, fileName) {
  1079. let elem = document.createElement('elem');
  1080. elem.href = data;
  1081. elem.download = fileName;
  1082. document.body.appendChild(elem);
  1083. elem.style = 'display: none';
  1084. elem.click();
  1085. elem.remove();
  1086. }
  1087.  
  1088. function recGameFun(player){
  1089. if (gameStats.rec === true){
  1090. room.sendChat("Last game has already been recorded by someone." +
  1091. "Contact us to get a copy of it", player.id);
  1092. }
  1093. else {
  1094. let date = new Date();
  1095. let month = (date.getMonth + 1);
  1096. let recname = "haxrec_" + date.getDate() + "_" +
  1097. "_" + date.getFullYear() + "_" + date.getHours() + "H" +
  1098. date.getMinutes() + "m.hbr2";
  1099.  
  1100. downloadBlob(recname);
  1101. room.sendChat("Game saved as " + recname +
  1102. " . Contact us on Discord to get a copy.", player.id);
  1103. gameStats.rec = true;
  1104. }
  1105. }
  1106.  
  1107. var Alts = {}; //{conn: [name1, ..., nameN]}
  1108.  
  1109. function getAlts(p, m){
  1110. m = m.substr("!getalts".length + 1);
  1111. if (Stats.hasOwnProperty(m))
  1112. room.sendChat("PM from Host: Alts: " + Alts[Stats[m].conn].join(" | "), p.id);
  1113. return false;
  1114. }
  1115.  
  1116. function stringBet(p, team, bet, team_msg){
  1117. Stats[p.name].winPred = team;
  1118. Stats[p.name].currentBet = Number(bet);
  1119. room.sendChat("PM from Host: You've bet " + bet + " EFCOINS on " +
  1120. team_msg + " team ! ", p.id);
  1121. }
  1122.  
  1123. function betOnTeam(p, m){
  1124. m = m.substr("!betwin".length + 1);
  1125. let bet = m.substr(2);
  1126. m = m.substr(0, 1);
  1127. let score = room.getScores();
  1128. let team = ["r", "b"];
  1129. if (!isNaN(bet) && bet >= 0 && bet <= Stats[p.name].money &&
  1130. Stats[p.name].currentBet === 0 && team.includes(m) &&
  1131. score != null && score.time < 20 && p.team === 0 &&
  1132. gameStats.redTeam.length >= 3 && gameStats.blueTeam.length >= 3){
  1133.  
  1134. stringBet(p, 1 * (m == "r") || 1 + (m == "b"), bet, m == "r" ? "red" : "blue");
  1135. }
  1136. else {
  1137. room.sendChat("PM from Host: You have to put this specific format: ", p.id);
  1138. room.sendChat("PM from Host: !betwin r X or !betwin b X", p.id);
  1139. room.sendChat("PM from Host: where r and b are the team X is the ammount of haxcoins you want to bet. ", p.id);
  1140. }
  1141. return false;
  1142. }
  1143.  
  1144.  
  1145. function checkFake(p, m){
  1146. m = m.substr("!check".length + 1);
  1147. if (Stats.hasOwnProperty(m)){
  1148. m = Stats[m].price ? "is" : "is not";
  1149. room.sendChat("PM From Host: This player " + msg + " a fake.");
  1150. }
  1151. }
  1152.  
  1153. var commands = {
  1154. "!swag": swap,
  1155. "!rr": reset,
  1156. "!rrz": resetWithSwap,
  1157. //"!rrt": resetWithTop,
  1158. "!bb": bb,
  1159. "!msup": sumMatchCommand,
  1160. "!discord": givesDiscord,
  1161. "!help": helpFun,
  1162. "!rankhelp": rankHelp,
  1163. "!disp": displayHere,
  1164. "!stats": stats,
  1165. "!rank": ranking,
  1166. //"!changepw": changePW,
  1167.  
  1168. "!mute": mute,
  1169. "!muteid": muteById,
  1170. "!muteall": muteAll,
  1171. "!unmute": unmute,
  1172. "!unmuteid": unmuteById,
  1173. "!unmuteall": resetMutes,
  1174. "!unban": unbanPlayer,
  1175. "!unbanall": unbanAll,
  1176. "!permaban": permaBan,
  1177. "!permabanid": permaBanById,
  1178. "!e": superAdmin,
  1179. "!admin": getAdmin,
  1180. "!admin2": getAdmin2,
  1181. "!addadmin": addAdmin,
  1182. "!map": changeMaps,
  1183. "!addpw": addPassword,
  1184. "!rmpw": rmPassword,
  1185. "!getalts": getAlts,
  1186. "!rec": recGameFun,
  1187. "!betwin": betOnTeam,
  1188. "!bethelp": betHelp,
  1189. "!banall": banall
  1190. "!check": checkFake,
  1191. };
  1192.  
  1193.  
  1194. function handleCommands(p, m){
  1195. let spacePos = m.search(" ");
  1196. let command = m.substr(0, spacePos !== -1 ? spacePos : m.length);
  1197. if (commands.hasOwnProperty(command) === true) return commands[command](p, m);
  1198. if (m.startsWith("!") === true) {
  1199. room.sendChat("PM from Host: This is not an existing command, write !help if needed !", p.id);
  1200. return false;
  1201. }
  1202. return true;
  1203. }
  1204.  
  1205.  
  1206. function handleStart(){
  1207. gameStats.updateRedTeam();
  1208. gameStats.updateBlueTeam();
  1209. handleTeams();
  1210. elo.handleEloCalc();
  1211. room.stopRecording();
  1212. room.startRecording();
  1213. room.sendChat("💰💰 Who will win this game ? You have 20s to place your bet and get rich 💰💰! See !bethelp for more info.");
  1214. }
  1215.  
  1216.  
  1217. function handleTimePlayed(){
  1218. var players = room.getPlayerList();
  1219. for (var i = 1; i < players.length; i++){
  1220. Stats[players[i].name].updateSecsPlayed();
  1221. Stats[players[i].name].updateMinsPlayed();
  1222. }
  1223. }
  1224.  
  1225.  
  1226.  
  1227. function handleGoals(team){
  1228. var time = room.getScores().time;
  1229. var m = Math.trunc(time / 60);
  1230. var s = Math.trunc(time % 60);
  1231. let string;
  1232. let assister = "";
  1233.  
  1234. time = m + ":" + (s < 10 ? "0" + s : s); // MM:SS format
  1235. gameStats.updateScore(team);
  1236.  
  1237. gameStats.updateScorers(Stats[gameControl.currentBallOwner], team);
  1238. gameStats.updateOwnScorers(Stats[gameControl.currentBallOwner], team);
  1239. gameStats.updateAssisters(Stats[gameControl.lastBallOwners[1]], team);
  1240.  
  1241. if (Stats.hasOwnProperty(gameControl.lastBallOwners[1]) &&
  1242. (Stats[gameControl.lastBallOwners[1]].team ===
  1243. Stats[gameControl.lastBallOwners[0]].team)){
  1244.  
  1245. assister = gameControl.lastBallOwners[1];
  1246. }
  1247.  
  1248.  
  1249. if (team === Stats[gameControl.currentBallOwner].team){
  1250. string = "⚽ Scorer: " + gameControl.lastBallOwners[0] + "| Assister: " +
  1251. assister + "| at " + time;
  1252. room.sendChat(string);
  1253. }
  1254. else {
  1255. string = "Own goal from: " + gameControl.lastBallOwners[0] + "| at " + time;
  1256. room.sendChat(string);
  1257. }
  1258. gameStats.matchsumup.push(string);
  1259. gameControl.resetBallOwner();
  1260.  
  1261. }
  1262.  
  1263. function handleTeams(){
  1264. var p = room.getPlayerList();
  1265. for (var i = 1; i < p.length; i++) {
  1266. Stats[p[i].name].team = p[i].team;
  1267. }
  1268. }
  1269.  
  1270. function handleGk(){
  1271. if (gameStats.hasStarted === false){
  1272. if (room.getScores().time !== 0){
  1273. gameStats.hasStarted = true;
  1274. gameStats.updateGK();
  1275. room.sendChat("Red GK: " + gameStats.Gks[0] + ", Blue GK: " + gameStats.Gks[1]);
  1276. }
  1277. }
  1278. }
  1279.  
  1280. function handleEndGame(){
  1281. var players = room.getPlayerList().filter((p) => p.id != 0);
  1282. records.updateBestPassesInARow();
  1283. elo.updateElo();
  1284. for (var i = 0; i < players.length; i++){
  1285. if (Stats[players[i].name].price !== 1){
  1286. Stats[players[i].name].updateEGStats();
  1287. }
  1288. }
  1289. }
  1290.  
  1291. function handleOvertime(){
  1292. let scores = room.getScores();
  1293. if (scores !== null && scores.timeLimit !== 0 &&
  1294. scores.time >= scores.timeLimit){
  1295.  
  1296. handleEndGame();
  1297. }
  1298. }
  1299.  
  1300.  
  1301.  
  1302. function handleBans2(kicked, message, ban, by){
  1303. if (by.id !== 0){
  1304. if (Stats[by.name].isTrustedAdmin === 0){
  1305. room.kickPlayer(by.id, "You are not allowed to kick/ban players !", ban);
  1306. room.clearBan(kicked.id);
  1307. }
  1308. }
  1309. }
  1310.  
  1311. function handleBans(kicked, message, ban, by){
  1312. Stats[kicked.name].gotKicked += by !== null;
  1313. Stats[kicked.name].isBanned = ban === true;
  1314. if (by.id !== 0){
  1315. Stats[by.name].updateKickedSomeone();
  1316. if (Stats[by.name].kickedSomeone >= 10){
  1317. Stats[by.name].kickedSomeone = 0;
  1318. room.kickPlayer(by.id, "You kicked too much people", 1);
  1319. }
  1320. }
  1321. }
  1322.  
  1323. function handleRefresh(p){
  1324.  
  1325.  
  1326. if (Stats.hasOwnProperty(p.name) && Stats[p.name].logged !== 0){
  1327. if (Stats[p.name].auth === p.auth){
  1328. room.kickPlayer(Stats[p.name].id, "You just refreshed.", 0);
  1329. }
  1330. else {
  1331. room.kickPlayer(p.id, "This nickname is already taken in the room.", 0);
  1332. }
  1333. }
  1334. }
  1335. function handleRefresh2(p){
  1336. let players = room.getPlayerList();
  1337. for (var i = 0; i < players.length; i++) {
  1338. if (Stats[players[i].name].auth === p.auth && Stats[p.name].logged !== 0)
  1339. room.kickPlayer(Stats[players[i].name].id, "You just refreshed.", 0);
  1340. }
  1341. }
  1342.  
  1343.  
  1344.  
  1345. function updateSanction(p){
  1346. if (room.getPlayerList().filter((pl) => pl.name === p.name &&
  1347. pl.team === p.team).length === 0){
  1348.  
  1349. let score = gameStats.redScore - gameStats.blueScore;
  1350. Stats[p.name].kickedSomeone += p.team === 1 && score > 0;
  1351. Stats[p.name].kickedSomeone += p.team === 2 && score < 0;
  1352.  
  1353. Stats[p.name].kickedSomeone += 3 * (p.team === 1 && score < 0);
  1354. Stats[p.name].kickedSomeone += 3 * (p.team === 2 && score > 0);
  1355.  
  1356. Stats[p.name].kickedSomeone += 2 * (score === 0);
  1357.  
  1358. Stats[p.name].kickedSomeone *= 5;
  1359.  
  1360.  
  1361. }
  1362.  
  1363. }
  1364.  
  1365. function handleSanction(p){
  1366. if (p.team !== 0){
  1367. setTimeout(updateSanction, 1000 * 20, p);
  1368. }
  1369. }
  1370.  
  1371. function leaveInGame(p){
  1372. if (room.getScores() != null && p.team !== 0){
  1373. room.pauseGame(true);
  1374. }
  1375. }
  1376.  
  1377. function handleCSMessage(){
  1378. let str = "";
  1379. if (gameStats.redScore === 0)
  1380. str = [gameStats.Gks[1] + " kept a cs for his team"].join();
  1381. if (gameStats.blueScore === 0)
  1382. str = [gameStats.Gks[0] + " kept a cs for his team"].join();
  1383. return str;
  1384. }
  1385.  
  1386.  
  1387. function handleMode(){
  1388. mode = room.getScores().timeLimit === 7;
  1389. }
  1390.  
  1391.  
  1392.  
  1393. function handleAlts(p){
  1394. if (Alts.hasOwnProperty(p.conn)){
  1395. if (!Alts[p.conn].includes(p.name))
  1396. Alts[p.conn].push(p.name);
  1397. }
  1398. else {
  1399. Alts[p.conn] = [p.name];
  1400. }
  1401. }
  1402.  
  1403. function handleBans(p){
  1404. if (Stats[p.name].isBanned != 0)
  1405. room.kickPlayer(p.id, "You're banned permanently", 1);
  1406. }
  1407.  
  1408. function resetBettings(){
  1409. let players = room.getPlayerList();
  1410. for (var i = 0; i < players.length; i++) {
  1411. Stats[players[i].name].currentBet = 0;
  1412. Stats[players[i].name].winPred = 0;
  1413. }
  1414. room.sendChat("Since the game was stopped, all bets are reseted !");
  1415. }
  1416.  
  1417.  
  1418. function handleStadiumChange(name, by){
  1419. if (first_stadium_loaded === true){
  1420. if (by.id != 0){
  1421. room.kickPlayer(by.id, "Please use !map [stadium] next time !", false);
  1422. room.setCustomStadium(maps.big);
  1423. }
  1424. }
  1425. else first_stadium_loaded = true;
  1426. }
  1427.  
  1428. function updateStreak(winners){
  1429. winStreak.score = (winStreak.team == "red" && winners) ||
  1430. !(winStreak.team == "red" || winners) ? winStreak.score + 1 : 1;
  1431. winStreak.team = winners ? "red" : "blue";
  1432.  
  1433. room.sendChat("The current streak is held by " + winStreak.team +
  1434. " with " + winStreak.score + " wins ! ");
  1435. }
  1436.  
  1437.  
  1438. function banall(p){
  1439. if (p === undefined || Stats[p.name].isTrustedAdmin >= 1){
  1440. let players = room.getPlayerList().filter((p) => p.id != 0);
  1441. if (players.length != 0){
  1442. for (var i = 0; i < players.length; i++) {
  1443. room.kickPlayer(players[i].id, "Be active next time :-)", 0);
  1444. }
  1445. }
  1446. }
  1447. return false;
  1448. }
  1449.  
  1450. function checkfdps(){
  1451. if (active.length == 0 && room.getPlayerList().length >= 6){
  1452. banall();
  1453. }
  1454. active = [];
  1455. }
  1456.  
  1457.  
  1458. function getBestRanks(){
  1459. let string;
  1460. for (var rank in msg_to_command) {
  1461. if (msg_to_command.hasOwnProperty(rank)){
  1462. string = bestRanks(rank);
  1463. console.log(rank + ": " + string.substring(0, 400));
  1464. }
  1465. }
  1466. }
  1467.  
  1468. function resetAuth(name){
  1469. if (Stats.hasOwnProperty(name))
  1470. Stats[name].auth = 0;
  1471. }
  1472.  
  1473. function kickLastPlayer(p){
  1474. if (room.getPlayerList().length === MAX_PLAYERS &&
  1475. !roomAdminsAuth.hasOwnProperty(p.auth) &&
  1476. !headAdminsAuths.hasOwnProperty(p.auth)){
  1477.  
  1478. room.kickPlayer(p.id, "Sorry, this slot is reserved for EFC staff !", 0);
  1479.  
  1480. }
  1481. }
  1482.  
  1483.  
  1484. function putTeamColor(){
  1485. room.setTeamColors(1, 45, 0xFFA41C, [0x7A1602, 0x7A1602, 0x571002]);
  1486. room.setTeamColors(2, 135, 0xFFA41C, [0x1A164A, 0x1A164A, 0x110E30]);
  1487. }
  1488.  
  1489. function spamcolors(team, color){
  1490. room.setTeamColors(team, 45, color, [color, color, color]);
  1491. }
  1492.  
  1493.  
  1494. function warn4def(team){
  1495.  
  1496. room.sendChat("You are not applying the 4def rule ! Please be careful");
  1497. spamcolors(team, 0x000000);
  1498. }
  1499.  
  1500. function check4def(){
  1501. if (room.getScores() == null) return;
  1502. let red4def = room.getPlayerList().filter((p) =>
  1503. p.team == 1 && p.position.x < -386).length;
  1504.  
  1505. let blue4def = room.getPlayerList().filter((p) =>
  1506. p.team == 2 && p.position.x > 386).length;
  1507.  
  1508. if (red4def == 4 || blue4def == 4){
  1509. warn4def(1 + (blue4def == 4));
  1510. }
  1511. else putTeamColor();
  1512. }
  1513.  
  1514.  
  1515. /**************************************************************
  1516. * ************************** EVENTS ****************************
  1517. ***************************************************************/
  1518. var gameStats = new GameStats();
  1519. var gameControl = new GameControl(5.9);
  1520. var records = new Records();
  1521. var elo;
  1522. var mode = false;
  1523. var lastMatchSumUp = [];
  1524. var active = [];
  1525.  
  1526. var winStreak = {"team": "", "score": 1};
  1527.  
  1528. setInterval(saveStatsFun, 300000);
  1529. setInterval(checkfdps, 1000 * 60 * 4);
  1530. setInterval(deleteStatsFun, 1000 * 60 * 60 * 24 * 7);
  1531. setInterval(updateSelectedAdmins, 1000 * 60 * 4);
  1532.  
  1533. setInterval(function(){
  1534. room.sendChat("🚨🏆 EFC Trophy will RETURN for a 4th season! Join our Discord 👉 http://discord.gg/jTn2ZDp 👈");
  1535. room.sendChat("🚨🤙 Get online! Find your team! Compete in the biggest European Haxball community! 🏆");
  1536. }, 1000 * 60 * 5);
  1537.  
  1538. setInterval(check4def, 1000);
  1539. setInterval(decreaseRqTime, 1000 * 60);
  1540.  
  1541.  
  1542. room.onPlayerChat = function(p, m){
  1543. console.log(p.name + "#" + p.id + " : " + m );
  1544. if (Stats[p.name].isMuted) return false;
  1545. if (handleCommands(p, m) === false) return false;
  1546. if (sendPM(p, m) === false) return false;
  1547. handleSpam(lastWriters, p);
  1548. };
  1549.  
  1550.  
  1551. room.onPlayerTeamChange = function(p, by){
  1552. preventPlaying(p);
  1553. if (p.id === 0 && p.team != 0){
  1554. room.setPlayerTeam(p.id, 0);
  1555. room.sendChat("😬 Woah, hang on! I'm only a bot, you really think I'm coded to play? 😬");
  1556. }
  1557. handleTeams();
  1558. };
  1559.  
  1560.  
  1561.  
  1562.  
  1563. room.onPlayerJoin = function(player) {
  1564. console.log("👋👋👋 " + player.name + " # " + player.id + " Joined - " + player.auth);
  1565. handleRefresh(player);
  1566. //handleRefresh2(player);
  1567. autoConnect(player);
  1568. handleBans(player);
  1569. handleAlts(player);
  1570. updateAdmins();
  1571. room.sendChat("👋 Hey " + player.name + " ! 👋 New season will kick off in June! Join and play with us! 📣📣 https://discord.gg/jTn2ZDp", player.id);
  1572.  
  1573. if (!active.includes(Stats[player.name].conn)) {
  1574. active.push(Stats[player.name].conn);
  1575. }
  1576. };
  1577.  
  1578. room.onPlayerLeave = function(player) {
  1579. console.log("😢😢😢 " + player.name + " has left the room");
  1580. updateAdmins();
  1581. leaveInGame(player);
  1582. handleSanction(player);
  1583. Stats[player.name].disconnect();
  1584.  
  1585. };
  1586.  
  1587.  
  1588.  
  1589.  
  1590. room.onPlayerKicked = function(kicked, message, ban, by){
  1591. handleBans2(kicked, message, ban, by);
  1592. };
  1593.  
  1594.  
  1595. room.onGameStart = function(){
  1596. putTeamColor();
  1597. gameStats = new GameStats();
  1598. gameControl = new GameControl(5.9);
  1599. elo = new ELO();
  1600. handleStart();
  1601. handleMode();
  1602.  
  1603. };
  1604.  
  1605.  
  1606. room.onTeamGoal = function(team){
  1607. handleGoals(team);
  1608. };
  1609.  
  1610.  
  1611. room.onGameStop = function(){
  1612. resetMutes();
  1613. gameControl.resetBallOwner();
  1614.  
  1615. };
  1616.  
  1617.  
  1618.  
  1619. room.onGameTick = function(){
  1620. gameControl.updateBallOwner();
  1621. gameControl.updateLastBallOwners();
  1622. gameControl.updatePassesInARow();
  1623. handleGk();
  1624. handleTimePlayed();
  1625. if (mode === true) setInterval(handleOvertime, 5000);
  1626. };
  1627.  
  1628. room.onPlayerBallKick = function (player){
  1629. gameControl.currentBallOwner = player.name;
  1630. };
  1631.  
  1632.  
  1633. room.onTeamVictory = function(){
  1634. if (mode === false) handleEndGame();
  1635. gameStats.matchsumup.push(handleCSMessage());
  1636. lastMatchSumUp.push(gameStats.matchsumup);
  1637.  
  1638.  
  1639. updateStreak(gameStats.redScore > gameStats.blueScore);
  1640.  
  1641. room.stopGame();
  1642.  
  1643. };
  1644.  
  1645. room.onPlayerAdminChange = function(p, by){
  1646. if (by != null && Stats[p.name].isTrustedAdmin > Stats[by.name].isTrustedAdmin){
  1647. room.kickPlayer(by.id, "Don't try this at home, kid.", false);
  1648. room.setPlayerAdmin(p.id, true);
  1649. }
  1650. updateAdmins();
  1651. };
  1652.  
  1653. room.onRoomLink = function(){
  1654. let vide = "";
  1655. vide.name = "";
  1656. loadStats();
  1657. disconnectAll();
  1658. autoConnect(room.getPlayer(0));
  1659. autoConnect(vide);
  1660. };
  1661.  
  1662.  
  1663. room.onStadiumChange = function(name, by){
  1664. handleStadiumChange(name, by);
  1665. };
  1666.  
  1667.  
  1668.  
  1669.  
  1670. room.onPlayerActivity = function(p){
  1671. if (!active.includes(Stats[p.name].conn)) {
  1672. active.push(Stats[p.name].conn);
  1673. }
  1674. };
  1675.  
  1676. /* EOF */
  1677.  
  1678.  
  1679. /* Python-like update dict method having at least an empty object */
  1680. function updateObject(object, p){
  1681. if (object.hasOwnProperty(p.name)){
  1682. object[p.name]++;
  1683. }
  1684. else {
  1685. object[p.name] = 1;
  1686. }
  1687. }
  1688.  
  1689.  
  1690. // Gives the last player who touched the ball, works only if the ball has the same
  1691. // size than in classics maps.
  1692. // Calculate the distance between 2 points
  1693. function pointDistance(p1, p2) {
  1694. var d1 = p1.x - p2.x;
  1695. var d2 = p1.y - p2.y;
  1696. return Math.sqrt(d1 * d1 + d2 * d2);
  1697. }
  1698.  
  1699.  
  1700.  
  1701.  
  1702.  
  1703.  
  1704.  
  1705.  
  1706.  
  1707. var bigmap = `{
  1708.  
  1709. "name" : "[EFC] 4v4 by Kang & Mona",
  1710.  
  1711. "width" : 800,
  1712.  
  1713. "height" : 350,
  1714.  
  1715. "spawnDistance" : 350,
  1716.  
  1717. "bg" : { "type" : "hockey", "width" : 0, "height" : 0, "kickOffRadius" : 80, "cornerRadius" : 0 },
  1718.  
  1719. "vertexes" : [
  1720. /* 0 */ { "x" : -700, "y" : 320, "trait" : "ballArea" },
  1721. /* 1 */ { "x" : -700, "y" : -320, "trait" : "ballArea" },
  1722. /* 2 */ { "x" : 700, "y" : 320, "trait" : "ballArea" },
  1723. /* 3 */ { "x" : 700, "y" : -320, "trait" : "ballArea" },
  1724.  
  1725. /* 4 */ { "x" : 0, "y" : 350, "trait" : "kickOffBarrier" },
  1726. /* 5 */ { "x" : 0, "y" : 80, "trait" : "kickOffBarrier", "color" : "3377ae", "vis" : true, "curve" : 180 },
  1727. /* 6 */ { "x" : 0, "y" : -80, "trait" : "kickOffBarrier", "color" : "3377ae", "vis" : true, "curve" : 180 },
  1728. /* 7 */ { "x" : 0, "y" : -350, "trait" : "kickOffBarrier" },
  1729.  
  1730. /* 8 */ { "x" : -700, "y" : -85, "trait" : "goalNet", "curve" : 0, "color" : "DA4D4B" },
  1731. /* 9 */ { "x" : -741, "y" : -85, "trait" : "goalNet", "curve" : -23, "color" : "DA4D4B", "bCoef" : 0.8 },
  1732. /* 10 */ { "x" : -741, "y" : 85, "trait" : "goalNet", "curve" : -23, "color" : "DA4D4B", "bCoef" : 0.8 },
  1733. /* 11 */ { "x" : -700, "y" : 85, "trait" : "goalNet", "curve" : 0, "color" : "DA4D4B" },
  1734. /* 12 */ { "x" : 700, "y" : -85, "trait" : "goalNet", "curve" : 0, "color" : "3377ae" },
  1735. /* 13 */ { "x" : 743, "y" : -85, "trait" : "goalNet", "curve" : 23, "color" : "3377ae", "bCoef" : 0.8 },
  1736. /* 14 */ { "x" : 743, "y" : 84, "trait" : "goalNet", "curve" : 23, "color" : "3377ae", "bCoef" : 0.8 },
  1737. /* 15 */ { "x" : 700, "y" : 85, "trait" : "goalNet", "curve" : 0, "color" : "3377ae" },
  1738.  
  1739. /* 16 */ { "x" : -700, "y" : 85, "bCoef" : 1.25, "cMask" : ["ball" ], "trait" : "ballArea", "color" : "1e252a" },
  1740. /* 17 */ { "x" : -700, "y" : 320, "bCoef" : 1.25, "cMask" : ["ball" ], "trait" : "ballArea", "color" : "1e252a" },
  1741. /* 18 */ { "x" : -700, "y" : -85, "bCoef" : 1.25, "cMask" : ["ball" ], "trait" : "ballArea", "color" : "1e252a" },
  1742. /* 19 */ { "x" : -700, "y" : -320, "bCoef" : 1.25, "cMask" : ["ball" ], "trait" : "ballArea", "color" : "1e252a" },
  1743. /* 20 */ { "x" : -700, "y" : 320, "bCoef" : 2, "cMask" : ["ball" ], "trait" : "ballArea", "color" : "1e252a" },
  1744. /* 21 */ { "x" : 700, "y" : 320, "bCoef" : 2, "cMask" : ["ball" ], "trait" : "ballArea", "color" : "1e252a" },
  1745. /* 22 */ { "x" : 700, "y" : 85, "bCoef" : 1.25, "cMask" : ["ball" ], "trait" : "ballArea", "color" : "1e252a" },
  1746. /* 23 */ { "x" : 700, "y" : 320, "bCoef" : 1.25, "cMask" : ["ball" ], "trait" : "ballArea", "color" : "1e252a" },
  1747. /* 24 */ { "x" : 700, "y" : -320, "bCoef" : 1.25, "cMask" : ["ball" ], "trait" : "ballArea", "color" : "1e252a" },
  1748. /* 25 */ { "x" : 700, "y" : -85, "bCoef" : 1.25, "cMask" : ["ball" ], "trait" : "ballArea", "color" : "1e252a" },
  1749. /* 26 */ { "x" : 700, "y" : -320, "bCoef" : 0, "cMask" : ["ball" ], "trait" : "ballArea" },
  1750. /* 27 */ { "x" : 700, "y" : -320, "bCoef" : 0, "cMask" : ["ball" ], "trait" : "ballArea" },
  1751. /* 28 */ { "x" : -700, "y" : -320, "bCoef" : 2, "cMask" : ["ball" ], "trait" : "ballArea", "color" : "1e252a" },
  1752. /* 29 */ { "x" : 700, "y" : -320, "bCoef" : 2, "cMask" : ["ball" ], "trait" : "ballArea", "color" : "1e252a" },
  1753.  
  1754. /* 30 */ { "x" : 0, "y" : -318, "bCoef" : 0.1, "cMask" : ["red","blue" ], "cGroup" : ["redKO","blueKO" ], "trait" : "kickOffBarrier", "color" : "1e252a" },
  1755. /* 31 */ { "x" : 0, "y" : -82, "bCoef" : 0.1, "cMask" : ["red","blue" ], "cGroup" : ["redKO","blueKO" ], "trait" : "kickOffBarrier", "color" : "1e252a" },
  1756. /* 32 */ { "x" : 0, "y" : 82, "bCoef" : 0.1, "cMask" : ["red","blue" ], "cGroup" : ["redKO","blueKO" ], "trait" : "kickOffBarrier", "color" : "1e252a" },
  1757. /* 33 */ { "x" : 0, "y" : 318, "bCoef" : 0.1, "cMask" : ["red","blue" ], "cGroup" : ["redKO","blueKO" ], "trait" : "kickOffBarrier", "color" : "1e252a" },
  1758. /* 34 */ { "x" : 0, "y" : -82, "bCoef" : 0.1, "cMask" : ["red","blue" ], "trait" : "kickOffBarrier", "vis" : true, "color" : "F8F8F8" },
  1759. /* 35 */ { "x" : 0, "y" : 82, "bCoef" : 0.1, "cMask" : ["red","blue" ], "trait" : "kickOffBarrier", "vis" : true, "color" : "F8F8F8" },
  1760. /* 36 */ { "x" : 0, "y" : -150, "bCoef" : 0.1, "cMask" : ["red","blue" ], "cGroup" : ["redKO","blueKO" ], "trait" : "kickOffBarrier" },
  1761. /* 37 */ { "x" : 0, "y" : 82, "trait" : "kickOffBarrier", "color" : "F8F8F8", "vis" : true, "curve" : -180 },
  1762. /* 38 */ { "x" : 0, "y" : -82, "trait" : "kickOffBarrier", "color" : "F8F8F8", "vis" : true, "curve" : -180 },
  1763. /* 39 */ { "x" : 0, "y" : 82, "trait" : "kickOffBarrier", "color" : "F8F8F8", "vis" : true, "curve" : 0 },
  1764.  
  1765. /* 40 */ { "x" : -707.5, "y" : 85, "bCoef" : 1, "cMask" : ["ball" ], "trait" : "ballArea", "curve" : 0, "vis" : false },
  1766. /* 41 */ { "x" : -707.5, "y" : -344, "bCoef" : 1, "cMask" : ["ball" ], "trait" : "ballArea", "vis" : false, "curve" : 0 },
  1767. /* 42 */ { "x" : -707.5, "y" : -85, "bCoef" : 1, "cMask" : ["ball" ], "trait" : "ballArea", "vis" : false, "curve" : 0 },
  1768. /* 43 */ { "x" : 697, "y" : -85, "bCoef" : 1, "cMask" : ["ball" ], "trait" : "ballArea" },
  1769. /* 44 */ { "x" : 697, "y" : -87, "bCoef" : 1, "cMask" : ["ball" ], "trait" : "ballArea", "vis" : false, "curve" : 0 },
  1770. /* 45 */ { "x" : 696, "y" : 84, "bCoef" : 1, "cMask" : ["ball" ], "trait" : "ballArea", "curve" : 0, "vis" : false },
  1771.  
  1772. /* 46 */ { "x" : -700, "y" : -86, "bCoef" : 0.1, "cMask" : ["blue" ], "cGroup" : ["redKO","blueKO" ], "trait" : "kickOffBarrier", "color" : "737573" },
  1773. /* 47 */ { "x" : -700, "y" : 81, "bCoef" : 0.1, "cMask" : ["blue" ], "cGroup" : ["redKO","blueKO" ], "trait" : "kickOffBarrier", "color" : "737573" },
  1774. /* 48 */ { "x" : 700, "y" : -83, "bCoef" : 0.1, "cMask" : ["red" ], "cGroup" : ["redKO","blueKO" ], "trait" : "kickOffBarrier", "color" : "737573" },
  1775. /* 49 */ { "x" : 700, "y" : 84, "bCoef" : 0.1, "cMask" : ["red" ], "cGroup" : ["redKO","blueKO" ], "trait" : "kickOffBarrier", "color" : "737573" },
  1776.  
  1777. /* 50 */ { "x" : -385.5, "y" : 318, "bCoef" : 0, "cMask" : ["wall" ], "color" : "737573" },
  1778. /* 51 */ { "x" : -385.5, "y" : -318, "bCoef" : 0, "cMask" : ["wall" ], "color" : "737573" },
  1779. /* 52 */ { "x" : 385.5, "y" : 318, "bCoef" : 0, "cMask" : ["wall" ], "color" : "737573" },
  1780. /* 53 */ { "x" : 385.5, "y" : -318, "bCoef" : 0, "cMask" : ["wall" ], "color" : "737573" },
  1781. /* 54 */ { "x" : -385.5, "y" : -130, "cMask" : ["wall" ], "curve" : 90, "color" : "737573" },
  1782. /* 55 */ { "x" : -385.5, "y" : 130, "cMask" : ["wall" ], "curve" : 90, "color" : "737573" },
  1783. /* 56 */ { "x" : 385.5, "y" : -130, "cMask" : ["wall" ], "curve" : -90, "color" : "737573" },
  1784. /* 57 */ { "x" : 385.5, "y" : 130, "cMask" : ["wall" ], "curve" : -90, "color" : "737573" },
  1785. /* 58 */ { "x" : -620, "y" : -115, "cMask" : ["wall" ], "color" : "737573" },
  1786. /* 59 */ { "x" : -698, "y" : -115, "cMask" : ["wall" ], "color" : "737573" },
  1787. /* 60 */ { "x" : -620, "y" : 115, "cMask" : ["wall" ], "color" : "737573" },
  1788. /* 61 */ { "x" : -698, "y" : 115, "cMask" : ["wall" ], "color" : "737573" },
  1789. /* 62 */ { "x" : -620, "y" : -115, "cMask" : ["wall" ], "color" : "737573" },
  1790. /* 63 */ { "x" : -620, "y" : 115, "cMask" : ["wall" ], "color" : "737573" },
  1791. /* 64 */ { "x" : 620, "y" : 115, "cMask" : ["wall" ], "color" : "737573" },
  1792. /* 65 */ { "x" : 698, "y" : 115, "cMask" : ["wall" ], "color" : "737573" },
  1793. /* 66 */ { "x" : 620, "y" : -115, "cMask" : ["wall" ], "color" : "737573" },
  1794. /* 67 */ { "x" : 698, "y" : -115, "cMask" : ["wall" ], "color" : "737573" },
  1795. /* 68 */ { "x" : 620, "y" : -115, "cMask" : ["wall" ], "color" : "737573" },
  1796. /* 69 */ { "x" : 620, "y" : 115, "cMask" : ["wall" ], "color" : "737573" },
  1797. /* 70 */ { "x" : 500, "y" : -2, "cMask" : ["wall" ], "curve" : 180, "color" : "737573" },
  1798. /* 71 */ { "x" : 500, "y" : 2, "cMask" : ["wall" ], "curve" : 180, "color" : "737573" },
  1799. /* 72 */ { "x" : 500, "y" : -2, "cMask" : ["wall" ], "curve" : -180, "color" : "737573" },
  1800. /* 73 */ { "x" : 500, "y" : 2, "cMask" : ["wall" ], "curve" : -180, "color" : "737573" },
  1801. /* 74 */ { "x" : -500, "y" : -2, "cMask" : ["wall" ], "curve" : 180, "color" : "737573" },
  1802. /* 75 */ { "x" : -500, "y" : 2, "cMask" : ["wall" ], "curve" : 180, "color" : "737573" },
  1803. /* 76 */ { "x" : -500, "y" : -2, "cMask" : ["wall" ], "curve" : -180, "color" : "737573" },
  1804. /* 77 */ { "x" : -500, "y" : 2, "cMask" : ["wall" ], "curve" : -180, "color" : "737573" },
  1805. /* 78 */ { "x" : 0, "y" : -2, "cMask" : ["wall" ], "curve" : 180, "color" : "737573" },
  1806. /* 79 */ { "x" : 0, "y" : 2, "cMask" : ["wall" ], "curve" : 180, "color" : "737573" },
  1807. /* 80 */ { "x" : 0, "y" : -2, "cMask" : ["wall" ], "curve" : -180, "color" : "737573" },
  1808. /* 81 */ { "x" : 0, "y" : 2, "cMask" : ["wall" ], "curve" : -180, "color" : "737573" },
  1809.  
  1810. /* 82 */ { "x" : -707.5, "y" : 344, "bCoef" : 1, "cMask" : ["ball" ], "trait" : "ballArea", "vis" : false, "curve" : 0 },
  1811. /* 83 */ { "x" : -707.5, "y" : 85, "bCoef" : 1, "cMask" : ["ball" ], "trait" : "ballArea", "vis" : false, "curve" : 0 },
  1812. /* 84 */ { "x" : 707.5, "y" : 344, "bCoef" : 1, "cMask" : ["ball" ], "trait" : "ballArea", "vis" : false, "curve" : 0 },
  1813. /* 85 */ { "x" : 707.5, "y" : 85, "bCoef" : 1, "cMask" : ["ball" ], "trait" : "ballArea", "vis" : false, "curve" : 0 },
  1814. /* 86 */ { "x" : 707.5, "y" : -344, "bCoef" : 1, "cMask" : ["ball" ], "trait" : "ballArea", "vis" : false, "curve" : 0 },
  1815. /* 87 */ { "x" : 707.5, "y" : -85, "bCoef" : 1, "cMask" : ["ball" ], "trait" : "ballArea", "vis" : false, "curve" : 0 }
  1816.  
  1817. ],
  1818.  
  1819. "segments" : [
  1820. { "v0" : 8, "v1" : 9, "curve" : 0, "color" : "DA4D4B", "trait" : "goalNet" },
  1821. { "v0" : 9, "v1" : 10, "curve" : -23, "color" : "DA4D4B", "trait" : "goalNet", "bCoef" : 0.8 },
  1822. { "v0" : 10, "v1" : 11, "curve" : 0, "color" : "DA4D4B", "trait" : "goalNet" },
  1823. { "v0" : 12, "v1" : 13, "curve" : 0, "color" : "3377ae", "trait" : "goalNet" },
  1824. { "v0" : 13, "v1" : 14, "curve" : 23, "color" : "3377ae", "trait" : "goalNet", "bCoef" : 0.8 },
  1825. { "v0" : 14, "v1" : 15, "curve" : 0, "color" : "3377ae", "trait" : "goalNet" },
  1826.  
  1827. { "v0" : 4, "v1" : 5, "trait" : "kickOffBarrier" },
  1828. { "v0" : 5, "v1" : 6, "curve" : 180, "vis" : true, "color" : "DA4D4B", "cGroup" : ["blueKO" ], "trait" : "kickOffBarrier" },
  1829. { "v0" : 5, "v1" : 6, "curve" : -180, "vis" : true, "color" : "3377ae", "cGroup" : ["redKO" ], "trait" : "kickOffBarrier" },
  1830. { "v0" : 6, "v1" : 7, "trait" : "kickOffBarrier" },
  1831.  
  1832. { "v0" : 16, "v1" : 17, "vis" : true, "color" : "1e252a", "bCoef" : 1.25, "cMask" : ["ball" ], "trait" : "ballArea" },
  1833. { "v0" : 18, "v1" : 19, "vis" : true, "color" : "1e252a", "bCoef" : 1.25, "cMask" : ["ball" ], "trait" : "ballArea" },
  1834. { "v0" : 20, "v1" : 21, "vis" : true, "color" : "1e252a", "bCoef" : 2, "cMask" : ["ball" ], "trait" : "ballArea" },
  1835. { "v0" : 22, "v1" : 23, "vis" : true, "color" : "1e252a", "bCoef" : 1.25, "cMask" : ["ball" ], "trait" : "ballArea" },
  1836. { "v0" : 24, "v1" : 25, "vis" : true, "color" : "1e252a", "bCoef" : 1.25, "cMask" : ["ball" ], "trait" : "ballArea" },
  1837. { "v0" : 26, "v1" : 27, "vis" : true, "color" : "F8F8F8", "bCoef" : 0, "cMask" : ["ball" ], "trait" : "ballArea" },
  1838. { "v0" : 28, "v1" : 29, "vis" : true, "color" : "1e252a", "bCoef" : 2, "cMask" : ["ball" ], "trait" : "ballArea" },
  1839.  
  1840. { "v0" : 30, "v1" : 31, "vis" : true, "color" : "1e252a", "bCoef" : 0.1, "cMask" : ["red","blue" ], "cGroup" : ["redKO","blueKO" ], "trait" : "kickOffBarrier" },
  1841. { "v0" : 32, "v1" : 33, "vis" : true, "color" : "1e252a", "bCoef" : 0.1, "cMask" : ["red","blue" ], "cGroup" : ["redKO","blueKO" ], "trait" : "kickOffBarrier" },
  1842.  
  1843. { "v0" : 41, "v1" : 42, "curve" : 0, "vis" : false, "color" : "F8F8F8", "bCoef" : 1, "cMask" : ["ball" ], "trait" : "ballArea", "x" : -707.5 },
  1844.  
  1845. { "v0" : 46, "v1" : 47, "vis" : true, "color" : "737573", "bCoef" : 0.1, "cMask" : ["blue" ], "cGroup" : ["redKO","blueKO" ], "trait" : "kickOffBarrier", "x" : -700 },
  1846. { "v0" : 48, "v1" : 49, "vis" : true, "color" : "737573", "bCoef" : 0.1, "cMask" : ["red" ], "cGroup" : ["redKO","blueKO" ], "trait" : "kickOffBarrier", "x" : 700 },
  1847.  
  1848. { "v0" : 50, "v1" : 51, "curve" : 0, "vis" : true, "color" : "737573", "bCoef" : 0.1, "cMask" : ["wall" ], "trait" : "goalNet" },
  1849. { "v0" : 52, "v1" : 53, "curve" : 0, "vis" : true, "color" : "737573", "bCoef" : 0.1, "cMask" : ["wall" ], "trait" : "goalNet", "x" : 385.5 },
  1850.  
  1851. { "v0" : 54, "v1" : 55, "curve" : 90, "vis" : true, "color" : "737573", "cMask" : ["wall" ] },
  1852. { "v0" : 56, "v1" : 57, "curve" : -90, "vis" : true, "color" : "737573", "cMask" : ["wall" ], "x" : 385.5 },
  1853. { "v0" : 58, "v1" : 59, "curve" : 0, "vis" : true, "color" : "737573", "cMask" : ["wall" ] },
  1854. { "v0" : 60, "v1" : 61, "curve" : 0, "vis" : true, "color" : "737573", "cMask" : ["wall" ], "y" : 115 },
  1855. { "v0" : 62, "v1" : 63, "curve" : 0, "vis" : true, "color" : "737573", "cMask" : ["wall" ] },
  1856. { "v0" : 64, "v1" : 65, "curve" : 0, "vis" : true, "color" : "737573", "cMask" : ["wall" ], "y" : 215 },
  1857. { "v0" : 66, "v1" : 67, "curve" : 0, "vis" : true, "color" : "737573", "cMask" : ["wall" ], "y" : -115 },
  1858. { "v0" : 68, "v1" : 69, "curve" : 0, "vis" : true, "color" : "737573", "cMask" : ["wall" ], "x" : 620 },
  1859. { "v0" : 70, "v1" : 71, "curve" : 180, "vis" : true, "color" : "737573", "cMask" : ["wall" ] },
  1860. { "v0" : 72, "v1" : 73, "curve" : -180, "vis" : true, "color" : "737573", "cMask" : ["wall" ] },
  1861. { "v0" : 74, "v1" : 75, "curve" : 180, "vis" : true, "color" : "737573", "cMask" : ["wall" ], "x" : -500 },
  1862. { "v0" : 76, "v1" : 77, "curve" : -180, "vis" : true, "color" : "737573", "cMask" : ["wall" ], "x" : -500 },
  1863. { "v0" : 78, "v1" : 79, "curve" : 180, "vis" : true, "color" : "737573", "cMask" : ["wall" ], "x" : 0 },
  1864. { "v0" : 80, "v1" : 81, "curve" : -180, "vis" : true, "color" : "737573", "cMask" : ["wall" ], "x" : 0 },
  1865.  
  1866. { "v0" : 82, "v1" : 83, "curve" : 0, "vis" : false, "color" : "F8F8F8", "bCoef" : 1, "cMask" : ["ball" ], "trait" : "ballArea", "x" : -707.5 },
  1867. { "v0" : 84, "v1" : 85, "curve" : 0, "vis" : false, "color" : "F8F8F8", "bCoef" : 1, "cMask" : ["ball" ], "trait" : "ballArea", "x" : 707.5 },
  1868. { "v0" : 86, "v1" : 87, "curve" : 0, "vis" : false, "color" : "F8F8F8", "bCoef" : 1, "cMask" : ["ball" ], "trait" : "ballArea", "x" : 707.5 }
  1869.  
  1870. ],
  1871.  
  1872. "goals" : [
  1873. { "p0" : [-706,91 ], "p1" : [-706,-79 ], "team" : "red" },
  1874. { "p0" : [706,91 ], "p1" : [706,-79 ], "team" : "blue" }
  1875.  
  1876. ],
  1877.  
  1878. "discs" : [
  1879. { "radius" : 5.4, "pos" : [-700,85 ], "color" : "ce9e9e", "trait" : "goalPost" },
  1880. { "radius" : 5.4, "pos" : [-700,-85 ], "color" : "ce9e9e", "trait" : "goalPost" },
  1881. { "radius" : 5.4, "pos" : [699,85 ], "color" : "9eafce", "trait" : "goalPost" },
  1882. { "radius" : 5.4, "pos" : [699,-84 ], "color" : "9eafce", "trait" : "goalPost" }
  1883.  
  1884. ],
  1885.  
  1886. "planes" : [
  1887. { "normal" : [0,1 ], "dist" : -320, "trait" : "ballArea", "vis" : false, "curve" : 0 },
  1888. { "normal" : [0,-1 ], "dist" : -320, "trait" : "ballArea" },
  1889.  
  1890. { "normal" : [0,1 ], "dist" : -350, "bCoef" : 0.1 },
  1891. { "normal" : [0,-1 ], "dist" : -352, "bCoef" : 0.1 },
  1892. { "normal" : [1,0 ], "dist" : -800, "bCoef" : 0.1 },
  1893. { "normal" : [-1,0 ], "dist" : -800, "bCoef" : 0.1 },
  1894.  
  1895. { "bCoef" : 0.8, "cMask" : ["ball" ], "trait" : "goalNet", "dist" : -754, "normal" : [-1,0 ] },
  1896. { "bCoef" : 0.8, "cMask" : ["ball" ], "trait" : "goalNet", "dist" : -753.006773306292, "normal" : [0.9999309835650598,0.011748536360424984 ] }
  1897.  
  1898. ],
  1899.  
  1900. "traits" : {
  1901. "ballArea" : { "vis" : false, "bCoef" : 1, "cMask" : ["ball" ] },
  1902. "goalPost" : { "radius" : 8, "invMass" : 0, "bCoef" : 0.5 },
  1903. "goalNet" : { "vis" : true, "bCoef" : 0.1, "cMask" : ["ball" ] },
  1904. "kickOffBarrier" : { "vis" : false, "bCoef" : 0.1, "cGroup" : ["redKO","blueKO" ], "cMask" : ["red","blue" ] }
  1905.  
  1906. },
  1907.  
  1908. "playerPhysics" : {
  1909. "bCoef" : 0,
  1910. "acceleration" : 0.11,
  1911. "kickingAcceleration" : 0.083,
  1912. "kickStrength" : 4.545
  1913.  
  1914. },
  1915.  
  1916. "ballPhysics" : {
  1917. "radius" : 5.8,
  1918. "bCoef" : 0.412,
  1919. "invMass" : 1.5,
  1920. "damping" : 0.99,
  1921. "color" : "ffd133"
  1922.  
  1923. }
  1924. }`;
  1925.  
  1926. var mediummap = `{
  1927.  
  1928. "name" : "EFC 3v3 by Kang & Oprah)",
  1929.  
  1930. "width" : 648,
  1931.  
  1932. "height" : 270,
  1933.  
  1934. "spawnDistance" : 350,
  1935.  
  1936. "bg" : { "type" : "hockey" },
  1937.  
  1938. "vertexes" : [
  1939. /* 0 */ { "x" : 550, "y" : 240, "trait" : "ballArea" },
  1940. /* 1 */ { "x" : 550, "y" : -240, "trait" : "ballArea" },
  1941.  
  1942. /* 2 */ { "x" : 0, "y" : 270, "trait" : "kickOffBarrier" },
  1943. /* 3 */ { "x" : 0, "y" : 80, "trait" : "kickOffBarrier", "color" : "3377ae", "vis" : true, "curve" : 180 },
  1944. /* 4 */ { "x" : 0, "y" : -80, "trait" : "kickOffBarrier", "color" : "3377ae", "vis" : true, "curve" : 180 },
  1945. /* 5 */ { "x" : 0, "y" : -270, "trait" : "kickOffBarrier" },
  1946.  
  1947. /* 6 */ { "x" : -550, "y" : -80, "cMask" : ["ball" ], "trait" : "goalNet", "curve" : 0, "color" : "DA4D4B", "pos" : [-700,-80 ] },
  1948. /* 7 */ { "x" : -590, "y" : -80, "cMask" : ["ball" ], "trait" : "goalNet", "curve" : -23, "color" : "DA4D4B", "pos" : [-700,-80 ], "bCoef" : 0.8 },
  1949. /* 8 */ { "x" : -590, "y" : 80, "cMask" : ["ball" ], "trait" : "goalNet", "curve" : -23, "color" : "DA4D4B", "pos" : [-700,80 ], "bCoef" : 0.8 },
  1950. /* 9 */ { "x" : -550, "y" : 80, "cMask" : ["ball" ], "trait" : "goalNet", "curve" : 0, "color" : "DA4D4B", "pos" : [-700,80 ] },
  1951. /* 10 */ { "x" : 550, "y" : -80, "cMask" : ["ball" ], "trait" : "goalNet", "curve" : 0, "color" : "3377ae", "pos" : [700,-80 ] },
  1952. /* 11 */ { "x" : 590, "y" : -80, "cMask" : ["ball" ], "trait" : "goalNet", "curve" : 23, "color" : "3377ae", "pos" : [700,-80 ], "bCoef" : 0.8 },
  1953. /* 12 */ { "x" : 590, "y" : 80, "cMask" : ["ball" ], "trait" : "goalNet", "curve" : 23, "color" : "3377ae", "pos" : [700,80 ], "bCoef" : 0.8 },
  1954. /* 13 */ { "x" : 550, "y" : 80, "cMask" : ["ball" ], "trait" : "goalNet", "curve" : 0, "color" : "3377ae", "pos" : [700,80 ] },
  1955.  
  1956. /* 14 */ { "x" : -550, "y" : 80, "bCoef" : 1, "cMask" : ["ball" ], "trait" : "ballArea", "color" : "1e252a", "pos" : [-700,80 ], "_selected" : "segment" },
  1957. /* 15 */ { "x" : -550, "y" : 240, "bCoef" : 1, "cMask" : ["ball" ], "trait" : "ballArea", "color" : "1e252a", "_selected" : "segment" },
  1958. /* 16 */ { "x" : -550, "y" : -80, "bCoef" : 1, "cMask" : ["ball" ], "trait" : "ballArea", "color" : "1e252a", "pos" : [-700,-80 ] },
  1959. /* 17 */ { "x" : -550, "y" : -240, "bCoef" : 1, "cMask" : ["ball" ], "trait" : "ballArea", "color" : "1e252a" },
  1960. /* 18 */ { "x" : -550, "y" : 240, "bCoef" : 1, "cMask" : ["ball" ], "trait" : "ballArea", "color" : "1e252a" },
  1961. /* 19 */ { "x" : 550, "y" : 240, "bCoef" : 1, "cMask" : ["ball" ], "trait" : "ballArea", "color" : "1e252a" },
  1962. /* 20 */ { "x" : 550, "y" : 80, "bCoef" : 1, "cMask" : ["ball" ], "trait" : "ballArea", "pos" : [700,80 ], "color" : "1e252a" },
  1963. /* 21 */ { "x" : 550, "y" : 240, "bCoef" : 1, "cMask" : ["ball" ], "trait" : "ballArea", "color" : "1e252a" },
  1964. /* 22 */ { "x" : 550, "y" : -240, "bCoef" : 1, "cMask" : ["ball" ], "trait" : "ballArea", "color" : "1e252a" },
  1965. /* 23 */ { "x" : 550, "y" : -80, "bCoef" : 1, "cMask" : ["ball" ], "trait" : "ballArea", "color" : "1e252a", "pos" : [700,-80 ] },
  1966. /* 24 */ { "x" : 550, "y" : -240, "bCoef" : 0, "cMask" : ["ball" ], "trait" : "ballArea" },
  1967. /* 25 */ { "x" : 550, "y" : -240, "bCoef" : 0, "cMask" : ["ball" ], "trait" : "ballArea" },
  1968. /* 26 */ { "x" : -550, "y" : -240, "bCoef" : 1, "cMask" : ["ball" ], "trait" : "ballArea", "curve" : 0, "color" : "1e252a" },
  1969. /* 27 */ { "x" : 550, "y" : -240, "bCoef" : 1, "cMask" : ["ball" ], "trait" : "ballArea", "curve" : 0, "color" : "1e252a" },
  1970.  
  1971. /* 28 */ { "x" : 0, "y" : -240, "bCoef" : 0.1, "cMask" : ["red","blue" ], "cGroup" : ["redKO","blueKO" ], "trait" : "kickOffBarrier", "color" : "1e252a" },
  1972. /* 29 */ { "x" : 0, "y" : -82, "bCoef" : 0.1, "cMask" : ["red","blue" ], "cGroup" : ["redKO","blueKO" ], "trait" : "kickOffBarrier", "color" : "1e252a" },
  1973. /* 30 */ { "x" : 0, "y" : 82, "bCoef" : 0.1, "cMask" : ["red","blue" ], "cGroup" : ["redKO","blueKO" ], "trait" : "kickOffBarrier", "color" : "1e252a" },
  1974. /* 31 */ { "x" : 0, "y" : 240, "bCoef" : 0.1, "cMask" : ["red","blue" ], "cGroup" : ["redKO","blueKO" ], "trait" : "kickOffBarrier", "color" : "1e252a" },
  1975. /* 32 */ { "x" : 0, "y" : -82, "bCoef" : 0.1, "cMask" : ["red","blue" ], "trait" : "kickOffBarrier", "vis" : true, "color" : "F8F8F8" },
  1976. /* 33 */ { "x" : 0, "y" : 82, "bCoef" : 0.1, "cMask" : ["red","blue" ], "trait" : "kickOffBarrier", "vis" : true, "color" : "F8F8F8" },
  1977. /* 34 */ { "x" : 0, "y" : 82, "trait" : "kickOffBarrier", "color" : "F8F8F8", "vis" : true, "curve" : -180 },
  1978. /* 35 */ { "x" : 0, "y" : -82, "trait" : "kickOffBarrier", "color" : "F8F8F8", "vis" : true, "curve" : -180 },
  1979. /* 36 */ { "x" : 0, "y" : 82, "trait" : "kickOffBarrier", "color" : "F8F8F8", "vis" : true, "curve" : 0 },
  1980. /* 37 */ { "x" : 0, "y" : -82, "trait" : "kickOffBarrier", "color" : "F8F8F8", "vis" : true, "curve" : 0 },
  1981.  
  1982. /* 38 */ { "x" : -557.5, "y" : 80, "bCoef" : 0.1, "cMask" : ["ball" ], "trait" : "ballArea", "curve" : 0, "vis" : false, "pos" : [-700,80 ] },
  1983. /* 39 */ { "x" : -557.5, "y" : 240, "bCoef" : 2, "cMask" : ["ball" ], "trait" : "ballArea", "curve" : 0, "vis" : false },
  1984. /* 40 */ { "x" : -557.5, "y" : -240, "bCoef" : 2, "cMask" : ["ball" ], "trait" : "ballArea", "vis" : false, "curve" : 0 },
  1985. /* 41 */ { "x" : -557.5, "y" : -80, "bCoef" : 0.1, "cMask" : ["ball" ], "trait" : "ballArea", "vis" : false, "curve" : 0, "pos" : [-700,-80 ] },
  1986. /* 42 */ { "x" : 557.5, "y" : -240, "bCoef" : 2, "cMask" : ["ball" ], "trait" : "ballArea", "vis" : false, "curve" : 0 },
  1987. /* 43 */ { "x" : 557.5, "y" : -80, "bCoef" : 0.1, "cMask" : ["ball" ], "trait" : "ballArea", "vis" : false, "curve" : 0, "pos" : [700,-80 ] },
  1988. /* 44 */ { "x" : 557.5, "y" : 80, "bCoef" : 0.1, "cMask" : ["ball" ], "trait" : "ballArea", "curve" : 0, "vis" : false, "pos" : [700,80 ] },
  1989. /* 45 */ { "x" : 557.5, "y" : 240, "bCoef" : 2, "cMask" : ["ball" ], "trait" : "ballArea", "curve" : 0, "vis" : false },
  1990.  
  1991. /* 46 */ { "x" : 0, "y" : 82, "bCoef" : 0.1, "trait" : "line", "color" : "afa370" },
  1992. /* 47 */ { "x" : -550, "y" : -80, "bCoef" : 0.1, "trait" : "line", "color" : "737573" },
  1993. /* 48 */ { "x" : -550, "y" : 80, "bCoef" : 0.1, "trait" : "line", "color" : "737573" },
  1994. /* 49 */ { "x" : 550, "y" : -80, "bCoef" : 0.1, "trait" : "line", "color" : "737573" },
  1995. /* 50 */ { "x" : 550, "y" : 80, "bCoef" : 0.1, "trait" : "line", "color" : "737573" },
  1996. /* 51 */ { "x" : -548, "y" : 160, "bCoef" : 0.1, "trait" : "line", "color" : "737573", "curve" : -180 },
  1997. /* 52 */ { "x" : -548, "y" : -160, "bCoef" : 0.1, "trait" : "line", "color" : "737573", "curve" : -180 },
  1998. /* 53 */ { "x" : 548, "y" : 160, "bCoef" : 0.1, "trait" : "line", "color" : "737573", "curve" : 180 },
  1999. /* 54 */ { "x" : 548, "y" : -160, "bCoef" : 0.1, "trait" : "line", "color" : "737573", "curve" : 180 },
  2000. /* 55 */ { "x" : 0, "y" : -2, "bCoef" : 0.1, "trait" : "line", "color" : "737573" },
  2001. /* 56 */ { "x" : 0, "y" : 2, "bCoef" : 0.1, "trait" : "line", "color" : "737573" },
  2002. /* 57 */ { "x" : 0, "y" : -2, "bCoef" : 0.1, "trait" : "line", "curve" : 180, "color" : "737573" },
  2003. /* 58 */ { "x" : 0, "y" : 2, "bCoef" : 0.1, "trait" : "line", "curve" : 180, "color" : "737573" },
  2004. /* 59 */ { "x" : 480, "y" : -2, "bCoef" : 0.1, "trait" : "line", "color" : "737573" },
  2005. /* 60 */ { "x" : 480, "y" : 2, "bCoef" : 0.1, "trait" : "line", "color" : "737573" },
  2006. /* 61 */ { "x" : 480, "y" : -2, "bCoef" : 0.1, "trait" : "line", "curve" : 180, "color" : "737573" },
  2007. /* 62 */ { "x" : 480, "y" : 2, "bCoef" : 0.1, "trait" : "line", "curve" : 180, "color" : "737573" },
  2008. /* 63 */ { "x" : -480, "y" : -2, "bCoef" : 0.1, "trait" : "line", "color" : "737573" },
  2009. /* 64 */ { "x" : -480, "y" : 2, "bCoef" : 0.1, "trait" : "line", "color" : "737573" },
  2010. /* 65 */ { "x" : -480, "y" : -2, "bCoef" : 0.1, "trait" : "line", "curve" : 180, "color" : "737573" },
  2011. /* 66 */ { "x" : -480, "y" : 2, "bCoef" : 0.1, "trait" : "line", "curve" : 180, "color" : "737573" }
  2012.  
  2013. ],
  2014.  
  2015. "segments" : [
  2016. { "v0" : 6, "v1" : 7, "curve" : 0, "color" : "DA4D4B", "cMask" : ["ball" ], "trait" : "goalNet", "pos" : [-700,-80 ], "y" : -80 },
  2017. { "v0" : 7, "v1" : 8, "curve" : -23, "color" : "DA4D4B", "cMask" : ["ball" ], "trait" : "goalNet", "x" : -590, "bCoef" : 0.8 },
  2018. { "v0" : 8, "v1" : 9, "curve" : 0, "color" : "DA4D4B", "cMask" : ["ball" ], "trait" : "goalNet", "pos" : [-700,80 ], "y" : 80 },
  2019. { "v0" : 10, "v1" : 11, "curve" : 0, "color" : "3377ae", "cMask" : ["ball" ], "trait" : "goalNet", "pos" : [700,-80 ], "y" : -80 },
  2020. { "v0" : 11, "v1" : 12, "curve" : 23, "color" : "3377ae", "cMask" : ["ball" ], "trait" : "goalNet", "x" : 590, "bCoef" : 0.8 },
  2021. { "v0" : 12, "v1" : 13, "curve" : 0, "color" : "3377ae", "cMask" : ["ball" ], "trait" : "goalNet", "pos" : [700,80 ], "y" : 80 },
  2022.  
  2023. { "v0" : 2, "v1" : 3, "trait" : "kickOffBarrier" },
  2024. { "v0" : 3, "v1" : 4, "curve" : 180, "vis" : true, "color" : "DA4D4B", "cGroup" : ["blueKO" ], "trait" : "kickOffBarrier" },
  2025. { "v0" : 3, "v1" : 4, "curve" : -180, "vis" : true, "color" : "3377ae", "cGroup" : ["redKO" ], "trait" : "kickOffBarrier" },
  2026. { "v0" : 4, "v1" : 5, "trait" : "kickOffBarrier" },
  2027.  
  2028. { "v0" : 14, "v1" : 15, "vis" : true, "color" : "1e252a", "bCoef" : 1, "cMask" : ["ball" ], "trait" : "ballArea", "x" : -550, "_selected" : true },
  2029. { "v0" : 16, "v1" : 17, "vis" : true, "color" : "1e252a", "bCoef" : 1, "cMask" : ["ball" ], "trait" : "ballArea", "x" : -550 },
  2030. { "v0" : 18, "v1" : 19, "curve" : 0, "vis" : true, "color" : "1e252a", "bCoef" : 1, "cMask" : ["ball" ], "trait" : "ballArea", "y" : 240 },
  2031. { "v0" : 20, "v1" : 21, "vis" : true, "color" : "1e252a", "bCoef" : 1, "cMask" : ["ball" ], "trait" : "ballArea", "x" : 550 },
  2032. { "v0" : 22, "v1" : 23, "vis" : true, "color" : "1e252a", "bCoef" : 1, "cMask" : ["ball" ], "trait" : "ballArea", "x" : 550 },
  2033. { "v0" : 24, "v1" : 25, "vis" : true, "color" : "F8F8F8", "bCoef" : 0, "cMask" : ["ball" ], "trait" : "ballArea", "x" : 550, "y" : -240 },
  2034. { "v0" : 26, "v1" : 27, "curve" : 0, "vis" : true, "color" : "1e252a", "bCoef" : 1, "cMask" : ["ball" ], "trait" : "ballArea", "y" : -240 },
  2035.  
  2036. { "v0" : 28, "v1" : 29, "vis" : true, "color" : "1e252a", "bCoef" : 0.1, "cMask" : ["red","blue" ], "cGroup" : ["redKO","blueKO" ], "trait" : "kickOffBarrier" },
  2037. { "v0" : 30, "v1" : 31, "vis" : true, "color" : "1e252a", "bCoef" : 0.1, "cMask" : ["red","blue" ], "cGroup" : ["redKO","blueKO" ], "trait" : "kickOffBarrier" },
  2038.  
  2039. { "v0" : 38, "v1" : 39, "curve" : 0, "vis" : false, "color" : "F8F8F8", "bCoef" : 2, "cMask" : ["ball" ], "trait" : "ballArea", "x" : -557.5 },
  2040. { "v0" : 40, "v1" : 41, "curve" : 0, "vis" : false, "color" : "F8F8F8", "bCoef" : 2, "cMask" : ["ball" ], "trait" : "ballArea", "x" : -557.5 },
  2041. { "v0" : 42, "v1" : 43, "curve" : 0, "vis" : false, "color" : "F8F8F8", "bCoef" : 2, "cMask" : ["ball" ], "trait" : "ballArea", "x" : 557.5 },
  2042. { "v0" : 44, "v1" : 45, "curve" : 0, "vis" : false, "color" : "F8F8F8", "bCoef" : 2, "cMask" : ["ball" ], "trait" : "ballArea", "x" : 557.5 },
  2043.  
  2044. { "v0" : 47, "v1" : 48, "curve" : 0, "vis" : true, "color" : "737573", "bCoef" : 0.1, "trait" : "line", "x" : -550 },
  2045. { "v0" : 49, "v1" : 50, "curve" : 0, "vis" : true, "color" : "737573", "bCoef" : 0.1, "trait" : "line", "x" : 550 },
  2046. { "v0" : 51, "v1" : 52, "curve" : -180, "vis" : true, "color" : "737573", "bCoef" : 0.1, "trait" : "line" },
  2047. { "v0" : 53, "v1" : 54, "curve" : 180, "vis" : true, "color" : "737573", "bCoef" : 0.1, "trait" : "line", "x" : 548 },
  2048. { "v0" : 55, "v1" : 56, "curve" : -180, "vis" : true, "color" : "737573", "bCoef" : 0.1, "trait" : "line" },
  2049. { "v0" : 57, "v1" : 58, "curve" : 180, "vis" : true, "color" : "737573", "bCoef" : 0.1, "trait" : "line" },
  2050. { "v0" : 59, "v1" : 60, "curve" : -180, "vis" : true, "color" : "737573", "bCoef" : 0.1, "trait" : "line", "x" : 480 },
  2051. { "v0" : 61, "v1" : 62, "curve" : 180, "vis" : true, "color" : "737573", "bCoef" : 0.1, "trait" : "line", "x" : 480 },
  2052. { "v0" : 63, "v1" : 64, "curve" : -180, "vis" : true, "color" : "737573", "bCoef" : 0.1, "trait" : "line", "x" : -480 },
  2053. { "v0" : 65, "v1" : 66, "curve" : 180, "vis" : true, "color" : "737573", "bCoef" : 0.1, "trait" : "line", "x" : -480 }
  2054.  
  2055. ],
  2056.  
  2057. "goals" : [
  2058. { "p0" : [-556.3,-80 ], "p1" : [-556.3,80 ], "team" : "red" },
  2059. { "p0" : [556.3,80 ], "p1" : [556.3,-80 ], "team" : "blue" }
  2060.  
  2061. ],
  2062.  
  2063. "discs" : [
  2064. { "radius" : 5, "pos" : [-550,80 ], "color" : "ce9e9e", "trait" : "goalPost", "y" : 80 },
  2065. { "radius" : 5, "pos" : [-550,-80 ], "color" : "ce9e9e", "trait" : "goalPost", "y" : -80, "x" : -560 },
  2066. { "radius" : 5, "pos" : [550,80 ], "color" : "9eafce", "trait" : "goalPost", "y" : 80 },
  2067. { "radius" : 5, "pos" : [550,-80 ], "color" : "9eafce", "trait" : "goalPost", "y" : -80 }
  2068.  
  2069. ],
  2070.  
  2071. "planes" : [
  2072. { "normal" : [0,1 ], "dist" : -240, "bCoef" : 1, "trait" : "ballArea", "vis" : false, "curve" : 0 },
  2073. { "normal" : [0,-1 ], "dist" : -240, "bCoef" : 1, "trait" : "ballArea" },
  2074.  
  2075. { "normal" : [0,1 ], "dist" : -270, "bCoef" : 0.1 },
  2076. { "normal" : [0,-1 ], "dist" : -270, "bCoef" : 0.1 },
  2077. { "normal" : [1,0 ], "dist" : -642, "bCoef" : 0.1 },
  2078. { "normal" : [-1,0 ], "dist" : -644, "bCoef" : 0.1 },
  2079.  
  2080. { "normal" : [1,0 ], "dist" : -642, "bCoef" : 0.1, "trait" : "ballArea", "vis" : false, "curve" : 0 },
  2081. { "normal" : [-1,0 ], "dist" : -643, "bCoef" : 0.1, "trait" : "ballArea", "vis" : false, "curve" : 0 }
  2082.  
  2083. ],
  2084.  
  2085. "traits" : {
  2086. "ballArea" : { "vis" : false, "bCoef" : 1, "cMask" : ["ball" ] },
  2087. "goalPost" : { "radius" : 8, "invMass" : 0, "bCoef" : 0.5 },
  2088. "goalNet" : { "vis" : true, "bCoef" : 0.1, "cMask" : ["ball" ] },
  2089. "line" : { "vis" : true, "bCoef" : 0.1, "cMask" : ["" ] },
  2090. "kickOffBarrier" : { "vis" : false, "bCoef" : 0.1, "cGroup" : ["redKO","blueKO" ], "cMask" : ["red","blue" ] }
  2091.  
  2092. },
  2093.  
  2094. "playerPhysics" : {
  2095. "bCoef" : 0,
  2096. "acceleration" : 0.11,
  2097. "kickingAcceleration" : 0.083,
  2098. "kickStrength" : 4.2
  2099.  
  2100. },
  2101.  
  2102. "ballPhysics" : {
  2103. "radius" : 5.8,
  2104. "bCoef" : 0.412,
  2105. "invMass" : 1.5,
  2106. "damping" : 0.99,
  2107. "color" : "ffd133"
  2108.  
  2109. }
  2110. }`;
  2111.  
  2112.  
  2113. var smallmap = `{
  2114.  
  2115. "name" : "[EFC] 1vs1 / 2vs2 by Oprah",
  2116.  
  2117. "width" : 497,
  2118.  
  2119. "height" : 220,
  2120.  
  2121. "spawnDistance" : 350,
  2122.  
  2123. "bg" : { "type" : "hockey" },
  2124.  
  2125. "vertexes" : [
  2126. /* 0 */ { "x" : 400, "y" : 190, "trait" : "ballArea" },
  2127. /* 1 */ { "x" : 400, "y" : -190, "trait" : "ballArea" },
  2128.  
  2129. /* 2 */ { "x" : 0, "y" : 220, "trait" : "kickOffBarrier" },
  2130. /* 3 */ { "x" : 0, "y" : 60, "trait" : "kickOffBarrier", "color" : "3377ae", "vis" : true, "curve" : 180 },
  2131. /* 4 */ { "x" : 0, "y" : -60, "trait" : "kickOffBarrier", "color" : "3377ae", "vis" : true, "curve" : 180 },
  2132. /* 5 */ { "x" : 0, "y" : -220, "trait" : "kickOffBarrier" },
  2133.  
  2134. /* 6 */ { "x" : -400, "y" : -70, "cMask" : ["ball" ], "trait" : "goalNet", "curve" : 0, "color" : "DA4D4B", "pos" : [-700,-80 ] },
  2135. /* 7 */ { "x" : -440, "y" : -70, "cMask" : ["ball" ], "trait" : "goalNet", "curve" : -23, "color" : "DA4D4B", "pos" : [-700,-80 ], "bCoef" : 0.8 },
  2136. /* 8 */ { "x" : -440, "y" : 70, "cMask" : ["ball" ], "trait" : "goalNet", "curve" : -23, "color" : "DA4D4B", "pos" : [-700,80 ], "bCoef" : 0.8 },
  2137. /* 9 */ { "x" : -400, "y" : 70, "cMask" : ["ball" ], "trait" : "goalNet", "curve" : 0, "color" : "DA4D4B", "pos" : [-700,80 ] },
  2138. /* 10 */ { "x" : 400, "y" : -70, "cMask" : ["ball" ], "trait" : "goalNet", "curve" : 0, "color" : "3377ae", "pos" : [700,-80 ] },
  2139. /* 11 */ { "x" : 440, "y" : -70, "cMask" : ["ball" ], "trait" : "goalNet", "curve" : 23, "color" : "3377ae", "pos" : [700,-80 ], "bCoef" : 0.8 },
  2140. /* 12 */ { "x" : 440, "y" : 70, "cMask" : ["ball" ], "trait" : "goalNet", "curve" : 23, "color" : "3377ae", "pos" : [700,80 ], "bCoef" : 0.8 },
  2141. /* 13 */ { "x" : 400, "y" : 70, "cMask" : ["ball" ], "trait" : "goalNet", "curve" : 0, "color" : "3377ae", "pos" : [700,80 ] },
  2142.  
  2143. /* 14 */ { "x" : -400, "y" : 70, "bCoef" : 1, "cMask" : ["ball" ], "trait" : "ballArea", "color" : "1e252a", "pos" : [-700,80 ] },
  2144. /* 15 */ { "x" : -400, "y" : 190, "bCoef" : 1, "cMask" : ["ball" ], "trait" : "ballArea", "color" : "1e252a" },
  2145. /* 16 */ { "x" : -400, "y" : -70, "bCoef" : 1, "cMask" : ["ball" ], "trait" : "ballArea", "color" : "1e252a", "pos" : [-700,-80 ] },
  2146. /* 17 */ { "x" : -400, "y" : -190, "bCoef" : 1, "cMask" : ["ball" ], "trait" : "ballArea", "color" : "1e252a" },
  2147. /* 18 */ { "x" : -400, "y" : 190, "bCoef" : 1, "cMask" : ["ball" ], "trait" : "ballArea", "color" : "1e252a" },
  2148. /* 19 */ { "x" : 400, "y" : 190, "bCoef" : 1, "cMask" : ["ball" ], "trait" : "ballArea", "color" : "1e252a" },
  2149. /* 20 */ { "x" : 400, "y" : 70, "bCoef" : 1, "cMask" : ["ball" ], "trait" : "ballArea", "pos" : [700,80 ], "color" : "1e252a" },
  2150. /* 21 */ { "x" : 400, "y" : 190, "bCoef" : 1, "cMask" : ["ball" ], "trait" : "ballArea", "color" : "1e252a" },
  2151. /* 22 */ { "x" : 400, "y" : -190, "bCoef" : 1, "cMask" : ["ball" ], "trait" : "ballArea", "color" : "1e252a" },
  2152. /* 23 */ { "x" : 400, "y" : -70, "bCoef" : 1, "cMask" : ["ball" ], "trait" : "ballArea", "color" : "1e252a", "pos" : [700,-80 ] },
  2153. /* 24 */ { "x" : 400, "y" : -190, "bCoef" : 0, "cMask" : ["ball" ], "trait" : "ballArea" },
  2154. /* 25 */ { "x" : 400, "y" : -190, "bCoef" : 0, "cMask" : ["ball" ], "trait" : "ballArea" },
  2155. /* 26 */ { "x" : -400, "y" : -190, "bCoef" : 1, "cMask" : ["ball" ], "trait" : "ballArea", "curve" : 0, "color" : "1e252a" },
  2156. /* 27 */ { "x" : 400, "y" : -190, "bCoef" : 1, "cMask" : ["ball" ], "trait" : "ballArea", "curve" : 0, "color" : "1e252a" },
  2157.  
  2158. /* 28 */ { "x" : 0, "y" : -190, "bCoef" : 0.1, "cMask" : ["red","blue" ], "cGroup" : ["redKO","blueKO" ], "trait" : "kickOffBarrier", "color" : "1e252a" },
  2159. /* 29 */ { "x" : 0, "y" : -62, "bCoef" : 0.1, "cMask" : ["red","blue" ], "cGroup" : ["redKO","blueKO" ], "trait" : "kickOffBarrier", "color" : "1e252a" },
  2160. /* 30 */ { "x" : 0, "y" : 62, "bCoef" : 0.1, "cMask" : ["red","blue" ], "cGroup" : ["redKO","blueKO" ], "trait" : "kickOffBarrier", "color" : "1e252a" },
  2161. /* 31 */ { "x" : 0, "y" : 190, "bCoef" : 0.1, "cMask" : ["red","blue" ], "cGroup" : ["redKO","blueKO" ], "trait" : "kickOffBarrier", "color" : "1e252a" },
  2162. /* 32 */ { "x" : 0, "y" : -62, "bCoef" : 0.1, "cMask" : ["red","blue" ], "trait" : "kickOffBarrier", "vis" : true, "color" : "F8F8F8" },
  2163. /* 33 */ { "x" : 0, "y" : 62, "bCoef" : 0.1, "cMask" : ["red","blue" ], "trait" : "kickOffBarrier", "vis" : true, "color" : "F8F8F8" },
  2164. /* 34 */ { "x" : 0, "y" : 62, "trait" : "kickOffBarrier", "color" : "F8F8F8", "vis" : true, "curve" : -180 },
  2165. /* 35 */ { "x" : 0, "y" : -62, "trait" : "kickOffBarrier", "color" : "F8F8F8", "vis" : true, "curve" : -180 },
  2166. /* 36 */ { "x" : 0, "y" : 62, "trait" : "kickOffBarrier", "color" : "F8F8F8", "vis" : true, "curve" : 0 },
  2167. /* 37 */ { "x" : 0, "y" : -62, "trait" : "kickOffBarrier", "color" : "F8F8F8", "vis" : true, "curve" : 0 },
  2168.  
  2169. /* 38 */ { "x" : -407.5, "y" : 70, "bCoef" : 0.1, "cMask" : ["ball" ], "trait" : "ballArea", "curve" : 0, "vis" : false, "pos" : [-700,80 ] },
  2170. /* 39 */ { "x" : -407.5, "y" : 190, "bCoef" : 2, "cMask" : ["ball" ], "trait" : "ballArea", "curve" : 0, "vis" : false },
  2171. /* 40 */ { "x" : -407.5, "y" : -190, "bCoef" : 2, "cMask" : ["ball" ], "trait" : "ballArea", "vis" : false, "curve" : 0 },
  2172. /* 41 */ { "x" : -407.5, "y" : -70, "bCoef" : 0.1, "cMask" : ["ball" ], "trait" : "ballArea", "vis" : false, "curve" : 0, "pos" : [-700,-80 ] },
  2173. /* 42 */ { "x" : 407.5, "y" : -190, "bCoef" : 2, "cMask" : ["ball" ], "trait" : "ballArea", "vis" : false, "curve" : 0 },
  2174. /* 43 */ { "x" : 407.5, "y" : -70, "bCoef" : 0.1, "cMask" : ["ball" ], "trait" : "ballArea", "vis" : false, "curve" : 0, "pos" : [700,-80 ] },
  2175. /* 44 */ { "x" : 407.5, "y" : 70, "bCoef" : 0.1, "cMask" : ["ball" ], "trait" : "ballArea", "curve" : 0, "vis" : false, "pos" : [700,80 ] },
  2176. /* 45 */ { "x" : 407.5, "y" : 190, "bCoef" : 2, "cMask" : ["ball" ], "trait" : "ballArea", "curve" : 0, "vis" : false },
  2177.  
  2178. /* 46 */ { "x" : 0, "y" : 62, "bCoef" : 0.1, "trait" : "line", "color" : "afa370" },
  2179. /* 47 */ { "x" : -400, "y" : -70, "bCoef" : 0.1, "trait" : "line", "color" : "737573" },
  2180. /* 48 */ { "x" : -400, "y" : 70, "bCoef" : 0.1, "trait" : "line", "color" : "737573" },
  2181. /* 49 */ { "x" : 400, "y" : -70, "bCoef" : 0.1, "trait" : "line", "color" : "737573" },
  2182. /* 50 */ { "x" : 400, "y" : 70, "bCoef" : 0.1, "trait" : "line", "color" : "737573" },
  2183. /* 51 */ { "x" : 0, "y" : -2, "bCoef" : 0.1, "trait" : "line", "color" : "737573" },
  2184. /* 52 */ { "x" : 0, "y" : 2, "bCoef" : 0.1, "trait" : "line", "color" : "737573" },
  2185. /* 53 */ { "x" : 0, "y" : -2, "bCoef" : 0.1, "trait" : "line", "curve" : 180, "color" : "737573" },
  2186. /* 54 */ { "x" : 0, "y" : 2, "bCoef" : 0.1, "trait" : "line", "curve" : 180, "color" : "737573" },
  2187. /* 55 */ { "x" : -398, "y" : -130, "bCoef" : 0.1, "trait" : "line", "color" : "737573" },
  2188. /* 56 */ { "x" : -398, "y" : 130, "bCoef" : 0.1, "trait" : "line", "color" : "737573" },
  2189. /* 57 */ { "x" : 398, "y" : -130, "bCoef" : 0.1, "trait" : "line", "curve" : -180, "color" : "737573" },
  2190. /* 58 */ { "x" : 398, "y" : 130, "bCoef" : 0.1, "trait" : "line", "curve" : -180, "color" : "737573" },
  2191. /* 59 */ { "x" : 350, "y" : -2, "bCoef" : 0.1, "trait" : "line", "color" : "737573" },
  2192. /* 60 */ { "x" : 350, "y" : 2, "bCoef" : 0.1, "trait" : "line", "color" : "737573" },
  2193. /* 61 */ { "x" : 350, "y" : -2, "bCoef" : 0.1, "trait" : "line", "curve" : 180, "color" : "737573" },
  2194. /* 62 */ { "x" : 350, "y" : 2, "bCoef" : 0.1, "trait" : "line", "curve" : 180, "color" : "737573" },
  2195. /* 63 */ { "x" : -350, "y" : -2, "bCoef" : 0.1, "trait" : "line", "color" : "737573" },
  2196. /* 64 */ { "x" : -350, "y" : 2, "bCoef" : 0.1, "trait" : "line", "color" : "737573" },
  2197. /* 65 */ { "x" : -350, "y" : -2, "bCoef" : 0.1, "trait" : "line", "curve" : 180, "color" : "737573" },
  2198. /* 66 */ { "x" : -350, "y" : 2, "bCoef" : 0.1, "trait" : "line", "curve" : 180, "color" : "737573" }
  2199.  
  2200. ],
  2201.  
  2202. "segments" : [
  2203. { "v0" : 6, "v1" : 7, "curve" : 0, "color" : "DA4D4B", "cMask" : ["ball" ], "trait" : "goalNet", "pos" : [-700,-80 ], "y" : -70 },
  2204. { "v0" : 7, "v1" : 8, "curve" : -23, "color" : "DA4D4B", "cMask" : ["ball" ], "trait" : "goalNet", "x" : -440, "bCoef" : 0.8 },
  2205. { "v0" : 8, "v1" : 9, "curve" : 0, "color" : "DA4D4B", "cMask" : ["ball" ], "trait" : "goalNet", "pos" : [-700,80 ], "y" : 70 },
  2206. { "v0" : 10, "v1" : 11, "curve" : 0, "color" : "3377ae", "cMask" : ["ball" ], "trait" : "goalNet", "pos" : [700,-80 ], "y" : -70 },
  2207. { "v0" : 11, "v1" : 12, "curve" : 23, "color" : "3377ae", "cMask" : ["ball" ], "trait" : "goalNet", "x" : 440, "bCoef" : 0.8 },
  2208. { "v0" : 12, "v1" : 13, "curve" : 0, "color" : "3377ae", "cMask" : ["ball" ], "trait" : "goalNet", "pos" : [700,80 ], "y" : 70 },
  2209.  
  2210. { "v0" : 2, "v1" : 3, "trait" : "kickOffBarrier" },
  2211. { "v0" : 3, "v1" : 4, "curve" : 180, "vis" : true, "color" : "DA4D4B", "cGroup" : ["blueKO" ], "trait" : "kickOffBarrier" },
  2212. { "v0" : 3, "v1" : 4, "curve" : -180, "vis" : true, "color" : "3377ae", "cGroup" : ["redKO" ], "trait" : "kickOffBarrier" },
  2213. { "v0" : 4, "v1" : 5, "trait" : "kickOffBarrier" },
  2214.  
  2215. { "v0" : 14, "v1" : 15, "vis" : true, "color" : "1e252a", "bCoef" : 1, "cMask" : ["ball" ], "trait" : "ballArea", "x" : -400 },
  2216. { "v0" : 16, "v1" : 17, "vis" : true, "color" : "1e252a", "bCoef" : 1, "cMask" : ["ball" ], "trait" : "ballArea", "x" : -400 },
  2217. { "v0" : 18, "v1" : 19, "curve" : 0, "vis" : true, "color" : "1e252a", "bCoef" : 1, "cMask" : ["ball" ], "trait" : "ballArea", "y" : 190 },
  2218. { "v0" : 20, "v1" : 21, "vis" : true, "color" : "1e252a", "bCoef" : 1, "cMask" : ["ball" ], "trait" : "ballArea", "x" : 400 },
  2219. { "v0" : 22, "v1" : 23, "vis" : true, "color" : "1e252a", "bCoef" : 1, "cMask" : ["ball" ], "trait" : "ballArea", "x" : 400 },
  2220. { "v0" : 24, "v1" : 25, "vis" : true, "color" : "F8F8F8", "bCoef" : 0, "cMask" : ["ball" ], "trait" : "ballArea", "x" : 400, "y" : -190 },
  2221. { "v0" : 26, "v1" : 27, "curve" : 0, "vis" : true, "color" : "1e252a", "bCoef" : 1, "cMask" : ["ball" ], "trait" : "ballArea", "y" : -190 },
  2222.  
  2223. { "v0" : 28, "v1" : 29, "vis" : true, "color" : "1e252a", "bCoef" : 0.1, "cMask" : ["red","blue" ], "cGroup" : ["redKO","blueKO" ], "trait" : "kickOffBarrier" },
  2224. { "v0" : 30, "v1" : 31, "vis" : true, "color" : "1e252a", "bCoef" : 0.1, "cMask" : ["red","blue" ], "cGroup" : ["redKO","blueKO" ], "trait" : "kickOffBarrier" },
  2225.  
  2226. { "v0" : 38, "v1" : 39, "curve" : 0, "vis" : false, "color" : "F8F8F8", "bCoef" : 2, "cMask" : ["ball" ], "trait" : "ballArea", "x" : -407.5 },
  2227. { "v0" : 40, "v1" : 41, "curve" : 0, "vis" : false, "color" : "F8F8F8", "bCoef" : 2, "cMask" : ["ball" ], "trait" : "ballArea", "x" : -407.5 },
  2228. { "v0" : 42, "v1" : 43, "curve" : 0, "vis" : false, "color" : "F8F8F8", "bCoef" : 2, "cMask" : ["ball" ], "trait" : "ballArea", "x" : 407.5 },
  2229. { "v0" : 44, "v1" : 45, "curve" : 0, "vis" : false, "color" : "F8F8F8", "bCoef" : 2, "cMask" : ["ball" ], "trait" : "ballArea", "x" : 407.5 },
  2230.  
  2231. { "v0" : 47, "v1" : 48, "curve" : 0, "vis" : true, "color" : "737573", "bCoef" : 0.1, "trait" : "line", "x" : -400 },
  2232. { "v0" : 49, "v1" : 50, "curve" : 0, "vis" : true, "color" : "737573", "bCoef" : 0.1, "trait" : "line", "x" : 400 },
  2233. { "v0" : 51, "v1" : 52, "curve" : -180, "vis" : true, "color" : "737573", "bCoef" : 0.1, "trait" : "line" },
  2234. { "v0" : 53, "v1" : 54, "curve" : 180, "vis" : true, "color" : "737573", "bCoef" : 0.1, "trait" : "line" },
  2235. { "v0" : 55, "v1" : 56, "curve" : 180, "vis" : true, "color" : "737573", "bCoef" : 0.1, "trait" : "line" },
  2236. { "v0" : 57, "v1" : 58, "curve" : -180, "vis" : true, "color" : "737573", "bCoef" : 0.1, "trait" : "line", "x" : 400 },
  2237. { "v0" : 59, "v1" : 60, "curve" : -180, "vis" : true, "color" : "737573", "bCoef" : 0.1, "trait" : "line", "x" : 350 },
  2238. { "v0" : 61, "v1" : 62, "curve" : 180, "vis" : true, "color" : "737573", "bCoef" : 0.1, "trait" : "line", "x" : 350 },
  2239. { "v0" : 63, "v1" : 64, "curve" : -180, "vis" : true, "color" : "737573", "bCoef" : 0.1, "trait" : "line", "x" : -350 },
  2240. { "v0" : 65, "v1" : 66, "curve" : 180, "vis" : true, "color" : "737573", "bCoef" : 0.1, "trait" : "line", "x" : -350 }
  2241.  
  2242. ],
  2243.  
  2244. "goals" : [
  2245. { "p0" : [-406.3,-70 ], "p1" : [-406.3,70 ], "team" : "red" },
  2246. { "p0" : [406.3,70 ], "p1" : [406.3,-70 ], "team" : "blue" }
  2247.  
  2248. ],
  2249.  
  2250. "discs" : [
  2251. { "radius" : 5, "pos" : [-400,70 ], "color" : "ce9e9e", "trait" : "goalPost", "y" : 80 },
  2252. { "radius" : 5, "pos" : [-400,-70 ], "color" : "ce9e9e", "trait" : "goalPost", "y" : -80, "x" : -560 },
  2253. { "radius" : 5, "pos" : [400,70 ], "color" : "9eafce", "trait" : "goalPost", "y" : 80 },
  2254. { "radius" : 5, "pos" : [400,-70 ], "color" : "9eafce", "trait" : "goalPost", "y" : -80 }
  2255.  
  2256. ],
  2257.  
  2258. "planes" : [
  2259. { "normal" : [0,1 ], "dist" : -190, "bCoef" : 1, "trait" : "ballArea", "vis" : false, "curve" : 0 },
  2260. { "normal" : [0,-1 ], "dist" : -190, "bCoef" : 1, "trait" : "ballArea" },
  2261.  
  2262. { "normal" : [0,1 ], "dist" : -220, "bCoef" : 0.1 },
  2263. { "normal" : [0,-1 ], "dist" : -220, "bCoef" : 0.1 },
  2264. { "normal" : [1,0 ], "dist" : -492, "bCoef" : 0.1 },
  2265. { "normal" : [-1,0 ], "dist" : -492, "bCoef" : 0.1 },
  2266.  
  2267. { "normal" : [1,0 ], "dist" : -490, "bCoef" : 0.1, "cMask" : ["ball" ], "trait" : "ballArea", "vis" : false, "curve" : 0 },
  2268. { "normal" : [-1,0 ], "dist" : -490, "bCoef" : 0.1, "cMask" : ["ball" ], "trait" : "ballArea", "vis" : false, "curve" : 0 }
  2269.  
  2270. ],
  2271.  
  2272. "traits" : {
  2273. "ballArea" : { "vis" : false, "bCoef" : 1, "cMask" : ["ball" ] },
  2274. "goalPost" : { "radius" : 8, "invMass" : 0, "bCoef" : 0.5 },
  2275. "goalNet" : { "vis" : true, "bCoef" : 0.1, "cMask" : ["ball" ] },
  2276. "line" : { "vis" : true, "bCoef" : 0.1, "cMask" : ["" ] },
  2277. "kickOffBarrier" : { "vis" : false, "bCoef" : 0.1, "cGroup" : ["redKO","blueKO" ], "cMask" : ["red","blue" ] }
  2278.  
  2279. },
  2280.  
  2281. "playerPhysics" : {
  2282. "bCoef" : 0,
  2283. "acceleration" : 0.11,
  2284. "kickingAcceleration" : 0.083,
  2285. "kickStrength" : 4.2
  2286.  
  2287. },
  2288.  
  2289. "ballPhysics" : {
  2290. "radius" : 5.8,
  2291. "bCoef" : 0.412,
  2292. "invMass" : 1.5,
  2293. "damping" : 0.99,
  2294. "color" : "ffd133"
  2295.  
  2296. }
  2297. }`;
  2298.  
  2299.  
  2300. var maps = {
  2301. "big": bigmap,
  2302. "medium": mediummap,
  2303. "small": smallmap
  2304. };
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement