Room VFB
Room VFB
//          Version: 1.1.5
//          Build Date: 20-April-21
//          Author: Kuma @ hbanz
//          Website: hbanz.org/realsoccer
//          * Real Soccer Revolution (RSR)
//             Official Map for Vietnam Pro Haxball League
//             Discord: https://discord.gg/nkxjFunJV7
//
// =========================================================================
//   =========================================================================
//   Usefull Links
//   ------------------------------------------------
//   https://www.haxball.com/headless
//   https://github.com/haxball/haxball-issues/wiki/Headless-Host
//   https://www.haxball.com/headlesstoken
//   https://www.haxball.com/playerauth
//   =========================================================================
     return realSoccerMap;
}
// ------------------------------------------------
// Global Variables
// ------------------------------------------------
var roomName = "VFootball SS1";
var roomPassword = null;
var maxPlayers = 30;
var roomPublic = false ;
var token = "";
var roomLink = "";
var gameTime = 10; //default game time if 0 is selected
var map = "VFB SS1";
var superAdmins = [];
// -------------------------------------------------
// Classes
// -------------------------------------------------
class Game {
      constructor() {
            this.time = 0;
            this.paused = false;
            this.ballRadius;
            this.rsTouchTeam = 0;
            this.rsActive = true;
            this.rsReady = false;
            this.rsCorner = false;
            this.rsGoalKick = false;
            this.rsSwingTimer = 1000;
            this.rsTimer;
            this.ballOutPositionX;
            this.ballOutPositionY;
            this.throwInPosY;
            this.outStatus = "";
            this.warningCount = 0;
            this.bringThrowBack = false;
            this.extraTime = false;
            this.extraTimeCount = 0;
            this.extraTimeEnd;
            this.extraTimeAnnounced = false;
            this.lastPlayAnnounced = false;
            this.boosterState;
            this.throwinKicked = false;
            this.pushedOut;
            this.lastKickerId;
            this.lastKickerName;
            this.lastKickerTeam;
            this.secondLastKickerId;
            this.secondLastKickerName;
            this.secondLastKickerTeam;
            this.redScore = 0;
            this.blueScore = 0;
      }
           this.lastKickerId = id;
           this.lastKickerName = name;
           this.lastKickerTeam = team;
     }
}
room.setCustomStadium(getRealSoccerMap());
room.setScoreLimit(0);
room.setTimeLimit(10);
room.onRoomLink = function(url) {
      roomLink = url;
      console.log(roomLink);
}
room.onPlayerJoin = function(player) {
      console.log(player.name + " joined the room");
      whisper("⚽      Wᴇʟᴄᴏᴍᴇ ᴛᴏ VFB League ( SS1 )     ⚽", player.id, 0x61ddff,
"bold", 0);
      whisper("⚽      Type !help for available commands      ⚽", player.id,
0x61e7ff, "bold", 0);
     displayAdminMessage();
}
room.onPlayerLeave = function(player) {
      displayAdminMessage();
      console.log(player.name + " left the room");
room.onGameStart = function(byPlayer) {
      if (map == "RSR") {
            if (byPlayer == null) {
                  game = new Game();
                  announce("Game length set to " + gameTime + " minutes");
            }
            else {
                  if (room.getScores().timeLimit != 0) {
                        gameTime = room.getScores().timeLimit / 60;
                  }
                  else {
                        gameTime = 10;
                  }
                  room.stopGame();
                  room.setTimeLimit(0);
                  room.startGame();
            }
      }
}
room.onGameStop = function(byPlayer) {
      if (map == "RSR") {
            if (byPlayer != null) {
                  room.setTimeLimit(gameTime);
            }
      }
}
room.onPlayerBallKick = function(player) {
      if (map == "RSR") {
            game.rsTouchTeam = player.team;
            game.updateLastKicker(player.id, player.name, player.team);
           if (game.rsReady == true) {
                 var players = room.getPlayerList().filter((player) => player.team
!= 0);
                  players.forEach(function(player) {
                        if
(room.getPlayerDiscProperties(player.id).invMass.toFixed(1) != 0.3) {
                              room.setPlayerDiscProperties(player.id, {invMass:
0.3});
                        }
                  });
            }
                 game.rsActive = true;
                 game.rsReady = false;
                 room.setDiscProperties(1, {x: 2000, y: 2000 });
                 room.setDiscProperties(2, {x: 2000, y: 2000 });
                 room.setDiscProperties(0, {color: "0xffffff"});
                 game.rsTimer = 1000000;
                 game.warningCount++;
                 game.rsCorner = false;
                 game.rsGoalKick = false;
                 game.outStatus = "";
           }
                  }
                  else {
                        whisper("Cannot change map background color while game in
progress", player.id);
                  }
            }
            else if (args[0] == "swap") {
                  if (player.admin) {
                        if (args.length == 1) {
                              var players = room.getPlayerList().filter((player) =>
player.id != 0 );
                              if ( players.length == 0 ) return false;
                              players.forEach(function(player) {
                                    if (player.team == 1) {
                                          room.setPlayerTeam(player.id, 2);
                                    }
                                    if (player.team == 2) {
                                          room.setPlayerTeam(player.id, 1);
                                    }
                              });
                              announce("🔄 Teams have been swapped");
                        }
                  }
                   else {
                         whisper("Admin only command", player.id);
                   }
              }
              else if (args[0] == "setpassword" && player.admin) {
                    if (superAdmins.indexOf(player.id) > -1) {
                          room.setPassword(args[1]);
                          roomPassword = args[1];
                          announce("Password has been changed by " + player.name);
                    }
                    else {
                          whisper("Only Super Admins can change password",
player.id);
                    }
              }
              else if (args[0] == "clearpassword" && player.admin) {
                    if (superAdmins.indexOf(player.id) > -1) {
                          room.setPassword(null);
                          roomPassword = null;
                          announce("Password has been cleared by " + player.name);
                    }
                    else {
                          whisper("Only Super Admins can clear password", player.id);
                    }
              }
              else if (args[0] == "rs" && player.admin) {
                    if (room.getScores() == null) {
                          room.setCustomStadium(getRealSoccerMap());
                    }
                    else {
                          whisper("Cannot change map while game in progress",
player.id);
                  }
            }
            else if (args[0] == "rr" && player.admin) {
                  room.stopGame();
                  room.startGame();
            }
            else if (args[0] == "bb") {
                  room.kickPlayer(player.id, "Bye", false);
            }
            else if (args[0] == "help") {
                  displayHelp(player.id, args[1]);
            }
            else if (args[0] == "super") {
                  let superMsg = "Super Admins: ";
                  superAdmins.forEach(function(id) {
                        if (room.getPlayer(id) != null || room.getPlayer(id) !=
undefined) {
                              superMsg = superMsg + room.getPlayer(id).name + ", ";
                        }
                  });
                  if (superAdmins.length > 0) {
                        superMsg = superMsg.slice(0, -2);
                  }
                  else {
                        superMsg = "There are no super admins present";
                  }
                  whisper(superMsg, player.id);
           }
           return false;
      }
      if (message.startsWith("t ")) {
            teamMsg = message.substring(1).trim();
            if (player.team == 1) {
                  var players = room.getPlayerList().filter((player) =>   player.team
== 1);
                  players.forEach(function(teamPlayer) {
                        room.sendAnnouncement("[Team] " + player.name +   ": " +
teamMsg, teamPlayer.id, 0xED6A5A, "normal", 1);
                  });
            }
            if (player.team == 2) {
                  var players = room.getPlayerList().filter((player) =>   player.team
== 2);
                  players.forEach(function(teamPlayer) {
                        room.sendAnnouncement("[Team] " + player.name +   ": " +
teamMsg, teamPlayer.id, 0x5995ED, "normal", 1);
                  });
            }
            if (player.team == 0) {
                  var players = room.getPlayerList().filter((player) =>   player.team
== 0);
                  players.forEach(function(teamPlayer) {
                        room.sendAnnouncement("[Spec] " + player.name +   ": " +
teamMsg, teamPlayer.id, 0xdee7fa, "normal", 1);
                  });
            }
            return false;
      }
      if (message.startsWith("@@")) {
            message = message.substr(2).trim();
            if (message.indexOf(' ') !== -1) {
                  let args = message.match(/^(\S+)\s(.*)/).slice(1);
                  if (args.length > 1) {
                        var pmMsg = args[1];
                        var players = room.getPlayerList();
                        var pmSent = false;
                        players.forEach(function(pmPlayer) {
                              if (pmPlayer.name === args[0] || pmPlayer.name ===
args[0].replace(/_/g, ' ')) {
                                    whisper("[PM > " + pmPlayer.name + "] " +
player.name + ": " + pmMsg, player.id, 0xff20ff, "normal", 1);
                                    whisper("[PM] " + player.name + ": " + pmMsg,
pmPlayer.id, 0xff20ff, "normal", 1);
                                    pmSent = true;
                              }
                        });
                        if (pmSent == false) {
                              whisper("Cannot find user '" + args[0] + "'",
player.id, 0xff20ff, "normal", 1);
                        }
                        return false;
                  }
            }
      }
}
function displayHelp(id, selection) {
      if (selection == null) {
            whisper("Commands: !rs, !rr, !bb, !admin, !setpassword, !clearpassword,
!super, !clearbans, !swap, @@[player] [pm msg] , t [team chat msg], !court, !court
[hexcolor], !court reset", id, null, "small");
      }
}
room.onTeamGoal = function(team) {
      if (map == "RSR") {
            game.rsActive = false;
room.onPositionsReset = function() {
      if (map == "RSR") {
            if (game.lastPlayAnnounced == true) {
                  room.pauseGame(true);
                  game.lastPlayAnnounced = false;
                  announce("END");
            }
      }
}
room.onGameTick = function() {
      if (map == "RSR") {
            updateGameStatus();
            handleBallTouch();
            realSoccerRef();
      }
}
function realSoccerRef() {
      blockThrowIn();
      blockGoalKick();
      removeBlock();
      if (game.time == gameTime * 60 && game.extraTimeAnnounced == false) {
            extraTime();
           game.extraTimeAnnounced = true;
     }
      if (game.rsTimer < 99999 && game.paused == false && game.rsActive == false &&
game.rsReady == true) {
            game.rsTimer++;
      }
     if (game.boosterState == true) {
           game.boosterCount++;
     }
      if (game.rsActive == true) {
            if ((room.getBallPosition().y > 611.45 || room.getBallPosition().y < -
611.45)) {
                  game.rsActive = false;
                  if (game.lastPlayAnnounced == true) {
                        room.pauseGame(true);
                       game.lastPlayAnnounced = false;
                       announce("END");
                 }
                  if (game.rsTouchTeam == 1) {
                        room.setDiscProperties(3, {x: game.ballOutPositionX, y:
game.throwInPosY, radius: 18 });
                        sleep(100).then(() => {
                              game.outStatus = "blueThrow";
                              game.throwinKicked = false;
                              game.rsTimer = 0;
                              game.rsReady = true;
                              room.setDiscProperties(0, {xspeed: 0, yspeed: 0, x:
game.ballOutPositionX, y: game.throwInPosY, xgravity: 0, ygravity: 0});
                              //announce(" Throw In: 🔵 Blue");
                              room.setDiscProperties(0, {color: "0x0fbcf9"});
                       });
                       sleep(100).then(() => {
                             room.setDiscProperties(3, {x: 0, y: 2000, radius:
0});
                        });
                  }
                  else {
                        room.setDiscProperties(3, {x: game.ballOutPositionX, y:
game.throwInPosY, radius: 18 });
                        sleep(100).then(() => {
                              game.outStatus = "redThrow";
                              game.throwinKicked = false;
                              game.rsTimer = 0;
                              game.rsReady = true;
                              room.setDiscProperties(0, {xspeed: 0, yspeed: 0, x:
game.ballOutPositionX, y: game.throwInPosY, xgravity: 0, ygravity: 0});
                              //announce(" Throw In: 🔴 Red");
                              room.setDiscProperties(0, {color: "0xff3f34"});
                       });
                       sleep(100).then(() => {
                             room.setDiscProperties(3, {x: 0, y: 2000, radius:
0});
                       });
                 }
           }
                  if (game.rsTouchTeam == 1) {
                        room.setDiscProperties(3, {x: 1060, y: 0, radius: 18 });
                        sleep(100).then(() => {
                              game.outStatus = "blueGK";
                              game.rsTimer = 0;
                              game.rsReady = true;
                              //announce("🥅 Goal Kick: 🔵 Blue");
                              game.rsGoalKick = true;
                              game.rsSwingTimer = 0;
                              game.boosterCount = 0;
                              game.boosterState = false;
                              room.setDiscProperties(0, {xspeed: 0, yspeed: 0, x:
1060, y: 0, color: "0x0fbcf9", cMask: 268435519, xgravity: 0, ygravity: 0});
                        });
                        sleep(3000).then(() => {
                              room.setDiscProperties(3, {x: 0, y: 2000, radius:
0});
                        });
                  }
                  else {
                        //announce("🚩 Corner Kick: 🔴 Red");
                       game.rsSwingTimer = 0;
                       if (room.getBallPosition().y < -124) {
                 if (game.rsTouchTeam == 1) {
                       //announce("🚩 Corner Kick: 🔵 Blue");
                       game.rsSwingTimer = 0;
                       if (room.getBallPosition().y < -124) {
                             room.setDiscProperties(3, {x: -1140, y: -590, radius:
18 });
                              sleep(100).then(() => {
                                    game.rsCorner = true;
                                    game.outStatus = "blueCK";
                                    game.rsTimer = 0;
                                    game.rsReady = true;
                                    game.boosterCount = 0;
                                    game.boosterState = false;
                                    room.setDiscProperties(0, {x: -1140, y: -590,
xspeed: 0, yspeed: 0, color: "0x0fbcf9", cMask: 268435519, xgravity: 0, ygravity:
0});
                                    room.setDiscProperties(1, {x: -1150, y: -670,
radius: 420 });
                                    room.setDiscProperties(3, {x: 0, y: 2000,
radius: 0});
                              });
                        }
                        if (room.getBallPosition().y > 124) {
                             room.setDiscProperties(3, {x: -1140, y: 590, radius:
18 });
                              sleep(100).then(() => {
                                    game.rsCorner = true;
                                    game.outStatus = "blueCK";
                                    game.rsTimer = 0;
                                    game.rsReady = true;
                                    game.boosterCount = 0;
                                    game.boosterState = false;
                                    room.setDiscProperties(0, {x: -1140, y: 590,
xspeed: 0, yspeed: 0, color: "0x0fbcf9", cMask: 268435519, xgravity: 0, ygravity:
0});
                                    room.setDiscProperties(1, {x: -1150, y: 670,
radius: 420 });
                                    room.setDiscProperties(3, {x: 0, y: 2000,
radius: 0});
                              });
                        }
                  }
                  else {
                        room.setDiscProperties(3, {x: -1060, y: 0, radius: 18 });
                        sleep(100).then(() => {
                              game.outStatus = "redGK";
                              game.rsTimer = 0;
                              game.rsReady = true;
                              //announce("🥅 Goal Kick: 🔴 Red");
                              game.rsGoalKick = true;
                              game.rsSwingTimer = 0;
                              game.boosterCount = 0;
                              game.boosterState = false;
                              room.setDiscProperties(0, {xspeed: 0, yspeed: 0, x: -
1060, y: 0, color: "0xff3f34", cMask: 268435519, xgravity: 0, ygravity: 0});
                        });
                        sleep(3000).then(() => {
                              room.setDiscProperties(3, {x: 0, y: 2000, radius:
0});
                        });
                  }
            }
      }
            if (room.getBallPosition().y.toFixed(1) == game.throwInPosY.toFixed(1)
&& room.getBallPosition().x.toFixed(1) == game.ballOutPositionX.toFixed(1)) {
                  game.bringThrowBack     = false;
                  game.pushedOut = false;
            }
      }
}
function handleBallTouch() {
      var players = room.getPlayerList();
      var ballPosition = room.getBallPosition();
      var ballRadius = game.ballRadius;
      var playerRadius = 15;
      var triggerDistance = ballRadius + playerRadius + 0.01;
     for (var i = 0; i < players.length; i++) { // Iterate over all the players
           var player = players[i];
           if ( player.position == null ) continue;
           var distanceToBall = pointDistance(player.position, ballPosition);
           if ( distanceToBall < triggerDistance ) {
                 game.rsTouchTeam = player.team;
                 game.throwinKicked = false;
           });
     if (dis_loop == false) {
           dis_loop = true
           sleep(30000).then(() => {
                 announce("Discord: https://discord.gg/jXeZw6a5We",null,0x333DAA)
                 dis_loop = false
           });
     }
     }
}
function isAdminPresent() {
      var players = room.getPlayerList();
      if (players.find((player) => player.admin) != null) {
            return true;
      }
      else {
            return false;
      }
}
function displayAdminMessage() {
      if (isAdminPresent() == false && allowPublicAdmin == true) {
            announce("No admin present: Type !admin to take control");
      }
}
function extraTime() {
      var extraSeconds = Math.ceil(game.extraTimeCount / 60);
      game.extraTimeEnd = (gameTime * 60) + extraSeconds;
      announce("Extra time: " + extraSeconds + " Seconds", null, null, null, 1);
}
function secondsToMinutes(time) {
      // Hours, minutes and seconds
    var hrs = ~~(time / 3600);
    var mins = ~~((time % 3600) / 60);
    var secs = ~~time % 60;
function blockThrowIn() {
      var players = room.getPlayerList().filter((player) => player.team != 0);
      if (room.getBallPosition().y < 0) { // top throw line
            if (game.outStatus == "redThrow") {
                  players.forEach(function(player) {
                        if (player.team == 2 &&
room.getPlayerDiscProperties(player.id).y < 0) {
                              if (room.getPlayerDiscProperties(player.id).cGroup !=
536870918) {
                                    room.setPlayerDiscProperties(player.id,
{cGroup: 536870918});
                             }
                             if (player.position.y < -485) {
                                   room.setPlayerDiscProperties(player.id, {y: -
470});
                              }
                        }
                        if (player.team == 1 &&
room.getPlayerDiscProperties(player.id).cGroup != 2) {
                              room.setPlayerDiscProperties(player.id, {cGroup: 2});
                        }
                        if (room.getDiscProperties(17).x != 1149) { // show top red
line
                              room.setDiscProperties(17, {x: 1149});
                        }
                        if (room.getDiscProperties(19).x != -1149) { // hide top
blue line
                              room.setDiscProperties(19, {x: -1149});
                        }
                  });
            }
            if (game.outStatus == "blueThrow") {
                  players.forEach(function(player) {
                        if (player.team == 1 &&
room.getPlayerDiscProperties(player.id).y < 0) {
                              if (room.getPlayerDiscProperties(player.id).cGroup !=
536870918) {
                                    room.setPlayerDiscProperties(player.id,
{cGroup: 536870918});
                              }
                              if (player.position.y < -485) {
                                    room.setPlayerDiscProperties(player.id, {y: -
470});
                              }
                        }
                        if (player.team == 2 &&
room.getPlayerDiscProperties(player.id).cGroup != 2) {
                              room.setPlayerDiscProperties(player.id, {cGroup: 2});
                        }
                        if (room.getDiscProperties(19).x != 1149) { // show top
blue line
                              room.setDiscProperties(19, {x: 1149});
                        }
                        if (room.getDiscProperties(17).x != -1149) { // hide top
red line
                              room.setDiscProperties(17, {x: -1149});
                        }
                  });
            }
      }
      if (room.getBallPosition().y > 0) { // bottom throw line
            if (game.outStatus == "redThrow") {
                  players.forEach(function(player) {
                        if (player.team == 2 &&
room.getPlayerDiscProperties(player.id).y > 0) {
                              if (room.getPlayerDiscProperties(player.id).cGroup !=
536870918) {
                                    room.setPlayerDiscProperties(player.id,
{cGroup: 536870918});
                              }
                             if (player.position.y > 485) {
                                   room.setPlayerDiscProperties(player.id, {y:
470});
                              }
                        }
                        if (player.team == 1 &&
room.getPlayerDiscProperties(player.id).cGroup != 2) {
                              room.setPlayerDiscProperties(player.id, {cGroup: 2});
                        }
                        if (room.getDiscProperties(21).x != 1149) { // show bottom
red line
                              room.setDiscProperties(21, {x: 1149});
                        }
                        if (room.getDiscProperties(23).x != -1149) { // hide bottom
blue line
                              room.setDiscProperties(23, {x: -1149});
                        }
                  });
            }
            if (game.outStatus == "blueThrow") {
                  players.forEach(function(player) {
                        if (player.team == 1 &&
room.getPlayerDiscProperties(player.id).y > 0) {
                              if (room.getPlayerDiscProperties(player.id).cGroup !=
536870918) {
                                    room.setPlayerDiscProperties(player.id,
{cGroup: 536870918});
                              }
                              if (player.position.y > 485) {
                                    room.setPlayerDiscProperties(player.id, {y:
470});
                              }
                        }
                        if (player.team == 2 &&
room.getPlayerDiscProperties(player.id).cGroup != 2) {
                              room.setPlayerDiscProperties(player.id, {cGroup: 2});
                        }
                        if (room.getDiscProperties(23).x != 1149) { // show bottom
blue line
                              room.setDiscProperties(23, {x: 1149});
                        }
                        if (room.getDiscProperties(21).x != -1149) { // hide bottom
red line
                              room.setDiscProperties(21, {x: -1149});
                        }
                  });
            }
      }
}
function blockGoalKick() {
      var players = room.getPlayerList().filter((player) => player.team != 0);
      if (room.getBallPosition().x < 0) { // left side red goal kick
            if (game.outStatus == "redGK") {
                  players.forEach(function(player) {
                        if (player.team == 2 &&
room.getPlayerDiscProperties(player.id).x < 0) {
                              if (room.getPlayerDiscProperties(player.id).cGroup !=
268435462) {
                                   room.setPlayerDiscProperties(player.id,
{cGroup: 268435462});
                              }
                              if (player.position.x < -840 && player.position.y > -
320 && player.position.y < 320) {
                                    room.setPlayerDiscProperties(player.id, {x: -
1125});
                              }
                        }
                        if (player.team == 1 &&
room.getPlayerDiscProperties(player.id).cGroup != 2) {
                              room.setPlayerDiscProperties(player.id, {cGroup: 2});
                        }
                  });
            }
      }
      if (room.getBallPosition().x > 0) { // right side blue goal kick
            if (game.outStatus == "blueGK") {
                  players.forEach(function(player) {
                        if (player.team == 1 &&
room.getPlayerDiscProperties(player.id).x > 0) {
                              if (room.getPlayerDiscProperties(player.id).cGroup !=
268435462) {
                                    room.setPlayerDiscProperties(player.id,
{cGroup: 268435462});
                              }
                              if (player.position.x > 840 && player.position.y > -
320 && player.position.y < 320) {
                                    room.setPlayerDiscProperties(player.id, {x:
1125});
                              }
                        }
                        if (player.team == 2 &&
room.getPlayerDiscProperties(player.id).cGroup != 2) {
                              room.setPlayerDiscProperties(player.id, {cGroup: 2});
                        }
                  });
            }
      }
}
function removeBlock() {
      var players = room.getPlayerList().filter((player) => player.team != 0);
      if (game.outStatus == "") {
            players.forEach(function(player) {
                  if (player.team == 1 &&
room.getPlayerDiscProperties(player.id).cGroup != 2) {
                        room.setPlayerDiscProperties(player.id, {cGroup: 2});
                  }
                  if (player.team == 2 &&
room.getPlayerDiscProperties(player.id).cGroup != 4) {
                        room.setPlayerDiscProperties(player.id, {cGroup: 4});
                  }
            });
            if (room.getDiscProperties(17).x != -1149) { // hide top red line
                  room.setDiscProperties(17, {x: -1149});
        }
        if (room.getDiscProperties(19).x   != -1149) { // hide top blue line
              room.setDiscProperties(19,   {x: -1149});
        }
        if (room.getDiscProperties(21).x   != -1149) { // hide bottom red line
              room.setDiscProperties(21,   {x: -1149});
        }
        if (room.getDiscProperties(23).x   != -1149) { // hide bottom blue line
              room.setDiscProperties(23,   {x: -1149});
        }
    }
}