├── Advanced ├── Admin.js ├── AvatarOverride.js ├── CollisionDetection.js ├── CommandAbuseDetection.js ├── MVP.js ├── Mute.js ├── RadiusSetting_CommandUsage.js └── VoteBan.js ├── Beginner ├── AdminSlot.js ├── BallZoneCheckAndTeleport.js ├── Basketball.js ├── Blacklist.js ├── Clearban.js ├── Collision.js ├── CommandBan.js ├── DuplicatedConnections.js ├── JoiningHistory.js ├── KickGame.js ├── MarkedZone.js ├── MovePlayers.js ├── Nearest_Player.js ├── PlayerAvatarControl.js ├── PlayerRadiusAvatarSetting.js ├── Powershot.js ├── RadiusSetting.js ├── RankSystem.js ├── Ranks.js ├── RockPaperScissors_v1.js ├── RockPaperScissors_v2.js ├── RockPaperScissors_v3.js ├── SlowMode.js ├── Spam_Mute.js ├── VIP_Roles.js ├── Webhooks.js ├── XPSystem_v1.js ├── XPSystem_v2.js └── ZoneCheck.js ├── Intermediate ├── 3DefLines.js ├── Badwords.js ├── CollisionDetection_Counter.js ├── Counter.js ├── FinishLine.js ├── GiveUp.js ├── Goal_AfterEffects.js ├── Ignore.js ├── Login.js ├── MapVote.js ├── PlayerFreeze.js ├── Player_Teleport_After_KickOff.js ├── Register-Login.js ├── ReorderPlayers.js ├── TacticalTimeout.js ├── TeamChat.js └── Uniforms.js ├── LICENSE └── README.md /Advanced/AvatarOverride.js: -------------------------------------------------------------------------------- 1 | var LineUp = ``; //Lineup map scripts here 2 | 3 | var JLineUp = JSON.parse(LineUp); 4 | var _LineUp = {ID: 1, Name: JLineUp.name}; 5 | 6 | var RS = ``; //Real soccer v6 map scripts here 7 | 8 | var JRS = JSON.parse(RS); 9 | var _RS = {ID: 2, Name: JRS.name}; 10 | 11 | var Maps = [LineUp,RS]; 12 | var _Maps = [_LineUp,_RS]; 13 | 14 | var _Map = {ID: 0}; 15 | 16 | var red_1_pos = {"x": -405, "y": 0, avatar: "1", avatarSet: false, position: "GK", playerid: 0, toSet: {x: -1200, y: 0}}; //Do not forget to change these x's and y's according to your map. They were gathered from my own lineup map. 17 | var red_3_pos = {"x": -333, "y": -90, avatar: "3", avatarSet: false, position: "DF", playerid: 0, toSet: {x: -1000, y: 0}}; 18 | var red_6_pos = {"x": -261, "y": 90, avatar: "6", avatarSet: false, position: "DMF", playerid: 0, toSet: {x: -800, y: 0}}; 19 | var red_8_pos = {"x": -189, "y": -45, avatar: "8", avatarSet: false, position: "MF", playerid: 0, toSet: {x: -600, y: 0}}; 20 | var red_9_pos = {"x": -45, "y": 0, avatar: "9", avatarSet: false, position: "FW", playerid: 0, toSet: {x: -200, y: 0}}; 21 | var red_10_pos = {"x": -117, "y": 45, avatar: "10", avatarSet: false, position: "OMF", playerid: 0, toSet: {x: -400, y: 0}}; 22 | 23 | var blue_1_pos = {"x": 405, "y": 0, avatar: "1", avatarSet: false, position: "GK", playerid: 0, toSet: {x: 1200, y: 0}}; 24 | var blue_3_pos = {"x": 333, "y": -90, avatar: "3", avatarSet: false, position: "DF", playerid: 0, toSet: {x: 1000, y: 0}}; 25 | var blue_6_pos = {"x": 261, "y": 90, avatar: "6", avatarSet: false, position: "DMF", playerid: 0, toSet: {x: 800, y: 0}}; 26 | var blue_8_pos = {"x": 189, "y": -45, avatar: "8", avatarSet: false, position: "MF", playerid: 0, toSet: {x: 600, y: 0}}; 27 | var blue_9_pos = {"x": 45, "y": 0, avatar: "9", avatarSet: false, position: "FW", playerid: 0, toSet: {x: 200, y: 0}}; 28 | var blue_10_pos = {"x": 117, "y": 45, avatar: "10", avatarSet: false, position: "OMF", playerid: 0, toSet: {x: 400, y: 0}}; 29 | 30 | var redPositions = [red_1_pos, red_3_pos, red_6_pos, red_8_pos, red_9_pos, red_10_pos]; 31 | var bluePositions = [blue_1_pos, blue_3_pos, blue_6_pos, blue_8_pos, blue_9_pos, blue_10_pos]; 32 | var teamPositions = [redPositions,bluePositions]; 33 | 34 | var teams = ["spectators","red","blue"]; 35 | 36 | var playerList = {}; 37 | 38 | var colors = {mapChangeWrongName: 0xFFFF00, mapChangeDeny: 0xFF0000, playerLeft: 0xFFFF00, positionSet: 0xFFFFFF}; 39 | var fonts = {mapChangeWrongName: "normal", mapChangeDeny: "bold", playerLeft: "normal", positionSet: "normal"}; 40 | var sounds = {mapChangeWrongName: 1, mapChangeDeny: 2, playerLeft: 1, positionSet: 1}; 41 | 42 | var gameStartTimeout = 2000; 43 | 44 | var room = HBInit({roomName:"AVATAR OVERRIDE TEST",noPlayer:true,public:false,maxPlayers:12}); 45 | 46 | function checkPlayerSits(){ 47 | var players = room.getPlayerList().filter(p => room.getPlayerDiscProperties(p.id) != null); 48 | var fullRedPos = redPositions.filter(r => r.avatarSet == true && r.playerid != 0); 49 | var fullBluePos = bluePositions.filter(b => b.avatarSet == true && b.playerid != 0); 50 | 51 | if(_Map.ID == 1){ 52 | players.forEach(p => { 53 | var index = teamPositions[p.team-1].findIndex(t => pointDistance({x: t.x, y: t.y},room.getPlayerDiscProperties(p.id)) == 0 && t.avatarSet == false && t.playerid == 0); 54 | if(index !== -1){ 55 | teamPositions[p.team-1][index].avatarSet = true; 56 | teamPositions[p.team-1][index].playerid = p.id; 57 | room.setPlayerAvatar(p.id,teamPositions[p.team-1][index].avatar); 58 | playerList[p.name].avatar = teamPositions[p.team-1][index].avatar; 59 | playerList[p.name].toSet.x = teamPositions[p.team-1][index].toSet.x; 60 | playerList[p.name].toSet.y = teamPositions[p.team-1][index].toSet.y; 61 | room.sendAnnouncement(`Your position set as ${teamPositions[p.team-1][index].position} please wait for the others to sit.`,p.id,colors.positionSet,fonts.positionSet,sounds.positionSet); 62 | } 63 | }); 64 | if(fullRedPos != undefined && fullBluePos != undefined && fullRedPos.length == redPositions.length && fullBluePos.length == bluePositions.length){ 65 | room.stopGame(); 66 | var name = p.name; 67 | var id = p.id; 68 | setTimeout(function(){ 69 | room.setCustomStadium(RS); 70 | room.startGame(); 71 | room.setPlayerDiscProperties(id,{x: playerList[name].toSet.x, y: playerList[name].toSet.y}); 72 | },gameStartTimeout); 73 | } 74 | } 75 | } 76 | 77 | function pointDistance(p1,p2){ 78 | return Math.hypot(p1.x-p2.x,p1.y-p2.y); 79 | } 80 | 81 | function resetPlayerAvatars(){ 82 | room.getPlayerList().forEach(p => { 83 | room.setPlayerAvatar(p.id); 84 | playerList[p.name].avatar = 0; 85 | }); 86 | } 87 | 88 | function resetPlayerSetPositions(){ 89 | room.getPlayerList().forEach(p => { 90 | room.setPlayerAvatar(p.id); 91 | playerList[p.name].toSet.x = 0; 92 | playerList[p.name].toSet.y = 0; 93 | }); 94 | } 95 | 96 | function resetPositions(){ 97 | for(var t in teamPositions){ 98 | teamPositions[t].forEach(p => { 99 | p.avatarSet = false; 100 | p.playerid = 0; 101 | p.toSet.x = 0; 102 | p.toSet.y = 0; 103 | }); 104 | } 105 | } 106 | 107 | room.onGameStart = function(byPlayer){ 108 | byPlayer == null ? console.log(`Game started`) : console.log(`Game started by ${byPlayer.name}`); 109 | 110 | if(_Map.ID == 1){ 111 | resetPlayerAvatars(); 112 | resetPlayerSetPositions(); 113 | resetPositions(); 114 | } 115 | } 116 | 117 | room.onGameStop = function(byPlayer){ 118 | byPlayer == null ? console.log(`Game stopped`) : console.log(`Game stopped by ${byPlayer.name}`); 119 | } 120 | 121 | room.onGameTick = function(){ 122 | checkPlayerSits(); 123 | } 124 | 125 | room.onPlayerJoin = function(player){ 126 | console.log(`${player.name} has joined`); 127 | 128 | if(playerList[player.name] == undefined) 129 | playerList[player.name] = {name: player.name, id: player.id, avatar: 0, toSet: {x:0,y:0}}; 130 | } 131 | 132 | room.onPlayerLeave = function(player){ 133 | console.log(`${player.name} has left`); 134 | 135 | room.sendAnnouncement(`${player.name} from ${teams[player.team]} with number ${playerList[player.name].avatar} has left the room`,null,colors.playerLeft,fonts.playerLeft,sounds.playerLeft); 136 | 137 | var index = teamPositions[player.team-1].findIndex(t => t.playerid == player.id); 138 | if(index !== -1){ 139 | teamPositions[player.team-1][index].playerid = 0; 140 | } 141 | } 142 | 143 | room.onPositionsReset = function(){ 144 | console.log("Positions reset"); 145 | } 146 | 147 | room.onStadiumChange = function(newStadiumName,byPlayer){ 148 | byPlayer == null ? console.log(`${newStadiumName} was loaded`) : console.log(`${newStadiumName} was loaded by ${byPlayer.name}`); 149 | 150 | var m = _Maps.find(x => x.Name == newStadiumName); 151 | var players = room.getPlayerList(); 152 | var admins = room.getPlayerList().filter(p => p.admin == true); 153 | 154 | if(byPlayer == null){ 155 | if(m){ 156 | _Map = {ID: m.ID, Name: m.Name}; 157 | } 158 | else{ 159 | admins.length > 0 ? admins.forEach(p => room.sendAnnouncement(`Something went wrong with map ${newStadiumName}. Please try again!`,p.id,colors.mapChangeWrongName,fonts.mapChangeWrongName,sounds.mapChangeWrongName)) : room.sendAnnouncement(`Something went wrong with map ${newStadiumName}. Please call an admin to try again!`,null,colors.mapChangeWrongName,fonts.mapChangeWrongName,sounds.mapChangeWrongName); 160 | } 161 | } 162 | else{ 163 | room.sendAnnouncement("You don't have authorization to change maps in this room!",byPlayer.id,colors.mapChangeDeny,fonts.mapChangeDeny,sounds.mapChangeDeny); 164 | room.setCustomStadium(Maps[0]); 165 | } 166 | } 167 | -------------------------------------------------------------------------------- /Advanced/CollisionDetection.js: -------------------------------------------------------------------------------- 1 | var Map = `` //Insert your map content in JSON parsed format 2 | 3 | var JMap = JSON.parse(Map); 4 | 5 | var room = HBInit({roomName:"Collision Detection",noPlayer:true,public:true,maxPlayers:10}); 6 | 7 | function collisionDetectionSegmentPlayer() { //This function must be handled in room.onGameTick() to get the true result. 8 | var players = room.getPlayerList(); 9 | for (var i = 0; i < players.length; i++) { 10 | for (var j = 0; j < JMap.segments.length; j++) { 11 | if (players[i].team == 1) { 12 | var distancetov0 = pointDistance(room.getPlayerDiscProperties(players[i].id), JMap.vertexes[JMap.segments[j].v0]); 13 | var distancetov1 = pointDistance(room.getPlayerDiscProperties(players[i].id), JMap.vertexes[JMap.segments[j].v1]); 14 | var length = pointDistance(JMap.vertexes[JMap.segments[j].v0], JMap.vertexes[JMap.segments[j].v1]); 15 | var dot = (((players[i].position.x - JMap.vertexes[JMap.segments[j].v0].x) * (JMap.vertexes[JMap.segments[j].v1].x - JMap.vertexes[JMap.segments[j].v0].x)) + ((players[i].position.y - JMap.vertexes[JMap.segments[j].v0].y) * (JMap.vertexes[JMap.segments[j].v1].y - JMap.vertexes[JMap.segments[j].v0].y))) / Math.pow(length, 2); 16 | var closestX = JMap.vertexes[JMap.segments[j].v0].x + (dot * (JMap.vertexes[JMap.segments[j].v1].x - JMap.vertexes[JMap.segments[j].v0].x)); 17 | var closestY = JMap.vertexes[JMap.segments[j].v0].y + (dot * (JMap.vertexes[JMap.segments[j].v1].y - JMap.vertexes[JMap.segments[j].v0].y)); 18 | var closestPoint = { x: closestX, y: closestY }; 19 | console.log("distancetov0: " + distancetov0 + "\ndistancetov1: " + distancetov1 + "\nlength: " + length + "\ndot: " + dot + "\nclosestPoint: {" + closestPoint.x + "," + closestPoint.y + "}"); //Before handling this function in room.onGameTick(), toggle this row in command line. 20 | 21 | if (pointDistance(closestPoint, JMap.vertexes[JMap.segments[j].v0]) + pointDistance(closestPoint, JMap.vertexes[JMap.segments[j].v1]) == length) { 22 | distX = closestX - players[i].position.x; 23 | distY = closestY - players[i].position.y; 24 | var distancetosegment = Math.sqrt(Math.pow(distX, 2) + Math.pow(distY, 2)); 25 | 26 | if (0 <= Math.hypot(room.getPlayerDiscProperties(players[i].id).xspeed, room.getPlayerDiscProperties(players[i].id).yspeed)) { 27 | if (JMap.segments[j].cMask != undefined && JMap.segments[j].cMask.includes("red") == true && JMap.segments[j].bCoef != undefined && JMap.segments[j].curve == undefined || (JMap.segments[j].curve != undefined && JMap.segments[j].curve == 0)) { //Red team collision condition for parkour maps 28 | if (distancetosegment <= room.getPlayerDiscProperties(players[i].id).radius + 0.01) { //0.01 is the tolerance 29 | if (room.getPlayerDiscProperties(players[i].id) != null) { 30 | console.log(new Date().getHours() + ":" + new Date().getMinutes() + ":" + new Date().getSeconds() + "." + new Date().getMilliseconds() + " 💥 " + players[i].name + " has collided with the point {" + closestX + "," + closestY + "} located on a wall on the point {" + room.getPlayerDiscProperties(players[i].id).x + "," + room.getPlayerDiscProperties(players[i].id).y + "}."); 31 | } 32 | } 33 | } 34 | } 35 | } 36 | } 37 | } 38 | } 39 | } 40 | 41 | room.onGameTick = function () { 42 | collisionDetectionSegmentPlayer(); 43 | } 44 | 45 | //WILL BE UPDATED SOON... 46 | -------------------------------------------------------------------------------- /Advanced/CommandAbuseDetection.js: -------------------------------------------------------------------------------- 1 | var commands = [["!admin",1000],["!afk",5000]]; //Same structure goes for the other commands 2 | var playerList = {}; 3 | var chatFunctions = [setAdmin,setAFK]; //A function must correspond a command 4 | var afkLimit = 1; 5 | 6 | var room = HBInit({roomName:"Command Abuse Detection",noPlayer:true,public:true,maxPlayers:12}); 7 | 8 | function checkForCommandAbuse(player,message){ 9 | var index = playerList[player.name].commandUsages.findIndex(c => c[0] == message.toLowerCase()); 10 | if(index !== -1){ 11 | playerList[player.name].commandUsages[index].push(Date.now()); 12 | if(playerList[player.name].commandUsages[index].length > 5){ 13 | playerList[player.name].commandUsages[index].splice(3,1); 14 | } 15 | if(playerList[player.name].commandUsages[index].length == 5){ 16 | if(parseInt(playerList[player.name].commandUsages[index][4]) - parseInt(playerList[player.name].commandUsages[index][3]) < parseInt(playerList[player.name].commandUsages[index][1])){ 17 | if(playerList[player.name].commandUsages[index][2] == false){ 18 | playerList[player.name].commandUsages[index][2] = true; 19 | } 20 | } 21 | else{ 22 | if(playerList[player.name].commandUsages[index][2] == true){ 23 | playerList[player.name].commandUsages[index][2] = false; 24 | } 25 | } 26 | } 27 | } 28 | else{ 29 | return false; 30 | } 31 | } 32 | 33 | function checkLobbyAFK(){ 34 | var players = room.getPlayerList().filter(p => playerList[p.name].afkStatus == true); 35 | players.forEach(p => { 36 | var length = playerList[p.name].afkMatches.length; 37 | 38 | if(playerList[p.name].commandUsages[1][2] == false){ 39 | if(playerList[p.name].afkMatches[length-1] < afkLimit){ 40 | playerList[p.name].afkMatches[length-1]++; 41 | } 42 | else{ 43 | room.kickPlayer(p.id,"Lobby AFK timeout.",false); 44 | } 45 | } 46 | else{ 47 | var lastAbusive = playerList[p.name].afkMatches.findLastIndex(x => x != 0); 48 | 49 | if(lastAbusive === -1){ 50 | if(playerList[p.name].afkMatches[length-1] < afkLimit){ 51 | playerList[p.name].afkMatches[length-1]++; 52 | } 53 | else{ 54 | room.kickPlayer(p.id,"Lobby AFK timeout.",false); 55 | } 56 | } 57 | else{ 58 | if(playerList[p.name].afkMatches[lastAbusive] < afkLimit){ 59 | playerList[p.name].afkMatches[lastAbusive]++; 60 | } 61 | else{ 62 | room.kickPlayer(p.id,"Lobby AFK timeout.",false); 63 | } 64 | } 65 | } 66 | }); 67 | } 68 | 69 | function setAdmin(player,message){ 70 | room.setPlayerAdmin(player.id,!player.admin); 71 | checkForCommandAbuse(player,message); 72 | return false; 73 | } 74 | 75 | function setAFK(player,message){ 76 | playerList[player.name].afkStatus = !playerList[player.name].afkStatus; 77 | checkForCommandAbuse(player,message); 78 | var length = playerList[player.name].afkMatches.length; 79 | 80 | var index = playerList[player.name].commandUsages.findIndex(cu => cu[0] == message); 81 | if(playerList[player.name].afkMatches[length-1] != 0){ 82 | if(playerList[player.name].commandUsages[index][2] == false){ 83 | playerList[player.name].afkMatches.push(0); 84 | } 85 | else{ 86 | var lastAbusive = playerList[player.name].afkMatches.findLastIndex(p => p != 0); 87 | if(lastAbusive === -1){ 88 | console.log("No abusive behaviors found."); 89 | } 90 | else{ 91 | playerList[player.name].afkMatches[length-1] = playerList[player.name].afkMatches[lastAbusive]; 92 | } 93 | } 94 | } 95 | 96 | if(playerList[player.name].afkStatus == true){ 97 | room.setPlayerTeam(player.id,0); 98 | room.sendAnnouncement(`You're now AFK. (At most ${afkLimit+1} matches)`,player.id,0x00FF00,"normal",1); 99 | return false; 100 | } 101 | else{ 102 | room.sendAnnouncement(`You're now with us!`,player.id,0x00FF00,"normal",1); 103 | var index = playerList[player.name].commandUsages.findIndex(cu => cu[0] == message); 104 | return false; 105 | } 106 | } 107 | 108 | room.onPlayerChat = function(player,message){ 109 | console.log(`${player.name}: ${message}`); 110 | 111 | for(var i=0; i c[0] == message.toLowerCase()); 114 | if(index !== -1){ 115 | chatFunctions[index](player,message); 116 | return false; 117 | } 118 | else{ 119 | room.sendAnnouncement("There's no such a command",player.id,0xFF0000,"bold",2); 120 | return false; 121 | } 122 | } 123 | } 124 | } 125 | 126 | room.onPlayerJoin = function(player){ 127 | console.log(`${player.name} has joined`); 128 | 129 | if(playerList[player.name] == undefined){ 130 | playerList[player.name] = {name: player.name, auth: player.auth, conn: player.conn, afkMatches: [0], afkStatus: false, commandUsages: []}; 131 | } 132 | else if(playerList[player.name] == undefined){ 133 | playerList[player.name].afkMatches.push(0); 134 | playerList[player.name].afkStatus = false; 135 | } 136 | 137 | for(var i=0; i cu[0] == commands[i][0]); 139 | if(index === -1){ 140 | playerList[player.name].commandUsages.push([commands[i][0],commands[i][1],false,Date.now(),Date.now()]); //[Command,Interval,Is abusive?,Previous usage,Last usage] 141 | } 142 | else{ 143 | continue; 144 | } 145 | } 146 | } 147 | 148 | room.onPlayerTeamChange = function(changedPlayer,byPlayer){ 149 | if(changedPlayer.team != 0 && playerList[changedPlayer.name].afkStatus == true){ 150 | room.setPlayerTeam(changedPlayer.id,0); 151 | } 152 | } 153 | 154 | room.onTeamVictory = function(scores){ 155 | checkLobbyAFK(); 156 | } 157 | -------------------------------------------------------------------------------- /Advanced/MVP.js: -------------------------------------------------------------------------------- 1 | var Map = '{"name":"hax.ita Futsal 1v1 2v2","width":480,"height":230,"bg":{"type":"","kickOffRadius":60,"color":"304a32"},"vertexes":[{"x":-401.4,"y":-200,"trait":"vertexDefault"},{"x":401.4,"y":-200,"trait":"vertexDefault"},{"x":401.4,"y":200,"trait":"vertexDefault"},{"x":-401.4,"y":200,"trait":"vertexDefault"},{"x":0,"y":200,"trait":"vertexDefault"},{"x":0,"y":-200,"trait":"vertexDefault"},{"x":0,"y":-80,"cMask":["red","blue"],"cGroup":["redKO","blueKO"],"trait":"vertexDefault","color":"c2c2c2"},{"x":0,"y":80,"cMask":["red","blue"],"cGroup":["redKO","blueKO"],"trait":"vertexDefault","color":"c2c2c2"},{"x":-400,"y":70,"trait":"vertexDefault"},{"x":-400,"y":-70,"trait":"vertexDefault"},{"x":400,"y":-70,"trait":"vertexDefault"},{"x":400,"y":70,"trait":"vertexDefault"},{"x":0,"y":230,"trait":"vertexDefault"},{"x":0,"y":-230,"trait":"vertexDefault"},{"x":436.4,"y":-70,"trait":"vertexDefault"},{"x":436.4,"y":70,"trait":"vertexDefault"},{"x":-436.4,"y":-70,"trait":"vertexDefault"},{"x":-436.4,"y":70,"trait":"vertexDefault"},{"x":0,"y":-1.5,"trait":"vertexDefault"},{"x":0,"y":1.5,"trait":"vertexDefault"},{"x":400,"y":-135,"trait":"vertexDefault"},{"x":400,"y":135,"trait":"vertexDefault"},{"x":-400,"y":-135,"trait":"vertexDefault"},{"x":-400,"y":135,"trait":"vertexDefault"},{"x":-400,"y":-201.4,"trait":"vertexDefault"},{"x":400,"y":-201.4,"trait":"vertexDefault"},{"x":400,"y":201.4,"trait":"vertexDefault"},{"x":-400,"y":201.4,"trait":"vertexDefault"},{"x":435,"y":-71.4,"trait":"vertexDefault"},{"x":435,"y":71.4,"trait":"vertexDefault"},{"x":-435,"y":-71.4,"trait":"vertexDefault"},{"x":-435,"y":71.4,"trait":"vertexDefault"}],"segments":[{"v0":5,"v1":6,"trait":"wall_map_nc"},{"v0":4,"v1":7,"trait":"wall_map_nc"},{"v0":6,"v1":13,"trait":"KO_barrier"},{"v0":7,"v1":12,"trait":"KO_barrier"},{"v0":6,"v1":7,"curve":180,"color":"c2c2c2","trait":"KO_wall_red"},{"v0":7,"v1":6,"curve":180,"color":"c2c2c2","trait":"KO_wall_blue"},{"v0":18,"v1":19,"curve":180,"trait":"decoration_map"},{"v0":19,"v1":18,"curve":180,"trait":"decoration_map"},{"v0":21,"v1":20,"curve":150,"trait":"decoration_map"},{"v0":22,"v1":23,"curve":150,"trait":"decoration_map"},{"v0":10,"v1":14,"trait":"wall_blue_goal"},{"v0":28,"v1":29,"trait":"wall_blue_goal"},{"v0":15,"v1":11,"trait":"wall_blue_goal"},{"v0":8,"v1":17,"trait":"wall_red_goal"},{"v0":31,"v1":30,"trait":"wall_red_goal"},{"v0":16,"v1":9,"trait":"wall_red_goal"},{"v0":9,"v1":8,"trait":"goal_line"},{"v0":10,"v1":11,"trait":"goal_line"},{"v0":0,"v1":1,"trait":"wall_map"},{"v0":25,"v1":10,"trait":"wall_map"},{"v0":11,"v1":26,"trait":"wall_map"},{"v0":2,"v1":3,"trait":"wall_map"},{"v0":27,"v1":8,"trait":"wall_map"},{"v0":9,"v1":24,"trait":"wall_map"}],"planes":[{"normal":[0,1],"dist":-230,"bCoef":0,"_data":{"extremes":{"normal":[0,1],"dist":-230,"canvas_rect":[-901,-368,901,368],"a":[-901,-230],"b":[901,-230]}}},{"normal":[0,-1],"dist":-230,"bCoef":0,"_data":{"extremes":{"normal":[0,-1],"dist":-230,"canvas_rect":[-901,-368,901,368],"a":[-901,230],"b":[901,230]}}},{"normal":[1,0],"dist":-480,"bCoef":0,"_data":{"extremes":{"normal":[1,0],"dist":-480,"canvas_rect":[-901,-368,901,368],"a":[-480,-368],"b":[-480,368]}}},{"normal":[-1,0],"dist":-480,"bCoef":0,"_data":{"extremes":{"normal":[-1,0],"dist":-480,"canvas_rect":[-901,-368,901,368],"a":[480,-368],"b":[480,368]}}}],"goals":[{"p0":[-407.9,70],"p1":[-407.9,-70],"team":"red"},{"p0":[407.9,70],"p1":[407.9,-70],"team":"blue"}],"discs":[{"pos":[-400,-70],"trait":"goal_post"},{"pos":[-400,70],"trait":"goal_post"},{"pos":[400,-70],"trait":"goal_post"},{"pos":[400,70],"trait":"goal_post"}],"playerPhysics":{"bCoef":0,"acceleration":0.11,"kickingAcceleration":0.083,"kickStrength":4.2,"radius":15},"ballPhysics":{"radius":5.8,"bCoef":0.412,"invMass":1.55,"color":"FFF26D"},"spawnDistance":200,"traits":{"wall_map":{"vis":true,"color":"abc2d5","bCoef":1,"cMask":["ball"],"bias":-10},"wall_map_nc":{"vis":true,"color":"abc2d5","bCoef":0,"cMask":[],"cGroup":[]},"KO_wall_red":{"vis":true,"color":"d9a472","bCoef":0.1,"cMask":["red","blue"],"cGroup":["redKO"]},"KO_wall_blue":{"vis":true,"color":"d9a472","bCoef":0.1,"cMask":["red","blue"],"cGroup":["blueKO"]},"vertexDefault":{"bCoef":1,"cMask":[],"cGroup":[]},"decoration_map":{"vis":true,"color":"626262","bCoef":0,"cMask":[]},"goal_line":{"vis":true,"color":"c5c5c5","bCoef":0,"cMask":[]},"wall_red_goal":{"vis":true,"color":"ff6666","bCoef":0.1,"cMask":["ball"],"bias":-10},"wall_blue_goal":{"vis":true,"color":"6666ff","bCoef":0.1,"cMask":["ball"],"bias":-10},"goal_post":{"radius":5.4,"invMass":0,"color":"031726"},"map_point":{"curve":180,"vis":true,"color":"626262","cMask":[]},"KO_barrier":{"vis":false,"bCoef":0.1,"cMask":["red","blue"],"cGroup":["redKO","blueKO"]}},"joints":[],"redSpawnPoints":[],"blueSpawnPoints":[],"canBeStored":false}'; 2 | 3 | var JMap = JSON.parse(Map); 4 | 5 | var room = HBInit({ roomName: "MVP Script", playerName: "", noPlayer: true, public: true, maxPlayers: 16}); 6 | 7 | room.setCustomStadium(Map) 8 | 9 | var lastScores = 0; 10 | var lastTeamTouched = 0; 11 | var previousBallPos; 12 | var assistingTouch = undefined; 13 | var lastPlayerTouched = undefined; 14 | var previousPlayerTouched; 15 | var radiusBall = JMap.ballPhysics.radius; //Requires your map to have ballPhysics with a real radius value. 16 | var radiusPlayer = JMap.playerPhysics.radius; //Requires your map to have playerPhysics with a real radius value. 17 | var triggerDistance = radiusBall + radiusPlayer + 0.01; 18 | var mvp; 19 | 20 | var playerList = []; 21 | 22 | room.setScoreLimit(0); 23 | room.setTimeLimit(0); 24 | room.setTeamsLock(true); 25 | 26 | function getLastTouchTheBall() { 27 | var ballPosition = room.getBallPosition(); 28 | var players = room.getPlayerList(); 29 | for (var i = 0; i < players.length; i++) { 30 | if (players[i].position != null) { 31 | var distanceToBall = pointDistance(players[i].position, ballPosition); 32 | if (distanceToBall < triggerDistance) { 33 | if (lastPlayerTouched != players[i]) { 34 | if (lastTeamTouched == players[i].team) { 35 | assistingTouch = lastPlayerTouched; 36 | } 37 | else { 38 | assistingTouch = undefined; 39 | } 40 | } 41 | lastTeamTouched = players[i].team; 42 | previousPlayerTouched == lastPlayerTouched; 43 | lastPlayerTouched = players[i]; 44 | } 45 | } 46 | } 47 | return lastPlayerTouched; 48 | } 49 | 50 | function pointDistance(p1, p2) { 51 | return Math.hypot(p1.x - p2.x, p1.y - p2.y); 52 | } 53 | 54 | function SortRanks() { 55 | mvp = playerList[0]; 56 | for(var i=0; i mvp.matchgoals){ 58 | mvp = playerList[i]; 59 | } 60 | else if(playerList[i].matchgoals == mvp.matchgoals){ 61 | if(playerList[i].matchassists > mvp.matchassists){ 62 | mvp = playerList[i]; 63 | } 64 | } 65 | } 66 | 67 | return mvp; 68 | } 69 | 70 | function findMvp(player) { 71 | mvp = SortRanks(); 72 | room.sendAnnouncement("Actual most valuable player:\nName: " + mvp.name + " - Goals: " + mvp.matchgoals + " - Assists: " + mvp.matchassists, player.id, 0xFFFFFF, "normal", 1); 73 | } 74 | 75 | room.onPlayerBallKick = function (player) { 76 | if (player != lastPlayerTouched) { 77 | if (lastTeamTouched == player.team) { 78 | assistingTouch = lastPlayerTouched; 79 | } else assistingTouch = undefined; 80 | } 81 | previousPlayerTouched = lastPlayerTouched; 82 | lastPlayerTouched = player; 83 | lastTeamTouched = player.team; 84 | } 85 | 86 | room.onPlayerJoin = function (player) { 87 | var playerObject; 88 | if (localStorage.getItem(player.auth) == null) { //On first join 89 | playerObject = { auth: player.auth, conn: player.conn, name: player.name, id: player.id, goals: 0, assists: 0, matchgoals: 0, matchassists: 0, isInTheRoom: true }; 90 | localStorage.setItem(player.auth, JSON.stringify(playerObject)); 91 | 92 | playerList[player.id - 1] = { auth: player.auth, conn: player.conn, name: player.name, id: player.id, goals: 0, assists: 0, matchgoals: 0, matchassists: 0, isInTheRoom: true }; 93 | } 94 | else if (localStorage.getItem(player.auth) != null) { //On second are more joins 95 | playerList[player.id - 1] = { auth: player.auth, conn: player.conn, name: player.name, id: player.id, goals: JSON.parse(localStorage.getItem(player.auth)).goals, assists: JSON.parse(localStorage.getItem(player.auth)).assists, matchgoals: 0, matchassists: 0, isInTheRoom: true }; 96 | } 97 | } 98 | 99 | room.onPlayerLeave = function (player) { 100 | playerList[player.id - 1].isInTheRoom = false; 101 | var playerObject = { auth: playerList[player.id - 1].auth, conn: playerList[player.id - 1].conn, name: player.name, id: player.id, goals: JSON.parse(localStorage.getItem(playerList[player.id - 1].auth)).goals, assists: JSON.parse(localStorage.getItem(playerList[player.id - 1].auth)).assists, matchgoals: 0, matchassists: 0, isInTheRoom: false }; 102 | localStorage.setItem(playerList[player.id - 1].auth, JSON.stringify(playerObject)); 103 | } 104 | 105 | room.onPlayerChat = function (player, message) { 106 | if (message == "!mvp") { 107 | findMvp(player); 108 | return false; 109 | } 110 | }; 111 | 112 | room.onPositionsReset = function () { 113 | assistingTouch = undefined; 114 | lastPlayerTouched = undefined; 115 | } 116 | 117 | room.onGameStart = function (byPlayer) { 118 | assistingTouch = undefined; 119 | lastPlayerTouched = undefined; 120 | 121 | playerList.filter(p => playerList[p.id - 1].isInTheRoom == true).forEach(p => { playerList[p.id - 1].matchgoals = 0; playerList[p.id - 1].matchassists = 0; }); 122 | } 123 | 124 | room.onGameStop = function (byPlayer) { 125 | assistingTouch = undefined; 126 | lastPlayerTouched = undefined; 127 | 128 | playerList.filter(p => playerList[p.id - 1].isInTheRoom == true).forEach(p => { playerList[p.id - 1].matchgoals = 0; playerList[p.id - 1].matchassists = 0; }); 129 | } 130 | 131 | room.onTeamGoal = function (team) { 132 | var time = room.getScores().time; 133 | var players = room.getPlayerList(); 134 | var floorm = m => m < 10 ? "0" + m : m; 135 | var floors = s => s < 10 ? "0" + s : s; 136 | var m = Math.trunc(time / 60); 137 | var s = Math.trunc(time % 60); 138 | time = floorm(m) + ":" + floors(s); 139 | 140 | for (var i = 0; i < players.length; i++) { 141 | if (lastPlayerTouched != undefined) { 142 | if (players[i].id == lastPlayerTouched.id) { 143 | if (players[i].team == team) { 144 | if (assistingTouch != undefined) { 145 | if (players[i].id != assistingTouch.id) { 146 | room.sendAnnouncement("[G] ⚽️ Goal! - Scorer: " + players[i].name + ". Assist by: " + assistingTouch.name + " ⌛ " + time + " - Score is now... 🔴 " + room.getScores().red + " - " + room.getScores().blue + " 🔵", null,); 147 | playerList[players[i].id - 1].matchgoals++; 148 | for (var j = 0; j < players.length; j++) { 149 | if (players[j].team == players[i].team && players[j].id == assistingTouch.id && players[j].id != players[i].id) { 150 | playerList[players[j].id - 1].matchassists++; 151 | } 152 | } 153 | assistingTouch = undefined; 154 | lastPlayerTouched = undefined; 155 | } 156 | else { 157 | room.sendAnnouncement("[G] ⚽️ Goal! - Scorer: " + players[i].name + " ⌛ " + time + " - Score is now... 🔴 " + room.getScores().red + " - " + room.getScores().blue + " 🔵"); 158 | playerList[players[i].id - 1].matchgoals++; 159 | assistingTouch = undefined; 160 | lastPlayerTouched = undefined; 161 | } 162 | } 163 | else { 164 | room.sendAnnouncement("[G] ⚽️ Goal! - Scorer: " + players[i].name + " ⌛ " + time + " - Score is now... 🔴 " + room.getScores().red + " - " + room.getScores().blue + " 🔵"); 165 | playerList[players[i].id - 1].matchgoals++; 166 | assistingTouch = undefined; 167 | lastPlayerTouched = undefined; 168 | } 169 | } 170 | else { 171 | room.sendAnnouncement("[OG] ⚽️ Own goal! - Scorer: " + players[i].name + " ⌛ " + time + " - Score is now... 🔴 " + room.getScores().red + " - " + room.getScores().blue + " 🔵"); 172 | } 173 | } 174 | } 175 | } 176 | } 177 | 178 | room.onGameTick = function () { 179 | getLastTouchTheBall(); 180 | } 181 | 182 | room.onTeamVictory = function (scores) { 183 | mvp = SortRanks(); 184 | room.sendAnnouncement("Actual most valuable player:\nName: " + mvp.name + " - Goals: " + mvp.matchgoals + " - Assists: " + mvp.matchassists, null, 0xFFFFFF, "normal", 1); 185 | } 186 | 187 | room.onStadiumChange = function (newStadiumName, byPlayer) { 188 | if (byPlayer != null) { 189 | room.setCustomStadium(Map); 190 | } 191 | } 192 | -------------------------------------------------------------------------------- /Advanced/Mute.js: -------------------------------------------------------------------------------- 1 | var playerList = {}; 2 | var mutedAuths = []; 3 | 4 | var playerMessages = ["PLAYER","ADMIN"]; 5 | var messagePrefix = "!"; 6 | var commands = ["!mute"]; 7 | 8 | var muteRange = {Min: 1, Max: 10}; 9 | 10 | var timeObject = {Seconds: 1000, Minutes: 60000, Hours: 3600000}; 11 | 12 | var colors = { 13 | Mute:{ 14 | Admin: 0xFF0000, 15 | AdminCanSee: 0xFFFF00, 16 | Already: 0xFFFF00, 17 | InvalidID: 0xFFFF00, 18 | InvalidNumber: 0xFFFF00, 19 | NoSuchPlayer: 0xFF0000, 20 | OutOfRange: 0xFFFF00, 21 | Removal: 0x00FF00, 22 | Self: 0xFFFF00, 23 | Still: 0xFFFF00, 24 | Success: 0x00FF00 25 | }, 26 | NoAuthorization:{ 27 | Mute: 0xFF0000 28 | }, 29 | Player: [0xFFFFFF,0xFFDB72], 30 | Unmute: 0x00FF00, 31 | Welcome: 0xFFFFFF 32 | }; 33 | 34 | var fonts = { 35 | Mute:{ 36 | Admin: "bold", 37 | AdminCanSee: "bold", 38 | Already: "bold", 39 | InvalidID: "bold", 40 | InvalidNumber: "bold", 41 | NoSuchPlayer: "bold", 42 | OutOfRange: "bold", 43 | Removal: "normal", 44 | Self: "bold", 45 | Still: "small", 46 | Success: "normal", 47 | }, 48 | NoAuthorization:{ 49 | Mute: "bold" 50 | }, 51 | Player: ["normal","bold"], 52 | Unmute: "normal", 53 | Welcome: "normal" 54 | }; 55 | 56 | var sounds = { 57 | Mute:{ 58 | Admin: 2, 59 | AdminCanSee: 1, 60 | Already: 2, 61 | InvalidID: 2, 62 | InvalidNumber: 2, 63 | NoSuchPlayer: 2, 64 | OutOfRange: 2, 65 | Removal: 1, 66 | Self: 2, 67 | Still: 0, 68 | Success: 1, 69 | }, 70 | NoAuthorization:{ 71 | Mute: 2 72 | }, 73 | Player: [1,1], 74 | Unmute: 1, 75 | Welcome: 1 76 | }; 77 | 78 | var messages = { 79 | Mute:{ 80 | Admin: "You cannot mute an administrator!", 81 | Already: "This player is already muted!", 82 | InvalidID: "Invalid ID!", 83 | InvalidNumber: "Invalid number!", 84 | NoSuchPlayer: "No such a player with the given ID!", 85 | OutOfRange: `Mute period is bound with ${muteRange.Min} and ${muteRange.Max} minutes`, 86 | Removal: "has been unmuted!", 87 | Self: "You cannot mute yourselves!", 88 | Still: "You are still muted! Only the administration can see your messages", 89 | Success: ["has been muted by","for"] 90 | }, 91 | NoAuthorization:{ 92 | Mute: "You have no authorization to mute a player in this room!" 93 | }, 94 | Unmute: "has been unmuted!", 95 | Welcome: "Welcome!" 96 | }; 97 | 98 | var room = HBInit({roomName:"Mute Players",noPlayer:true,public:true,maxPlayers:12}); 99 | 100 | function isCommand(string){ 101 | return string.startsWith(messagePrefix) == true && (commands.includes(string) == true || commands.includes(string.split(" ")[0]) == true); 102 | } 103 | 104 | room.onPlayerChat = function(player,message){ 105 | console.log(`${player.name}: ${message}`); 106 | var administrators = room.getPlayerList().filter(p => p.admin == true); 107 | 108 | if(isCommand(message) == true){ 109 | if(player.admin == true){ 110 | var ID = parseInt(message.toLowerCase().split(" ")[1]); 111 | 112 | if(isNaN(ID)){ 113 | room.sendAnnouncement(`${messages.Mute.InvalidID}`,player.id,colors.Mute.InvalidID,fonts.Mute.InvalidID,sounds.Mute.InvalidID); 114 | return false; 115 | } 116 | else{ 117 | var p = room.getPlayerList().find(x => x.id == ID); 118 | 119 | if(!p){ 120 | room.sendAnnouncement(`${messages.Mute.NoSuchPlayer}`,player.id,colors.Mute.NoSuchPlayer,fonts.Mute.NoSuchPlayer,sounds.Mute.NoSuchPlayer); 121 | return false; 122 | } 123 | else{ 124 | if(p.id == player.id){ 125 | room.sendAnnouncement(`${messages.Mute.Self}`,player.id,colors.Mute.Self,fonts.Mute.Self,sounds.Mute.Self); 126 | return false; 127 | } 128 | else{ 129 | if(p.admin == true){ 130 | room.sendAnnouncement(`${messages.Mute.Admin}`,player.id,colors.Mute.Admin,fonts.Mute.Admin,sounds.Mute.Admin); 131 | return false; 132 | } 133 | else{ 134 | var time = parseInt(message.toLowerCase().split(" ")[2]); 135 | 136 | if(isNaN(time)){ 137 | room.sendAnnouncement(`${messages.Mute.InvalidNumber}`,player.id,colors.Mute.InvalidNumber,fonts.Mute.InvalidNumber,sounds.Mute.InvalidNumber); 138 | return false; 139 | } 140 | else{ 141 | if(time < muteRange.Min || muteRange.Max < time){ 142 | room.sendAnnouncement(`${messages.Mute.OutOfRange}`,player.id,colors.Mute.OutOfRange,fonts.Mute.OutOfRange,sounds.Mute.OutOfRange); 143 | return false; 144 | } 145 | else{ 146 | if(mutedAuths.includes(playerList[p.name].auth) == true){ 147 | room.sendAnnouncement(`${messages.Mute.Already}`,player.id,colors.Mute.Already,fonts.Mute.Already,sounds.Mute.Already); 148 | return false; 149 | } 150 | else{ 151 | room.sendAnnouncement(`${p.name} ${messages.Mute.Success[0]} ${player.name} ${messages.Mute.Success[1]} ${time} ${time == 1 ? "minute." : "minutes."}`,null,colors.Mute.Success,fonts.Mute.Success,sounds.Mute.Success); 152 | mutedAuths.push(playerList[p.name].auth); 153 | var pname = p.name; 154 | var pauth = playerList[pname].auth; 155 | setTimeout(function(){ 156 | if(mutedAuths.includes(pauth) == true){ 157 | var index = mutedAuths.indexOf(pauth); 158 | mutedAuths.splice(index,1); 159 | room.sendAnnouncement(`${pname} ${messages.Unmute}`,null,colors.Unmute,fonts.Unmute,sounds.Unmute); 160 | } 161 | },time*timeObject.Minutes); 162 | return false; 163 | } 164 | } 165 | } 166 | } 167 | } 168 | } 169 | } 170 | } 171 | else{ 172 | room.sendAnnouncement(`${messages.NoAuthorization.Mute}`,player.id,colors.NoAuthorization.Mute,fonts.NoAuthorization.Mute,sounds.NoAuthorization.Mute); 173 | return false; 174 | } 175 | } 176 | else{ 177 | if(player.admin == false && mutedAuths.includes(playerList[player.name].auth) == true){ 178 | room.sendAnnouncement(`${messages.Mute.Still} (${message})`,player.id,colors.Mute.AdminCanSee,fonts.Mute.AdminCanSee,sounds.Mute.AdminCanSee); 179 | administrators.forEach(a => { 180 | room.sendAnnouncement(`[${playerMessages[Number(player.admin)]}] [${player.id}] ${player.name}: ${message}`,a.id,colors.Mute.Still,fonts.Mute.Still,sounds.Mute.Still); 181 | }); 182 | return false; 183 | } 184 | 185 | room.sendAnnouncement(`[${playerMessages[Number(player.admin)]}] [${player.id}] ${player.name}: ${message}`,null,colors.Player[Number(player.admin)],fonts.Player[Number(player.admin)],sounds.Player[Number(player.admin)]); 186 | return false; 187 | } 188 | } 189 | 190 | room.onPlayerJoin = function(player){ 191 | console.log(`${player.name} has joined`); 192 | 193 | room.sendAnnouncement(`${messages.Welcome}`,player.id,colors.Welcome,fonts.Welcome,sounds.Welcome); 194 | 195 | if(playerList[player.name] == undefined){ 196 | playerList[player.name] = {name: player.name, auth: player.auth, conn: player.conn}; 197 | } 198 | if(mutedAuths.includes(player.auth) == true){ 199 | room.sendAnnouncement(`${messages.Mute.Still}`,player.id,colors.Mute.Still,fonts.Mute.Still,sounds.Mute.Still); 200 | } 201 | } 202 | -------------------------------------------------------------------------------- /Advanced/RadiusSetting_CommandUsage.js: -------------------------------------------------------------------------------- 1 | var commandPrefix = "!"; 2 | var commands = [["!commands", 0, false], ["!size", 1, true]]; //[command,usage bound,available during the game]; 0 means unlimited usage. 3 | var playerList = {}; 4 | var playerListArray = []; 5 | var radiusBounds = { Lower: 1, Upper: 100 }; 6 | 7 | var colors = { 8 | onPlayerChat: { 9 | Commands: [0xFFFFFF, 0xFFDB72], 10 | GameNotActive: 0xFFFF00, 11 | Invalid: { 12 | Number: 0xFFFF00, 13 | OutOfBounds: 0xFFFF00 14 | }, 15 | IsNotACommand: 0xFF0000, 16 | NotInGame: 0xFF0000, 17 | Player: [0xFFFFFF, 0xFFDB72], 18 | Size: { 19 | Fail: { 20 | RightExpired: 0xFF0000 21 | }, 22 | Success: 0x00FF00 23 | } 24 | } 25 | }; 26 | 27 | var fonts = { 28 | onPlayerChat: { 29 | Commands: ["normal", "bold"], 30 | GameNotActive: "bold", 31 | Invalid: { 32 | Number: "bold", 33 | OutOfBounds: "bold" 34 | }, 35 | IsNotACommand: "bold", 36 | NotInGame: "bold", 37 | Player: ["normal", "bold"], 38 | Size: { 39 | Fail: { 40 | RightExpired: "bold" 41 | }, 42 | Success: "normal" 43 | } 44 | } 45 | }; 46 | 47 | var sounds = { 48 | onPlayerChat: { 49 | Commands: [1, 1], 50 | GameNotActive: 2, 51 | Invalid: { 52 | Number: 1, 53 | OutOfBounds: 1 54 | }, 55 | IsNotACommand: 2, 56 | NotInGame: 2, 57 | Player: [1, 1], 58 | Size: { 59 | Fail: { 60 | RightExpired: 2 61 | }, 62 | Success: 1 63 | } 64 | } 65 | }; 66 | 67 | var messages = { 68 | onPlayerChat: { 69 | Commands: ["Available Commands: !commands, !size", "Available Commands: !commands, !size"], //Can also be done dynamically with different arrays for player/admin. 70 | GameNotActive: "The feature will be available when the game is running.", 71 | Invalid: { 72 | Number: "The value you have typed is not a number.", 73 | OutOfBounds: `The input value is invalid. Please type a number between ${radiusBounds.Lower} and ${radiusBounds.Upper}.` 74 | }, 75 | IsNotACommand: "is not a command. Please type !commands to see available command list.", 76 | NotInGame: "You cannot use this property unless you are actively playing.", 77 | Player: ["[PLAYER]", "[ADMIN]"], 78 | Size: { 79 | Fail: { 80 | RightExpired: "Your right for sizing radiuses has expired. Please try it in another match." 81 | }, 82 | Success: "Your radius set to" 83 | } 84 | } 85 | }; 86 | 87 | var roomObject = { 88 | maxPlayers: 2, 89 | noPlayer: true, 90 | public: true, 91 | roomName: "Radius Setting with Command Usage", 92 | }; 93 | 94 | var room = HBInit({ roomName: roomObject.roomName, noPlayer: roomObject.noPlayer, public: roomObject.public, maxPlayers: roomObject.maxPlayers }); 95 | 96 | var chatFunctions = [chat_commands, chat_size]; 97 | 98 | function chat_commands(player, message) { 99 | room.sendAnnouncement(`${messages.onPlayerChat.Commands[Number(player.admin)]}`, player.id, colors.onPlayerChat.Commands[Number(player.admin)], fonts.onPlayerChat.Commands[Number(player.admin)], sounds.onPlayerChat.Commands[Number(player.admin)]); 100 | return false; 101 | } 102 | 103 | function chat_size(player, message) { 104 | var value = message.split(" ")[1]; 105 | if (isNaN(value)) { 106 | room.sendAnnouncement(`${messages.onPlayerChat.Invalid.Number}`, player.id, colors.onPlayerChat.Invalid.Number, fonts.onPlayerChat.Invalid.Number, sounds.onPlayerChat.Invalid.Number); 107 | return false; 108 | } 109 | else { 110 | if (ifRadiusOutOfBounds(value, radiusBounds.Lower, radiusBounds.Upper) == true) { 111 | room.sendAnnouncement(`${messages.onPlayerChat.Invalid.OutOfBounds}`, player.id, colors.onPlayerChat.Invalid.OutOfBounds, fonts.onPlayerChat.Invalid.OutOfBounds, sounds.onPlayerChat.Invalid.OutOfBounds); 112 | return false; 113 | } 114 | else { 115 | if (ifPlayerIsInGame(player) == false) { 116 | room.sendAnnouncement(`${messages.onPlayerChat.NotInGame}`, player.id, colors.onPlayerChat.NotInGame, fonts.onPlayerChat.NotInGame, sounds.onPlayerChat.NotInGame); 117 | decreaseCommandUsages(player,1); 118 | return false; 119 | } 120 | else { 121 | setPlayerRadius(player,value); 122 | room.sendAnnouncement(`${messages.onPlayerChat.Size.Success} ${value}`, player.id, colors.onPlayerChat.Size.Success, fonts.onPlayerChat.Size.Success, sounds.onPlayerChat.Size.Success); 123 | return false; 124 | } 125 | } 126 | } 127 | } 128 | 129 | function decreaseCommandUsages(player,index) { 130 | if (playerList[player.name].commandUsages[index][0] > 0) { 131 | playerList[player.name].commandUsages[index][0]--; 132 | } 133 | } 134 | 135 | function handleCommandUsageBounds(player, message, index, bound) { 136 | if (playerList[player.name].commandUsages[index] > 0) { 137 | if (playerList[player.name].commandUsages[index][0] < bound) { 138 | chatFunctions[index](player, message); 139 | } 140 | else { 141 | if (playerList[player.name].commandUsages[index][1] == false) { 142 | playerList[player.name].commandUsages[index][1] = true; 143 | } 144 | } 145 | } 146 | } 147 | 148 | function ifPlayerIsInGame(player) { 149 | return room.getPlayerDiscProperties(player.id) != null; 150 | } 151 | 152 | function ifRadiusOutOfBounds(radius, lowerBound, upperBound) { 153 | return radius < lowerBound || upperBound < radius; 154 | } 155 | 156 | function increaseCommandUsages(player, message, index, bound) { 157 | if (isCommand(message) == true) { 158 | if (playerList[player.name].commandUsages[index][0] < bound) { 159 | playerList[player.name].commandUsages[index][0]++; 160 | } 161 | handleCommandUsageBounds(player, message, index, commands[index][1]); 162 | } 163 | } 164 | 165 | function isCommand(message) { 166 | return commands.filter(c => c[0] == message || c[0] == message.split(" ")[0]).length == 1; 167 | } 168 | 169 | function resetCommandUsages(player) { 170 | playerList[player.name].commandUsages.forEach(c => { 171 | c[0] = 0; 172 | c[1] = false; 173 | }); 174 | } 175 | 176 | function setPlayerRadius(player, radius) { 177 | if (ifPlayerIsInGame(player) == true) { 178 | room.setPlayerDiscProperties(player.id, { radius: radius }); 179 | } 180 | } 181 | 182 | room.onGameStart = function (byPlayer) { 183 | room.getPlayerList().forEach(p => resetCommandUsages(p)); 184 | } 185 | 186 | room.onPlayerChat = function (player, message) { 187 | if (message.startsWith(commandPrefix) == true) { 188 | if (isCommand(message) == true) { 189 | var index = commands.findIndex(c => c[0] == message || c[0] == message.split(" ")[0]); 190 | if (index === -1) { 191 | room.sendAnnouncement(`${messages.onPlayerChat.IsNotACommand}`, player.id, colors.onPlayerChat.IsNotACommand, fonts.onPlayerChat.IsNotACommand, sounds.onPlayerChat.IsNotACommand); 192 | return false; 193 | } 194 | else { 195 | if (commands[index][2] == false) { 196 | chatFunctions[index](player, message); 197 | return false; 198 | } 199 | else { 200 | if (room.getScores() == null) { 201 | room.sendAnnouncement(`${messages.onPlayerChat.GameNotActive}`, player.id, colors.onPlayerChat.GameNotActive, fonts.onPlayerChat.GameNotActive, sounds.onPlayerChat.GameNotActive); 202 | return false; 203 | } 204 | else { 205 | increaseCommandUsages(player, message, index, commands[index][1]); 206 | return false; 207 | } 208 | } 209 | } 210 | } 211 | else { 212 | room.sendAnnouncement(`${messages.onPlayerChat.IsNotACommand}`, player.id, colors.onPlayerChat.IsNotACommand, fonts.onPlayerChat.IsNotACommand, sounds.onPlayerChat.IsNotACommand); 213 | return false; 214 | } 215 | } 216 | else { 217 | room.sendAnnouncement(`${messages.onPlayerChat.Player[Number(player.admin)]}[${player.name}]: ${message}`, null, colors.onPlayerChat.Player[Number(player.admin)], fonts.onPlayerChat.Player[Number(player.admin)], sounds.onPlayerChat.Player[Number(player.admin)]); 218 | return false; 219 | } 220 | } 221 | 222 | room.onPlayerJoin = function (player) { 223 | if (playerList[player.name] == undefined) { 224 | playerList[player.name] = { name: player.name, id: player.id, auth: player.auth, conn: player.conn, commandUsages: [] }; 225 | for (var c = 0; c < commands.length; c++) { 226 | playerList[player.name].commandUsages.push([0, false]); 227 | } 228 | } 229 | } 230 | 231 | //YET TO BE TESTED!!! 232 | -------------------------------------------------------------------------------- /Advanced/VoteBan.js: -------------------------------------------------------------------------------- 1 | const votedPlayers = new Set() 2 | let votekickTimes = {}; 3 | let votekickCount = {}; 4 | var votekickTimeout = 60000; 5 | var temp_ban_timeout = 300000; 6 | var PlayerFound = false; 7 | var playerList = []; 8 | var conns = []; 9 | var temp_banlist = []; 10 | 11 | var room = HBInit({roomName:"Voteban",playerName:"",noPlayer:true,public:true,maxPlayers:12}); 12 | 13 | function GetTeam(id){ 14 | return room.getPlayerList().filter((player) => player.id != 0 && player.team == id); 15 | } 16 | 17 | function CreatePlayer(player){ 18 | playerList[playerList.length]={ 19 | name:player.name, 20 | id:player.id, 21 | auth:undefined, 22 | conn:undefined, 23 | jointime:0 24 | }; 25 | } 26 | 27 | function DeletePlayer(id){ 28 | for(var i=0; i= (room.getPlayerList().length)*1/2){ 72 | room.kickPlayer(player.id,"You've been voted out. Good bye!",true); 73 | } 74 | else{ 75 | console.log(new Date().getHours() + ":" + new Date().getMinutes() + ":" + new Date().getSeconds() + "." + new Date().getMilliseconds() + " 🗳️ " + player.name + " : " + JSON.parse(localStorage.getItem(GetPlayer(player.id).auth)).votes + "/" + (room.getPlayerList().length)*1/2); 76 | room.sendAnnouncement("🗳️ " + player.name + " : " + JSON.parse(localStorage.getItem(GetPlayer(player.id).auth)).votes + "/" + (room.getPlayerList().length)*1/2,null,0xFFFFFF,"normal",1); 77 | } 78 | } 79 | else if((room.getPlayerList().length)%2 == 1){ 80 | if(JSON.parse(localStorage.getItem(GetPlayer(player.id).auth)).votes >= Math.round((room.getPlayerList().length)*1/2)){ 81 | room.kickPlayer(player.id,"You've been voted out. Good bye!",true); 82 | } 83 | else{ 84 | console.log(new Date().getHours() + ":" + new Date().getMinutes() + ":" + new Date().getSeconds() + "." + new Date().getMilliseconds() + " 🗳️ " + player.name + " : " + JSON.parse(localStorage.getItem(GetPlayer(player.id).auth)).votes + "/" + Math.round((room.getPlayerList().length)*1/2)); 85 | room.sendAnnouncement("🗳️ " + player.name + " : " + JSON.parse(localStorage.getItem(GetPlayer(player.id).auth)).votes + "/" + Math.round((room.getPlayerList().length)*1/2),null,0xFFFFFF,"normal",1); 86 | } 87 | } 88 | } 89 | 90 | room.onPlayerJoin = function(player){ 91 | CreatePlayer(player); 92 | GetPlayer(player.id).auth = player.auth; 93 | GetPlayer(player.id).conn = player.conn; 94 | conns.push([player.id,player.name,player.auth,player.conn]); 95 | console.log(new Date().getHours() + ":" + new Date().getMinutes() + ":" + new Date().getSeconds() + "." + new Date().getMilliseconds() + " ➡️ " + player.name + " [" + player.id + "] has joined. (auth: " + player.auth + " | conn: " + player.conn + ")"); 96 | GetPlayer(player.id).jointime = Date.now(); 97 | 98 | if(temp_banlist.includes(player.auth) == true){ 99 | room.kickPlayer(player.id,"You have been penalized for 5 minutes for ragequit!",false); 100 | } 101 | 102 | if(localStorage.getItem(player.auth) == null){ 103 | var playerObject = {auth:player.auth,votes:0} 104 | localStorage.setItem(player.auth,JSON.stringify(playerObject)); 105 | } 106 | } 107 | 108 | room.onPlayerLeave = function(player){ 109 | console.log(new Date().getHours() + ":" + new Date().getMinutes() + ":" + new Date().getSeconds() + "." + new Date().getMilliseconds() + " ➡️ " + player.name + " [" + player.id + "] has left."); 110 | 111 | if(room.getScores() != null && player.position != null){ 112 | temp_banlist.push(GetPlayer(player.id).auth); 113 | setTimeout(function(){temp_banlist.splice(temp_banlist.indexOf(GetPlayer(player.id).auth),1);},temp_ban_timeout); 114 | } 115 | 116 | DeletePlayer(player.id); 117 | } 118 | 119 | room.onPlayerChat = function(player,message){ 120 | var players = room.getPlayerList(); 121 | 122 | console.log(new Date().getHours() + ":" + new Date().getMinutes() + ":" + new Date().getSeconds() + "." + new Date().getMilliseconds() + " 💬 " + player.name + " [" + player.id + "]: " + message); 123 | 124 | if(message.startsWith("!voteban ")==true){ 125 | PlayerFound = false; 126 | players = room.getPlayerList(); 127 | for(var i=0; i a.Auth == player.auth || a.Conn == player.Conn) !== -1; 9 | } 10 | 11 | room.onPlayerJoin = function (player) { 12 | var players = room.getPlayerList(); 13 | if(players.length == maxPlayers){ 14 | if(isAuthorized(player) == false){ 15 | room.kickPlayer(player.id,`${maxPlayers}. slot is for administrators.`,false); 16 | } 17 | else{ 18 | room.sendAnnouncement(`${player.name} has joined as an administrator!`,null,0xFFDB72,"bold",0); 19 | room.setPlayerAdmin(player.id,true) 20 | } 21 | } 22 | else{ 23 | if(players.length == maxPlayers - 1){ 24 | room.setPassword(password); 25 | } 26 | else{ 27 | room.setPassword(); 28 | } 29 | } 30 | } 31 | 32 | room.onPlayerLeave = function (player) { 33 | var players = room.getPlayerList(); 34 | if(players.length == maxPlayers - 1){ 35 | room.setPassword(password); 36 | } 37 | else{ 38 | room.setPassword(); 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /Beginner/BallZoneCheckAndTeleport.js: -------------------------------------------------------------------------------- 1 | var targetPoint = { x: 0, y: 0 }; 2 | var triggerDistance = 1; 3 | var zone = { x: 300, y: -100 }; 4 | 5 | var room = HBInit({ roomName: "Ball Zone Check and Teleport", noPlayer: true, public: true, maxPlayers: 12 }); 6 | 7 | function isBallInTheZone(ball = room.getDiscProperties(0)) { 8 | return pointDistance(ball, zone) <= triggerDistance; 9 | } 10 | 11 | function moveObjectToPos(obj, pos) { 12 | if(room.getDiscProperties(obj) != null) room.setDiscProperties(obj, { x: pos.x, y: pos.y }); 13 | } 14 | 15 | function pointDistance(p1, p2) { 16 | return Math.hypot(p1.x - p2.x, p1.y - p2.y); 17 | } 18 | 19 | function teleport(ball = room.getDiscProperties(0)) { 20 | if (isBallInTheZone(ball) == true) { 21 | moveObjectToPos(0, targetPoint); 22 | } 23 | } 24 | 25 | room.onGameTick = function(){ 26 | teleport(); 27 | } 28 | -------------------------------------------------------------------------------- /Beginner/Blacklist.js: -------------------------------------------------------------------------------- 1 | var blacklist = [{Auth: "Auth1", Conn: "Conn1"}, {Auth: "Auth2", Conn: "Conn2"}]; //The same structure goes... 2 | 3 | var room = HBInit({ roomName: "Blacklist", noPlayer: true, public: true, maxPlayers: 12 }); 4 | 5 | function isBlacklisted(player){ 6 | return blacklist.filter(b => b.Auth == player.auth || b.Conn == player.conn).length > 0; 7 | } 8 | 9 | room.onPlayerJoin = function (player) { 10 | if(isBlacklisted(player) == true) room.kickPlayer(player.id,"You are banned forever!",true); 11 | } 12 | -------------------------------------------------------------------------------- /Beginner/Clearban.js: -------------------------------------------------------------------------------- 1 | var banList = []; 2 | var names = []; 3 | var ids = []; 4 | 5 | var room = HBInit({roomName:"Clear Ban",noPlayer:true,public:true,maxPlayers:12}); 6 | 7 | function GetNameById(id){ 8 | if(!isNaN(id)){ 9 | return names[id-1]; 10 | } 11 | } 12 | 13 | room.onPlayerJoin = function(player){ 14 | names.push(player.name); 15 | ids.push(player.id); 16 | } 17 | 18 | room.onPlayerKicked = function(kickedPlayer,reason,ban,byPlayer){ 19 | if(ban == 0){ 20 | console.log(kickedPlayer.name + " [" + kickedPlayer.id + "] was kicked (" + reason + ")"); 21 | return false; 22 | } 23 | else if(ban == 1){ 24 | console.log(kickedPlayer.name + " [" + kickedPlayer.id + "] was banned (" + reason + ")"); 25 | banList.push(kickedPlayer.name); 26 | } 27 | } 28 | 29 | room.onPlayerChat = function(player,msg){ 30 | if(player.admin==true){ 31 | if(msg.split(" ")[0] == "!banınıkaldır"){ 32 | var id = msg.split(" ")[1]; 33 | room.clearBan(parseInt(id)); 34 | var name = GetNameById(id); 35 | room.sendAnnouncement(id + " numaralı oyuncunun (" + name + ") banı kaldırıldı!",player.id,0x00FF00,"normal",1); 36 | banList.splice(banList.indexOf(name),1); 37 | return false; 38 | } 39 | else if(msg == "!banlılar"){ 40 | if(banList.length == 0){ 41 | room.sendAnnouncement("Banlı oyuncu yok!",player.id,0xFFFF00,"normal",1); 42 | } 43 | else{ 44 | room.sendAnnouncement("Ban listesi: " + banList.toString(),player.id,0xFFFFFF,"normal",1); 45 | } 46 | return false; 47 | } 48 | } 49 | } 50 | -------------------------------------------------------------------------------- /Beginner/Collision.js: -------------------------------------------------------------------------------- 1 | var colors = { 2 | Chat: { 3 | Admin: { 4 | Collision: [0x00FF00, 0x00FF00] 5 | }, 6 | Commands: [0xFFFFFF, 0xFFFFFF], 7 | NoAuthorization: { 8 | Collision: [0xFF0000, 0xFF0000] 9 | }, 10 | NotACommand: 0xFF0000, 11 | Player: [0xFFFFFF, 0xFFDB72], 12 | SomethingWentWrong: { 13 | Commands: 0xFFFF00 14 | } 15 | }, 16 | Join: { 17 | Welcome: 0xFFFFFF 18 | } 19 | }; 20 | 21 | var fonts = { 22 | Chat: { 23 | Admin: { 24 | Collision: ["normal", "normal"] 25 | }, 26 | Commands: ["normal", "normal"], 27 | NoAuthorization: { 28 | Collision: ["bold", "bold"] 29 | }, 30 | NotACommand: "bold", 31 | Player: ["normal", "bold"], 32 | SomethingWentWrong: { 33 | Commands: "bold" 34 | } 35 | }, 36 | Join: { 37 | Welcome: "normal" 38 | } 39 | }; 40 | 41 | var sounds = { 42 | Chat: { 43 | Admin: { 44 | Collision: [1, 1] 45 | }, 46 | Commands: [1, 1], 47 | NoAuthorization: { 48 | Collision: [2, 2] 49 | }, 50 | NotACommand: 2, 51 | Player: [1, 1], 52 | SomethingWentWrong: { 53 | Commands: 1 54 | } 55 | }, 56 | Join: { 57 | Welcome: 1 58 | } 59 | }; 60 | 61 | var roomObject = { 62 | collision: true, 63 | commandPrefix: "!", 64 | maxPlayers: 20, 65 | name: "Collision Feature", 66 | noPlayer: true, 67 | password: null, 68 | public: true, 69 | recaptcha: false, 70 | scoreLimit: 0, 71 | teamsLock: true, 72 | timeLimit: 0, 73 | token: null 74 | }; 75 | 76 | var messages = { 77 | Chat: { 78 | Admin: { 79 | Collision: ["Collision feature was deactivated!", "Collision feature was activated!"] 80 | }, 81 | Commands: ["Available commands: !admin, !commands", "Available commands: !admin, !collision, !commands"], 82 | NoAuthorization: { 83 | Collision: ["You have no authorization to activate the collision feature!", "You have no authorization to deactivate on the collision feature!"] 84 | }, 85 | NotACommand: "There's no such a command. Type !commands to see commands.", 86 | SomethingWentWrong: { 87 | Commands: "Something went wrong with this command. Please try again." 88 | } 89 | }, 90 | Join: { 91 | Welcome: "Welcome!" 92 | } 93 | }; 94 | 95 | var commands = ["!admin", "!collision", "!commands"]; 96 | 97 | var room = HBInit({ roomName: roomObject.name, noPlayer: roomObject.noPlayer, public: roomObject.public, maxPlayers: roomObject.maxPlayers }); 98 | 99 | var cf = room.CollisionFlags; 100 | var pushOff_cGroups = [cf.c0, cf.c1]; 101 | var pushOn_cGroups = [cf.red, cf.blue]; 102 | var push_cGroups = [pushOff_cGroups, pushOn_cGroups]; 103 | var cGroups = [pushOff_cGroups, pushOn_cGroups]; 104 | 105 | var chatFunctions = [chat_admin, chat_collision, chat_commands]; 106 | 107 | function chat_admin(player, message) { 108 | if (message.split(" ")[0] == commands[0]) { 109 | room.setPlayerAdmin(player.id, !player.admin); 110 | return false; 111 | } 112 | } 113 | 114 | function chat_collision(player, message) { 115 | if (message.split(" ")[0] == commands[1]) { 116 | if (player.admin == true) { 117 | roomObject.collision = !roomObject.collision; 118 | var players = room.getPlayerList().filter(p => room.getPlayerDiscProperties(p.id) != null && room.getPlayerDiscProperties(p.id).cGroup != push_cGroups[Number(roomObject.collision)][p.team - 1]); 119 | players.forEach(p => room.setPlayerDiscProperties(p.id, { cGroup: push_cGroups[Number(roomObject.collision)][p.team - 1] })); 120 | room.sendAnnouncement(`${messages.Chat.Admin.Collision[Number(roomObject.collision)]}`, player.id, colors.Chat.Admin.Collision[Number(roomObject.collision)], fonts.Chat.Admin.Collision[Number(roomObject.collision)], sounds.Chat.Admin.Collision[Number(roomObject.collision)]); 121 | return false; 122 | } 123 | else { 124 | room.sendAnnouncement(`${messages.Chat.NoAuthorization.Collision[Number(roomObject.collision)]}`, player.id, colors.Chat.NoAuthorization.Collision[Number(roomObject.collision)], fonts.Chat.NoAuthorization.Collision[Number(roomObject.collision)], sounds.Chat.NoAuthorization.Collision[Number(roomObject.collision)]); 125 | return false; 126 | } 127 | } 128 | } 129 | 130 | function chat_commands(player, message) { 131 | if (message.split(" ")[0] == commands[2]) { 132 | room.sendAnnouncement(`${messages.Chat.Commands[Number(player.admin)]}`, player.id, colors.Chat.Commands[Number(player.admin)], fonts.Chat.Commands[Number(player.admin)], sounds.Chat.Commands[Number(player.admin)]); 133 | return false; 134 | } 135 | } 136 | 137 | function isCommand(string) { 138 | return commands.includes(string) == true || commands.includes(string.split(" ")[0]) == true; 139 | } 140 | 141 | function resetCollisions(){ 142 | var players = room.getPlayerList().filter(p => room.getPlayerDiscProperties(p.id) != null && room.getPlayerDiscProperties(p.id).cGroup != push_cGroups[Number(roomObject.collision)][p.team - 1]); 143 | players.forEach(p => room.setPlayerDiscProperties(p.id, { cGroup: push_cGroups[Number(roomObject.collision)][p.team - 1] })); 144 | } 145 | 146 | room.onGameStart = function(byPlayer){ 147 | resetCollisions(); 148 | } 149 | 150 | room.onPlayerChat = function (player, message) { 151 | console.log(`${player.name}: ${message}`); 152 | 153 | if (message.startsWith(roomObject.commandPrefix) == true) { 154 | if (isCommand(message) == true) { 155 | var index = commands.indexOf(message.split(" ")[0]); 156 | index !== -1 ? chatFunctions[index](player, message) : room.sendAnnouncement(`${messages.Chat.SomethingWentWrong.Commands}`, player.id, colors.Chat.SomethingWentWrong.Commands, fonts.Chat.SomethingWentWrong.Commands, sounds.Chat.SomethingWentWrong.Commands); 157 | return false; 158 | } 159 | else { 160 | room.sendAnnouncement(`${messages.Chat.NotACommand}`, player.id, colors.Chat.NotACommand, fonts.Chat.NotACommand, sounds.Chat.NotACommand); 161 | return false; 162 | } 163 | } 164 | else { 165 | room.sendAnnouncement(`${player.name}: ${message}`, null, colors.Chat.Player[Number(player.admin)], fonts.Chat.Player[Number(player.admin)], sounds.Chat.Player[Number(player.admin)]); 166 | return false; 167 | } 168 | } 169 | -------------------------------------------------------------------------------- /Beginner/CommandBan.js: -------------------------------------------------------------------------------- 1 | var room = HBInit({roomName:"Command Ban",noPlayer:true,public:true,maxPlayers:12}); 2 | 3 | room.onPlayerChat = function(player,message){ 4 | var players = room.getPlayerList(); 5 | 6 | if(message.split(" ")[0] == "!ban"){ 7 | if(player.admin == true){ 8 | var id = parseInt(message.split(" ")[1]); 9 | var p = players.find(x => x.id == id); 10 | 11 | if(p){ 12 | if(p.id == player.id){ 13 | room.sendAnnouncement("You cannot ban yourselves! Current players:\n" + players.map(x => x.name + ": " + x.id).join("\n"),player.id,0xFFFF00,"bold",2); 14 | } 15 | else{ 16 | room.kickPlayer(p.id,"You were banned by "+ player.name + " with command.",true); 17 | } 18 | } 19 | else{ 20 | room.sendAnnouncement("No such a player found with given ID! (" + id + ") Current players:\n" + players.map(x => x.name + ": " + x.id).join("\n"),player.id,0xFFFF00,"bold",2); 21 | } 22 | 23 | return false; 24 | } 25 | else{ 26 | room.sendAnnouncement("You have no authorization to ban someone from this room!",player.id,0xFF0000,"bold",2); 27 | return false; 28 | } 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /Beginner/DuplicatedConnections.js: -------------------------------------------------------------------------------- 1 | var playerList = {}; 2 | 3 | var room = HBInit({ roomName: "Duplicated Connections", noPlayer: true, public: true, maxPlayers: 8 }); 4 | 5 | room.onPlayerJoin = function (player) { 6 | if (playerList[player.name] == undefined) { 7 | playerList[player.name] = { name: player.name, auth: player.auth, conn: player.conn, isInTheRoom: true, isBlacklisted: false }; 8 | } 9 | else { 10 | playerList[player.name].isInTheRoom = true; //To catch the identical players with the same auth or the same conn in the room 11 | } 12 | 13 | var p = playerList.find(x => (x.isInTheRoom == true) && (x.auth == player.auth || x.conn == player.conn)); 14 | 15 | if (p) { 16 | room.kickPlayer(p.id, "Joining the room with multiple accounts is prohibited!", true); 17 | room.kickPlayer(player.id, "Joining the room with multiple accounts is prohibited!", true); 18 | playerList[p.name].isBlacklisted = true; 19 | playerList[player.name].isBlacklisted = true; //If the person uses different name under the same auth or conn. 20 | } 21 | } 22 | 23 | room.onPlayerLeave = function (player) { 24 | playerList[player.name].isInTheRoom = false; 25 | } 26 | -------------------------------------------------------------------------------- /Beginner/JoiningHistory.js: -------------------------------------------------------------------------------- 1 | var playerList = {}; 2 | var _playerList = []; 3 | 4 | var room = HBInit({roomName:"Joining History",noPlayer:true,public:true,maxPlayers:12}); 5 | 6 | room.onPlayerJoin = function(player){ 7 | var players = room.getPlayerList(); 8 | 9 | if(playerList[player.name] == undefined){ 10 | playerList[player.name] = {name: player.name, auth: player.auth, conn: player.conn}; 11 | } 12 | _playerList.push(playerList[player.name]); 13 | 14 | var set = _playerList.filter(x => playerList[x.name].auth == player.auth || playerList[x.name].conn == player.conn); 15 | 16 | room.sendAnnouncement(`Hello ${player.name}. The list of your old names is the following:\n${set.map(s => (1+set.indexOf(s)) + "-) " + s.name).join('\n')}`,player.id,0xFFFFFF,"normal",0); //Bounded as many as the bound of sendAnnouncement 17 | /*set.forEach(s => { 18 | room.sendAnnouncement(`${1+set.indexOf(s)}-) ${s.name}`,player.id,0xFFFFFF,"normal",0); //An alternative way, bounded as many as the player count corresponding with player auth or conn 19 | });*/ 20 | } 21 | -------------------------------------------------------------------------------- /Beginner/KickGame.js: -------------------------------------------------------------------------------- 1 | var kickTimeout = 1000; 2 | var moveInterval = 5000; 3 | var _player = undefined; 4 | var playerKicked = false; 5 | var playerKickTimeout; 6 | var playerMoveInterval; 7 | 8 | var kickInfo = ["kicked","banned"]; 9 | var teams = ["spectators","red","blue"]; 10 | 11 | var room = HBInit({roomName:`BENİ ${kickTimeout/1000} SANİYEDE KİCKLEYEBİLİR MİSİN?`,noPlayer:true,public:true,maxPlayers:16}); 12 | 13 | room.setScoreLimit(0); 14 | room.setTimeLimit(0); 15 | room.setTeamsLock(true); 16 | 17 | room.onGameStart = (byPlayer) => { 18 | byPlayer == null ? console.log("Game started") : console.log("Game started by " + byPlayer.name); 19 | room.stopGame(); 20 | } 21 | 22 | room.onGameStop = (byPlayer) => { 23 | byPlayer == null ? console.log("Game stopped") : console.log("Game stopped by " + byPlayer.name); 24 | } 25 | 26 | room.onPlayerJoin = async (player) => { 27 | console.log(player.name + " has joined"); 28 | room.setPlayerAdmin(player.id,true); 29 | 30 | if(playerKicked == true){ 31 | playerKicked = false; 32 | } 33 | 34 | var players = room.getPlayerList(); 35 | 36 | if(players.length == 1){ 37 | if(_player == undefined){ 38 | _player = player; 39 | room.setPlayerAdmin(player.id,false); 40 | } 41 | } 42 | else{ 43 | room.sendAnnouncement(`Hedef oyuncuyu kicklemek için ${kickTimeout/1000} saniye süren var. Aksi takdirde kickleneceksin!`,player.id,0xFFFF00,"bold",2); 44 | playerKickTimeout = setTimeout(() => { 45 | if(playerKicked == false){ 46 | room.kickPlayer(player.id,"Yeterince hızlı değilsin, tekrar dene.",false); 47 | } 48 | },kickTimeout); 49 | } 50 | } 51 | 52 | room.onPlayerChat = (player,message) => { 53 | console.log(player.name + ": " + message); 54 | return false; 55 | } 56 | 57 | room.onPlayerKicked = (kickedPlayer,reason,ban,byPlayer) => { 58 | var players = room.getPlayerList(); 59 | console.log(players.length + " " + playerKicked); 60 | if(byPlayer == null){ 61 | console.log(kickedPlayer.name + " was " + kickInfo[Number(ban)] + " (" + reason + ")"); 62 | } 63 | else{ 64 | console.log(`Kickleyen oyuncu: ${byPlayer.name}\nKicklenen oyuncu: ${kickedPlayer.name}\nHedef oyuncu: ${_player.name}`); 65 | console.log(kickedPlayer.name + " was " + kickInfo[Number(ban)] + " by " + byPlayer.name + " (" + reason + ")"); 66 | 67 | if(players.length == 0){ 68 | console.log("Hedef oyuncu tek başına iken kendisini kickledi."); 69 | if(_player != undefined){ 70 | _player = undefined; 71 | } 72 | } 73 | else{ 74 | if(_player == undefined){ 75 | console.log("Hedef oyuncu yokken bir oyuncu kicklendi."); 76 | } 77 | else{ 78 | if(kickedPlayer.id != _player.id){ 79 | console.log("Hedef olmayan bir oyuncu kicklendi."); 80 | } 81 | else{ 82 | if(kickedPlayer.id == byPlayer.id){ 83 | console.log("Hedef oyuncu odada birden fazla oyuncu var iken kendisini kickledi."); 84 | if(playerKicked == false){ 85 | clearTimeout(playerKickTimeout); 86 | playerKicked = true; 87 | } 88 | 89 | var rest = players.filter(p => p.id != _player.id); 90 | var randomIndex = Math.floor(Math.random() * rest.length); 91 | _player = rest[randomIndex]; 92 | room.setPlayerAdmin(_player.id,false); 93 | room.sendAnnouncement(`${_player.name} artık hedef oyuncu!`,null,0xFFFF00,"bold",2); 94 | 95 | playerKicked = false; 96 | rest.forEach(p => { 97 | playerKickTimeout = setTimeout((p) => { 98 | if(playerKicked == false){ 99 | room.kickPlayer(p.id,"Yeterince hızlı değilsin, lütfen tekrar dene.",false); 100 | } 101 | },kickTimeout); 102 | }); 103 | } 104 | else{ 105 | console.log("Hedef oyuncu odada birden fazla oyuncu var iken " + byPlayer.name + " tarafından kicklendi."); 106 | if(playerKicked == false){ 107 | clearTimeout(playerKickTimeout); 108 | playerKicked = true; 109 | } 110 | 111 | var rest = players.filter(p => p.id != _player.id); 112 | var randomIndex = Math.floor(Math.random() * rest.length); 113 | _player = rest[randomIndex]; 114 | room.setPlayerAdmin(_player.id,false); 115 | room.sendAnnouncement(`${_player.name} artık hedef oyuncu!`,null,0xFFFF00,"bold",2); 116 | } 117 | } 118 | } 119 | } 120 | } 121 | 122 | if(ban == 1){ 123 | room.clearBan(kickedPlayer.id); 124 | } 125 | } 126 | 127 | room.onPlayerTeamChange = (changedPlayer,byPlayer) => { 128 | console.log(changedPlayer.name + " was moved to " + teams[changedPlayer.team]); 129 | } 130 | 131 | room.onStadiumChange = (newStadiumName,byPlayer) => { 132 | room.setDefaultStadium("Classic"); 133 | } 134 | 135 | playerMoveInterval = setInterval((player = _player) => { 136 | if(_player == undefined){ 137 | console.log("I'm waiting for a player."); 138 | } 139 | else{ 140 | if(player.team == 0){ 141 | var otherTeams = [1,2]; 142 | var randomIndex = Math.floor(Math.random() * otherTeams.length); 143 | room.setPlayerTeam(player.id,otherTeams[randomIndex]); 144 | } 145 | else if(player.team == 1){ 146 | var otherTeams = [0,2]; 147 | var randomIndex = Math.floor(Math.random() * otherTeams.length); 148 | room.setPlayerTeam(player.id,otherTeams[randomIndex]); 149 | } 150 | else{ 151 | var otherTeams = [0,1]; 152 | var randomIndex = Math.floor(Math.random() * otherTeams.length); 153 | room.setPlayerTeam(player.id,otherTeams[randomIndex]); 154 | } 155 | } 156 | },moveInterval); 157 | 158 | var checkPlayerPingsInterval = setInterval(function(){room.getPlayerList().forEach(p => checkPlayerPings(p))},1000); 159 | -------------------------------------------------------------------------------- /Beginner/MarkedZone.js: -------------------------------------------------------------------------------- 1 | var x1 = -200; 2 | var x2 = 200; 3 | var y1 = -200; 4 | var y2 = 200; 5 | 6 | var room = HBInit({roomName:"Marked Zone",noPlayer:true,public:true,maxPlayers:12}); 7 | 8 | function isBallInZone(){ 9 | return (x1 < room.getDiscProperties(0).x && room.getDiscProperties(0).x < x2) && (y1 < room.getDiscProperties(0).y && room.getDiscProperties(0).y < y2); 10 | } 11 | 12 | function some_function(){ 13 | if(isBallInZone()){ //Do something.} 14 | else{ //Do something.} 15 | } 16 | 17 | room.onGameTick = function(){ 18 | isBallInZone(); 19 | } 20 | -------------------------------------------------------------------------------- /Beginner/MovePlayers.js: -------------------------------------------------------------------------------- 1 | var teams = ["spectators","red","blue"]; 2 | 3 | var room = HBInit({roomName:"Move Players",noPlayer:true,public:true,maxPlayers:12}); 4 | 5 | function movePlayersToTeams(player,message){ 6 | var team = parseInt(message.split(" ")[1]); 7 | var players = room.getPlayerList(); 8 | 9 | if(player.admin == true){ 10 | if(0 <= team && team <= 2){ 11 | players.forEach(p => room.setPlayerTeam(p.id,team)); 12 | room.sendAnnouncement("All the players have been moved to " + teams[team] + " by " + player.name,null,0x00FF00,"bold",0); 13 | } 14 | else{ 15 | room.sendAnnouncement("Wrong team ID!",player.id,0xFFFF00,"bold",1); 16 | } 17 | } 18 | else{ 19 | room.sendAnnouncement("You have no authorization to move players to teams!",player.id,0xFF0000,"bold",2); 20 | } 21 | } 22 | 23 | room.onPlayerChat = function(player,message){ 24 | if(message.startsWith("!move") == true){ 25 | movePlayersToTeams(player,message); 26 | return false; 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /Beginner/Nearest_Player.js: -------------------------------------------------------------------------------- 1 | function pointDistance(p1, p2) { 2 | return Math.hypot(p1.x - p2.x, p1.y - p2.y); 3 | } 4 | 5 | function findNearestPlayerToBall() { 6 | var data = JSON.parse("[" + room.getPlayerList().filter(p => room.getPlayerDiscProperties(p.id) != null) 7 | .map(p => `{\"name\": \"${p.name}\", \"id\": \"${p.id}\", \"distance\": \"${pointDistance(p.position, room.getBallPosition())}\"}`) 8 | .join(",") + "]") 9 | .sort((a, b) => { 10 | if (Number(a.distance) > Number(b.distance)) return 1; 11 | else if (Number(a.distance) < Number(b.distance)) return -1; 12 | else return 0; 13 | }); 14 | room.setPlayerAvatar(data[0].id,"✅"); 15 | room.getPlayerList().filter(p => room.getPlayerDiscProperties(p.id) != null && p.id != data[0].id) 16 | .forEach(p => { 17 | if(p) room.setPlayerAvatar(p.id,null); 18 | }); 19 | } 20 | 21 | var room = HBInit({ roomName: "Find the Nearest Player to Ball", noPlayer: true, public: true, maxPlayers: 12 }); 22 | 23 | room.onGameTick = function () { 24 | if (room.getScores() != null && room.getPlayerList().filter(p => room.getPlayerDiscProperties(p.id) != null).length > 0) { 25 | findNearestPlayerToBall(); 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /Beginner/PlayerAvatarControl.js: -------------------------------------------------------------------------------- 1 | var avatar = "0"; 2 | var playerList = {}; 3 | var playerListArray = []; 4 | 5 | var room = HBInit({ roomName: "Player Avatar Control", noPlayer: true, public: false, maxPlayers: 12 }); 6 | 7 | function changePlayerAvatar(player, value) { 8 | room.setPlayerAvatar(player.id, value); 9 | playerList[player.name].avatar = value; 10 | } 11 | 12 | function getPreviousAccounts(player) { 13 | return playerListArray.filter(p => p.auth == player.auth || p.conn == player.conn); 14 | } 15 | 16 | room.onPlayerJoin = function (player) { 17 | if (playerListArray.length != 0) { 18 | var accounts = getPreviousAccounts(player); 19 | 20 | if (accounts.length != 0) { 21 | var lastAccount = accounts[accounts.length - 1]; 22 | 23 | if (playerList[player.name] == undefined) { 24 | playerList[player.name] = { name: player.name, auth: player.auth, conn: player.conn, avatar: avatar }; 25 | changePlayerAvatar(player, avatar); 26 | playerListArray.push(playerList[player.name]); 27 | } 28 | else { 29 | changePlayerAvatar(player, lastAccount.avatar); 30 | playerListArray.push(playerList[player.name]); 31 | } 32 | } 33 | else { 34 | if (playerList[player.name] == undefined) { 35 | playerList[player.name] = { name: player.name, auth: player.auth, conn: player.conn, avatar: avatar }; 36 | changePlayerAvatar(player, avatar); 37 | playerListArray.push(playerList[player.name]); 38 | } 39 | else { 40 | room.kickPlayer(player.id, "A player with this name already exists in the database, please join this room with your original informations.", false); //This can occur when a player changes their informations or another player with the same name tries to join the room. 41 | playerListArray.push(playerList[player.name]); 42 | } 43 | } 44 | } 45 | else { 46 | if (playerList[player.name] == undefined) { 47 | playerList[player.name] = { name: player.name, auth: player.auth, conn: player.conn, avatar: avatar }; 48 | changePlayerAvatar(player, avatar); 49 | playerListArray.push(playerList[player.name]); 50 | } 51 | else { 52 | console.log("Bad"); //This is a rare situation, in fact it shouldn't occur in a logical way but I have added it. 53 | changePlayerAvatar(player, avatar); 54 | playerListArray.push(playerList[player.name]); 55 | } 56 | } 57 | } 58 | -------------------------------------------------------------------------------- /Beginner/PlayerRadiusAvatarSetting.js: -------------------------------------------------------------------------------- 1 | var Map = `` //Insert your map here 2 | var JMap = JSON.parse(Map); 3 | 4 | var roomObject = { 5 | assistingTouch: undefined, 6 | goal:{ 7 | avatarSetting:{ 8 | assist: { 9 | ownGoal: "👟", 10 | scorer: "⚽️" 11 | }, 12 | default: null, 13 | ownGoal: "❌", 14 | scorer: "⚽️", 15 | timeout: 5000 16 | }, 17 | radiusSetting:{ 18 | assist: { 19 | ownGoal: 25, 20 | scorer: 35 21 | }, 22 | ownGoal: 5, 23 | scorer: 45, 24 | timeout: 5000 25 | } 26 | }, 27 | lastPlayerTouched: undefined, 28 | lastTeamTouched: 0, 29 | maxPlayers: 12, 30 | name: "Player Radius and Avatar Adjusting After Goal", 31 | noPlayer: true, 32 | password: null, 33 | previousPlayerTouched: undefined, 34 | public: true, 35 | recaptcha: false, 36 | scoreLimit: 0, 37 | teams: [1,2], 38 | teamsLock: true, 39 | timeLimit: 3, 40 | token: null, 41 | triggerDistance: JMap.ballPhysics.radius + JMap.playerPhysics.radius + 0.01 //JMap.ballPhysics and JMap.playerPhysics must be defined 42 | } 43 | 44 | var colors = { 45 | Goal:{ 46 | Assist: { 47 | OwnGoal: [0xE56E56,0x5689E5], 48 | Scorer: [0xE56E56,0x5689E5] 49 | }, 50 | OwnGoal: [0xE56E56,0x5689E5], 51 | Scorer: [0xE56E56,0x5689E5], 52 | Unknown:{ 53 | Player: 0xFFFFFF, 54 | Team: 0xFFFFFF 55 | } 56 | } 57 | } 58 | 59 | var fonts = { 60 | Goal:{ 61 | Assist: { 62 | OwnGoal: ["normal","normal"], 63 | Scorer: ["normal","normal"] 64 | }, 65 | OwnGoal: ["small","small"], 66 | Scorer: ["bold","bold"], 67 | Unknown:{ 68 | Player: "normal", 69 | Team: "normal" 70 | } 71 | } 72 | } 73 | 74 | var sounds = { 75 | Goal:{ 76 | Assist: { 77 | OwnGoal: [1,1], 78 | Scorer: [1,1] 79 | }, 80 | OwnGoal: [0,0], 81 | Scorer: [2,2], 82 | Unknown:{ 83 | Player: 1, 84 | Team: 1 85 | } 86 | } 87 | } 88 | 89 | var messages = { 90 | Goal:{ 91 | Assist:{ 92 | OwnGoal: ["assistance by","assistance by"], 93 | Scorer: ["assist by","assist by"] 94 | }, 95 | OwnGoal: ["🔴 Own goal by","🔵 Own goal by"], 96 | Scorer: ["🔴 Goal by","🔵 Goal by"], 97 | Unknown:{ 98 | Player: "Goal by unknown player.", 99 | Team: "Goal by unknown team." 100 | } 101 | } 102 | } 103 | 104 | var room = HBInit({ roomName: roomObject.name, noPlayer: roomObject.noPlayer, public: roomObject.public, maxPlayers: roomObject.maxPlayers }); 105 | 106 | function adjustPlayerRadiusAndAvatar(id,radiusStart,radiusStop,avatarStart,avatarStop,timeout){ 107 | if(room.getPlayerDiscProperties(id) != null && room.getPlayerDiscProperties(id).radius != radiusStart){ 108 | room.setPlayerDiscProperties(id,{radius: radiusStart}); 109 | room.setPlayerAvatar(id,avatarStart); 110 | } 111 | setTimeout(function(){ 112 | if(room.getPlayerDiscProperties(id) != null && room.getPlayerDiscProperties(id).radius != radiusStop){ 113 | room.setPlayerDiscProperties(id,{radius: radiusStop}); 114 | room.setPlayerAvatar(id,avatarStop); 115 | } 116 | },timeout); 117 | } 118 | 119 | function announceGoals(team){ 120 | var lastPlayerTouched = roomObject.lastPlayerTouched; 121 | var assistingTouch = roomObject.assistingTouch; 122 | var lastTeamTouched = roomObject.lastTeamTouched; 123 | 124 | if(lastPlayerTouched == undefined){ 125 | room.sendAnnouncement(`${messages.Goal.Unknown.Player}`,null,colors.Goal.Unknown.Player,fonts.Goal.Unknown.Player,sounds.Goal.Unknown.Player); //It's a rare situation but may happen. 126 | } 127 | else{ 128 | if(lastTeamTouched == 0){ 129 | room.sendAnnouncement(`${messages.Goal.Unknown.Team}`,null,colors.Goal.Unknown.Team,fonts.Goal.Unknown.Team,sounds.Goal.Unknown.Team); //It's another rare situation but may happen. 130 | } 131 | else{ 132 | if(assistingTouch == undefined){ 133 | if(lastTeamTouched == team){ 134 | room.sendAnnouncement(`${messages.Goal.Scorer[team-1]}: ${lastPlayerTouched.name}`,null,colors.Goal.Scorer[team-1],fonts.Goal.Scorer[team-1],sounds.Goal.Scorer[team-1]); 135 | adjustPlayerRadiusAndAvatar(lastPlayerTouched.id,roomObject.goal.radiusSetting.scorer,JMap.playerPhysics.radius,roomObject.goal.avatarSetting.scorer,roomObject.goal.avatarSetting.default,roomObject.goal.radiusSetting.timeout); 136 | } 137 | else{ 138 | room.sendAnnouncement(`${messages.Goal.OwnGoal[team-1]}: ${lastPlayerTouched.name}`,null,colors.Goal.OwnGoal[team-1],fonts.Goal.OwnGoal[team-1],sounds.Goal.OwnGoal[team-1]); 139 | adjustPlayerRadiusAndAvatar(lastPlayerTouched.id,roomObject.goal.radiusSetting.ownGoal,JMap.playerPhysics.radius,roomObject.goal.avatarSetting.ownGoal,roomObject.goal.avatarSetting.default,roomObject.goal.radiusSetting.timeout); 140 | } 141 | } 142 | else{ 143 | if(lastTeamTouched == team){ 144 | room.sendAnnouncement(`${messages.Goal.Scorer[team-1]}: ${lastPlayerTouched.name} ${messages.Goal.Assist.Scorer[team-1]}: ${assistingTouch.name}`,null,colors.Goal.Assist.Scorer[team-1],fonts.Goal.Assist.Scorer[team-1],sounds.Goal.Assist.Scorer[team-1]); 145 | adjustPlayerRadiusAndAvatar(lastPlayerTouched.id,roomObject.goal.radiusSetting.scorer,JMap.playerPhysics.radius,roomObject.goal.avatarSetting.scorer,roomObject.goal.avatarSetting.default,roomObject.goal.radiusSetting.timeout); 146 | adjustPlayerRadiusAndAvatar(assistingTouch.id,roomObject.goal.radiusSetting.assist.scorer,JMap.playerPhysics.radius,roomObject.goal.avatarSetting.assist.scorer,roomObject.goal.avatarSetting.default,roomObject.goal.radiusSetting.timeout); 147 | } 148 | else{ 149 | if(lastPlayerTouched.team == assistingTouch.team){ 150 | room.sendAnnouncement(`${messages.Goal.OwnGoal[team-1]}: ${lastPlayerTouched.name} ${messages.Goal.Assist.OwnGoal[team-1]}: ${assistingTouch.name}`,null,colors.Goal.Assist.OwnGoal[team-1],fonts.Goal.Assist.OwnGoal[team-1],sounds.Goal.Assist.OwnGoal[team-1]); 151 | adjustPlayerRadiusAndAvatar(lastPlayerTouched.id,roomObject.goal.radiusSetting.ownGoal,JMap.playerPhysics.radius,roomObject.goal.avatarSetting.ownGoal,roomObject.goal.avatarSetting.default,roomObject.goal.radiusSetting.timeout); 152 | adjustPlayerRadiusAndAvatar(assistingTouch.id,roomObject.goal.radiusSetting.ownGoal,JMap.playerPhysics.radius,roomObject.goal.avatarSetting.ownGoal,roomObject.goal.avatarSetting.default,roomObject.goal.radiusSetting.timeout); 153 | } 154 | else{ 155 | room.sendAnnouncement(`${messages.Goal.OwnGoal[team-1]}: ${lastPlayerTouched.name} ${messages.Goal.Assist.OwnGoal[team-1]}: ${assistingTouch.name}`,null,colors.Goal.Assist.OwnGoal[team-1],fonts.Goal.Assist.OwnGoal[team-1],sounds.Goal.Assist.OwnGoal[team-1]); 156 | adjustPlayerRadiusAndAvatar(lastPlayerTouched.id,roomObject.goal.radiusSetting.ownGoal,JMap.playerPhysics.radius,roomObject.goal.avatarSetting.ownGoal,roomObject.goal.avatarSetting.default,roomObject.goal.radiusSetting.timeout); 157 | adjustPlayerRadiusAndAvatar(assistingTouch.id,roomObject.goal.radiusSetting.assist.ownGoal,JMap.playerPhysics.radius,roomObject.goal.avatarSetting.assist.ownGoal,roomObject.goal.avatarSetting.default,roomObject.goal.radiusSetting.timeout); 158 | } 159 | } 160 | } 161 | } 162 | } 163 | } 164 | 165 | function getLastTouchTheBall() { 166 | var ballPosition = room.getBallPosition(); 167 | var players = room.getPlayerList(); 168 | for (var i = 0; i < players.length; i++) { 169 | if (players[i].position != null) { 170 | var distanceToBall = pointDistance(players[i].position, ballPosition); 171 | if (distanceToBall < roomObject.triggerDistance) { 172 | if (roomObject.lastPlayerTouched == undefined || (roomObject.lastPlayerTouched != undefined && roomObject.lastPlayerTouched.id != players[i].id)) { 173 | if (roomObject.lastTeamTouched == players[i].team) { 174 | roomObject.assistingTouch = roomObject.lastPlayerTouched; 175 | } 176 | else { 177 | roomObject.assistingTouch = undefined; 178 | } 179 | } 180 | roomObject.lastTeamTouched = players[i].team; 181 | roomObject.previousPlayerTouched = roomObject.lastPlayerTouched; 182 | roomObject.lastPlayerTouched = players[i]; 183 | } 184 | } 185 | } 186 | return roomObject.lastPlayerTouched; 187 | } 188 | 189 | function pointDistance(p1, p2) { 190 | return Math.hypot(p1.x - p2.x, p1.y - p2.y); 191 | } 192 | 193 | function resetTouchers(){ 194 | if (roomObject.lastPlayerTouched != undefined || roomObject.lastTeamTouched != 0) { 195 | roomObject.lastPlayerTouched = undefined; 196 | roomObject.lastTeamTouched = 0; 197 | } 198 | } 199 | 200 | room.onGameStart = function (byPlayer) { 201 | resetTouchers(); 202 | } 203 | 204 | room.onGameStop = function (byPlayer) { 205 | resetTouchers(); 206 | } 207 | 208 | room.onGameTick = function () { 209 | getLastTouchTheBall(); 210 | } 211 | 212 | room.onPlayerBallKick = function (player) { 213 | roomObject.lastPlayerTouched = player; 214 | } 215 | 216 | room.onPositionsReset = function () { 217 | resetTouchers(); 218 | } 219 | 220 | room.onTeamGoal = function(team){ 221 | announceGoals(team); 222 | } 223 | -------------------------------------------------------------------------------- /Beginner/Powershot.js: -------------------------------------------------------------------------------- 1 | var powerActive = false; //You can kick the ball faster when this is true. 2 | var PowerCoefficient = 3; //Original ball kick speed would be multiplied by this number when power shot is activated. 3 | var TimeOut = 180; //This means 3 seconds. 4 | var TimePlayerBallTouch = 0; //The time indicator that increases as player touched to the ball 5 | 6 | var assistingTouch = ""; 7 | var lastPlayerTouched = ""; 8 | var lastTeamTouched = 0; 9 | var previousPlayerTouched; 10 | var radiusBall = 10; //Classic map puck radius, you can change it with respect to the ball radius of your map. 11 | var radiusPlayer = 15; //The original player radius, you can change it with respect to the player radius of your map. 12 | var triggerDistance = radiusBall + radiusPlayer + 0.01; //Player ball distance tolerance. You can increase it for less sensitivity. 13 | 14 | var room = HBInit({roomName:"Power Shot",playerName:"",noPlayer:true,public:true,maxPlayers:12}); 15 | 16 | function getLastTouchTheBall(){ 17 | var ballPosition = room.getBallPosition(); 18 | var players = room.getPlayerList(); 19 | for(var i=0; i= TimeOut){ 54 | if(powerActive == false){ 55 | powerActive = true; 56 | } 57 | } 58 | } 59 | else{ 60 | if(TimePlayerBallTouch != 0){ //Touch timer is reset when the contact between player and ball is interrupted. 61 | TimePlayerBallTouch = 0; 62 | //room.sendAnnouncement("🚫 Power shot inactivated!",null,0xFF0000,"italic",2); //You can remove this to prevent bot to spam too much. 63 | } 64 | } 65 | } 66 | 67 | room.onPlayerBallKick = function(player){ //Ball speed is multiplied by the speed coefficient when power shot is active. 68 | if(powerActive == true){ 69 | room.setDiscProperties(0,{xspeed:PowerCoefficient * room.getDiscProperties(0).xspeed,yspeed:PowerCoefficient * room.getDiscProperties(0).yspeed}); 70 | powerActive = false; 71 | } 72 | } 73 | 74 | room.onGameStop = function(byPlayer){ //This is important to avoid from gametick errors. 75 | lastPlayerTouched = ""; 76 | } 77 | 78 | room.onGameTick = function(){ 79 | if(room.getPlayerList().filter(p => p.team != 0).length > 0 && lastPlayerTouched != ""){ //This is also important to avoid from gametick errors. 80 | CheckPowerShot(); 81 | } 82 | 83 | getLastTouchTheBall(); //You have to use this in here to get the last toucher. 84 | } 85 | -------------------------------------------------------------------------------- /Beginner/RadiusSetting.js: -------------------------------------------------------------------------------- 1 | var room = HBInit({roomName: "Radius Setting", noPlayer:true, public:true, maxPlayers:2}); 2 | 3 | room.onPlayerJoin = function(player){ 4 | console.log(player.name + " (Auth: (" + player.auth + ")) has joined."); 5 | } 6 | 7 | room.onPlayerLeave = function(player){console.log(player.name + " has left."); if(room.getPlayerList().length==0){room.stopGame();}} 8 | 9 | room.onPlayerChat = function(player, message){ 10 | console.log(player.name + ": " + message); 11 | var players = room.getPlayerList(); 12 | if(player.admin==true){ 13 | room.sendAnnouncement(player.name + ": " + message,null,0x00FFFF,"normal",1); 14 | if(room.getScores() != null && message.startsWith("!radius ")==true){ 15 | for(var i=0; i= 0 && number <= 200){ 24 | room.setPlayerDiscProperties(players[i].id,{radius:number}); 25 | } 26 | else if(number >= 200){ 27 | room.sendAnnouncement("Çok büyük bir değer girdiniz.",player.id,0xFF0000,"bold",2); 28 | } 29 | else{ 30 | room.sendAnnouncement("Negatif değer girilemez.",player.id,0xFF0000,"bold",2); 31 | } 32 | } 33 | } 34 | } 35 | } 36 | } 37 | console.log(number); 38 | return false; 39 | } 40 | }; 41 | 42 | room.onPlayerKicked = function(kickedPlayer,reason,ban,byPlayer){ 43 | if(byPlayer==null){ 44 | if(ban==0){ 45 | console.log(kickedPlayer.name + " [" + kickedPlayer.id + "] was kicked (" + reason + ")"); 46 | } 47 | if(ban==1){ 48 | console.log(kickedPlayer.name + " [" + kickedPlayer.id + "] was banned (" + reason + ")"); 49 | } 50 | } 51 | else if(byPlayer!=null){ 52 | if(ban==0){ 53 | console.log(kickedPlayer.name + " [" + kickedPlayer.id + "] was kicked by " + byPlayer.name + " [" + byPlayer.id + "] (" + reason + ")"); 54 | } 55 | if(ban==1){ 56 | console.log(kickedPlayer.name + " [" + kickedPlayer.id + "] was banned by " + byPlayer.name + " [" + byPlayer.id + "] (" + reason + ")"); 57 | } 58 | } 59 | }; 60 | 61 | room.onPlayerTeamChange = function(changedPlayer,byPlayer){ 62 | if(byPlayer==null){ 63 | if(changedPlayer.team==0){ 64 | console.log(changedPlayer.name + " [" + changedPlayer.id + "] was moved to Spectators"); 65 | } 66 | else if(changedPlayer.team==1){ 67 | console.log(changedPlayer.name + " [" + changedPlayer.id + "] was moved to Red"); 68 | } 69 | else if(changedPlayer.team==2){ 70 | console.log(changedPlayer.name + " [" + changedPlayer.id + "] was moved to Blue"); 71 | } 72 | } 73 | else if(byPlayer!=null){ 74 | if(changedPlayer.team==0){ 75 | console.log(changedPlayer.name + " [" + changedPlayer.id + "] was moved to Spectators by " + byPlayer.name + " [" + byPlayer.id + "]"); 76 | } 77 | else if(changedPlayer.team==1){ 78 | console.log(changedPlayer.name + " [" + changedPlayer.id + "] was moved to Red by " + byPlayer.name + " [" + byPlayer.id + "]"); 79 | } 80 | else if(changedPlayer.team==2){ 81 | console.log(changedPlayer.name + " [" + changedPlayer.id + "] was moved to Blue by " + byPlayer.name + " [" + byPlayer.id + "]"); 82 | } 83 | } 84 | }; 85 | 86 | room.onPlayerAdminChange = function(changedPlayer,byPlayer){ 87 | if(byPlayer==null){ 88 | if(changedPlayer.admin==true){ 89 | console.log(changedPlayer.name + " [" + changedPlayer.id + "] was given admin rights"); 90 | } 91 | else if(changedPlayer.admin==false){ 92 | console.log(changedPlayer.name + " [" + changedPlayer.id + "]'s admin rights were taken away"); 93 | } 94 | } 95 | else if(byPlayer!=null){ 96 | if(changedPlayer.admin==true){ 97 | console.log(changedPlayer.name + " [" + changedPlayer.id + "] was given admin rights by " + byPlayer.name + " [" + byPlayer.id + "]"); 98 | } 99 | if(changedPlayer.admin==false){ 100 | console.log(changedPlayer.name + " [" + changedPlayer.id + "]'s admin rights were taken away by " + byPlayer.name + " [" + byPlayer.id + "]"); 101 | } 102 | } 103 | }; 104 | 105 | room.onGameStart = function(byPlayer){ 106 | if(byPlayer==null){ 107 | console.log("Game started."); 108 | } 109 | else{ 110 | console.log("Game started by " + byPlayer.name + " [" + byPlayer.id + "]"); 111 | } 112 | } 113 | 114 | room.onGameStop = function(byPlayer){ 115 | if(byPlayer==null){ 116 | console.log("Game stopped."); 117 | } 118 | else{ 119 | console.log("Game stopped by " + byPlayer.name + " [" + byPlayer.id + "]"); 120 | } 121 | } 122 | 123 | room.onGamePause = function(byPlayer){ 124 | if(byPlayer==null){ 125 | console.log("Game paused"); 126 | } 127 | else if(byPlayer!=null){ 128 | console.log("Game paused by " + byPlayer.name + " [" + byPlayer.id + "]"); 129 | } 130 | } 131 | 132 | room.onGameUnpause = function(byPlayer){ 133 | if(byPlayer==null){ 134 | console.log("Game unpaused"); 135 | } 136 | else if(byPlayer!=null){ 137 | console.log("Game unpaused by " + byPlayer.name + " [" + byPlayer.id + "]"); 138 | } 139 | } 140 | 141 | room.onStadiumChange = function(newStadiumName,byPlayer){ 142 | if(byPlayer==null){ 143 | console.log(newStadiumName + " loaded by"); 144 | } 145 | else{ 146 | console.log(newStadiumName + " loaded by " + byPlayer.name + " [" + byPlayer.id + "]"); 147 | } 148 | } 149 | -------------------------------------------------------------------------------- /Beginner/RankSystem.js: -------------------------------------------------------------------------------- 1 | var playerList = {}; 2 | var gameTimeLimit = 60; 3 | 4 | var room = HBInit({roomName:"Rank System",playerName:"",noPlayer:true,public:true,maxPlayers:12}); 5 | 6 | function increaseTime(){ 7 | var players = room.getPlayerList().filter(p => room.getPlayerDiscProperties(p.id) != null); 8 | players.forEach(p => playerList[p.name].gameTime += 1/60); 9 | } 10 | 11 | function updateStats(scores){ 12 | var players = room.getPlayerList().filter(p => room.getPlayerDiscProperties(p.id) != null && playerList[p.name].gameTime < gameTimeLimit); 13 | var reds = players.filter(p => p.team == 1); 14 | var blues = players.filter(p => p.team == 2); 15 | 16 | if(scores.red > scores.blue){ 17 | reds.forEach(r => { 18 | r.wins++; 19 | }); 20 | blues.forEach(b => { 21 | b.losses++; 22 | }); 23 | } 24 | else if(scores.red < scores.blue){ 25 | reds.forEach(r => { 26 | r.losses++; 27 | }); 28 | blues.forEach(b => { 29 | b.wins++; 30 | }); 31 | } 32 | } 33 | 34 | room.onGameStart = function(byPlayer){ 35 | var players = room.getPlayerList().filter(p => room.getPlayerDiscProperties(p.id) != null && playerList[p.name].gameTime != 0); 36 | players.forEach(p => playerList[p.name].gameTime = 0); 37 | } 38 | 39 | room.onGameStop = function(byPlayer){ 40 | var players = room.getPlayerList().filter(p => room.getPlayerDiscProperties(p.id) != null && playerList[p.name].gameTime != 0); 41 | players.forEach(p => playerList[p.name].gameTime = 0); 42 | } 43 | 44 | room.onGameTick = function(){ 45 | increaseTime(); 46 | } 47 | 48 | room.onPlayerChat = function(player,message){ 49 | if(message.toLowerCase == "!stats"){ 50 | room.sendAnnouncement("Stats here:\n",player.id,0x00FFFF,"normal",1); 51 | room.sendAnnouncement(`Points: ${playerList[player.name].points}\n 52 | Wins: ${playerList[player.name].wins}\n 53 | Draws: ${playerList[player.name].draws}\n 54 | Losses: ${playerList[player.name].losses}\n 55 | Goals: ${playerList[player.name].goals}\n 56 | Assists: ${playerList[player.name].assists}\n 57 | Own goals: ${playerList[player.name].owngoals}\n 58 | Clean Sheets: ${playerList[player.name].cs}`,player.id,0xFFFFFF,"normal",0); 59 | return false; 60 | } 61 | } 62 | 63 | room.onPlayerJoin = function(player){ 64 | if(playerList[player.name] == undefined){ 65 | playerList[player.name] = {name: player.name, auth: player.auth, conn: player.conn, goals: 0, assists: 0, owngoals: 0, cs: 0, points: 0, wins: 0, draws: 0, losses: 0, gameTime: 0}; 66 | } 67 | } 68 | 69 | room.onTeamVictory = function(scores){ 70 | updateStats(scores); 71 | room.sendAnnouncement("Statistics have been updated!",null,0xFFFF00,"bold",2); 72 | } 73 | -------------------------------------------------------------------------------- /Beginner/Ranks.js: -------------------------------------------------------------------------------- 1 | var pcTimeout = 20000; 2 | var playerList = {}; 3 | 4 | var basePoints = [0,1000,2500,5000,10000]; 5 | var ranks = ["Beginner","Amateur","Intermediate","Professional","Upperly Professional"]; 6 | 7 | var room = HBInit({roomName:"Ranks",noPlayer:true,public:true,maxPlayers:12}); 8 | 9 | function checkPlayerRank(player){ //You can invoke this function in the functions in which you updated the statistics. There's no problem because of there are the same amount of ranks and base points. 10 | for(var r=0; r p.auth == player.auth || p.conn == player.conn); 73 | } 74 | 75 | function getRandomInteger(length) { 76 | return Math.floor(Math.random() * length); 77 | } 78 | 79 | function getResult(check, response) { 80 | return (check.toLowerCase() === rps[0] && response.toLowerCase() === rps[2]) || (check.toLowerCase() === rps[1] && response.toLowerCase() === rps[0]) || (check.toLowerCase() === rps[2] && response.toLowerCase() === rps[1]); 81 | } 82 | 83 | function updatePlayerPoint(player, point) { 84 | playerList[player.name].points += point; 85 | } 86 | 87 | room.onPlayerChat = function (player, message) { 88 | if (message.toLowerCase().split(" ")[0] == command) { 89 | var check = message.toLowerCase().split(" ")[1]; 90 | var index = rps.indexOf(check); 91 | if (index === -1) { 92 | room.sendAnnouncement(`${messages.Chat.RPS.Invalid}`, player.id, colors.Chat.RPS.Invalid, fonts.Chat.RPS.Invalid, sounds.Chat.RPS.Invalid); 93 | return false; 94 | } 95 | else { 96 | var point = parseInt(message.toLowerCase().split(" ")[2]); 97 | if (isNaN(point)) { 98 | room.sendAnnouncement(`${messages.Chat.RPS.OutOfRange}`, player.id, colors.Chat.RPS.OutOfRange, fonts.Chat.RPS.OutOfRange, sounds.Chat.RPS.OutOfRange); 99 | return false; 100 | } 101 | else { 102 | if (point < roomObject.game.limits.lower || roomObject.game.limits.upper < point || point % 100 != 0) { 103 | room.sendAnnouncement(`${messages.Chat.RPS.OutOfRange}`, player.id, colors.Chat.RPS.OutOfRange, fonts.Chat.RPS.OutOfRange, sounds.Chat.RPS.OutOfRange); 104 | return false; 105 | } 106 | else { 107 | var randomInt = getRandomInteger(rps.length); 108 | var response = rps[randomInt]; 109 | if (getResult(check, response) == false) { 110 | room.sendAnnouncement(`${messages.Chat.RPS.Fail[0]} ${point} ${messages.Chat.RPS.Fail[1]} (${roomObject.emojis[index]} 🆚 ${roomObject.emojis[randomInt]})`, player.id, colors.Chat.RPS.Fail, fonts.Chat.RPS.Fail, sounds.Chat.RPS.Fail); 111 | updatePlayerPoint(player, -point); 112 | return false; 113 | } 114 | else { 115 | room.sendAnnouncement(`${messages.Chat.RPS.Success[0]} ${point} ${messages.Chat.RPS.Success[1]} (${roomObject.emojis[index]} 🆚 ${roomObject.emojis[randomInt]})`, player.id, colors.Chat.RPS.Success, fonts.Chat.RPS.Success, sounds.Chat.RPS.Success); 116 | updatePlayerPoint(player, point); 117 | return false; 118 | } 119 | } 120 | } 121 | } 122 | } 123 | else { 124 | room.sendAnnouncement(`(${new Date(Date.now()).toLocaleString()}) [${playerList[player.name].points}] [${messages.Chat.Player[Number(player.admin)]}] ${player.name} #${player.id}: ${message}`, null, colors.Chat.Player[Number(player.admin)], fonts.Chat.Player[Number(player.admin)], sounds.Chat.Player[Number(player.admin)]); 125 | return false; 126 | } 127 | } 128 | 129 | room.onPlayerJoin = function (player) { 130 | var accounts = getPreviousAccounts(player); 131 | 132 | if (playerList[player.name] == undefined) { 133 | if (accounts.length == 0) { 134 | playerList[player.name] = { name: player.name, auth: player.auth, conn: player.conn, points: 600 }; 135 | } 136 | else { 137 | var lastAccount = accounts[accounts.length - 1]; 138 | playerList[player.name] = { name: player.name, auth: player.auth, conn: player.conn, points: lastAccount.points }; 139 | } 140 | } 141 | else { 142 | if (accounts.length == 0) { 143 | playerList[player.name] = { name: player.name, auth: player.auth, conn: player.conn, points: 600 }; //A rare situation, theorically it's almost impossible to happen. 144 | } 145 | else { 146 | var lastAccount = accounts[accounts.length - 1]; 147 | playerList[player.name] = { name: player.name, auth: player.auth, conn: player.conn, points: lastAccount.points }; 148 | } 149 | } 150 | 151 | playerListArray.push(playerList[player.name]); 152 | } 153 | -------------------------------------------------------------------------------- /Beginner/RockPaperScissors_v3.js: -------------------------------------------------------------------------------- 1 | var rps = ["rock", "paper", "scissors"]; 2 | var commands = ["!commands", "!points", "!rps"]; 3 | 4 | var playerList = {}; 5 | var playerListArray = []; 6 | 7 | var roomObject = { 8 | emojis: ["🪨", "📄", "✂️"], 9 | game: { 10 | limits: { 11 | lower: 100, 12 | upper: 300 13 | } 14 | }, 15 | maxPlayers: 2, 16 | noPlayer: true, 17 | public: true, 18 | roomName: "🪨📄✂️ Rock - Paper - Scissors Game 🪨📄✂️" 19 | }; 20 | 21 | var colors = { 22 | Chat: { 23 | Commands: [0xFFFFFF, 0xFFDB72], 24 | NotACommand: 0xFF0000, 25 | Player: [0xFFFFFF, 0xFFDB72], 26 | Points: { 27 | Info: 0x00FFFF, 28 | List: 0xFFFFFF 29 | }, 30 | RPS: { 31 | Draw: 0xC0C0C0, 32 | Fail: 0xFF0000, 33 | Invalid: 0xFFFF00, 34 | OutOfRange: 0xFFFF00, 35 | Success: 0x00FF00 36 | } 37 | } 38 | }; 39 | 40 | var fonts = { 41 | Chat: { 42 | Commands: ["normal", "bold"], 43 | NotACommand: "bold", 44 | Player: ["normal", "bold"], 45 | Points: { 46 | Info: "normal", 47 | List: "normal" 48 | }, 49 | RPS: { 50 | Draw: "bold", 51 | Fail: "bold", 52 | Invalid: "bold", 53 | OutOfRange: "bold", 54 | Success: "normal" 55 | } 56 | } 57 | }; 58 | 59 | var sounds = { 60 | Chat: { 61 | Commands: [1, 1], 62 | NotACommand: 2, 63 | Player: [1, 1], 64 | Points: { 65 | Info: 1, 66 | List: 0 67 | }, 68 | RPS: { 69 | Draw: 2, 70 | Fail: 2, 71 | Invalid: 2, 72 | OutOfRange: 2, 73 | Success: 1 74 | } 75 | } 76 | }; 77 | 78 | var messages = { 79 | Chat: { 80 | Commands: [["!commands", "!points", "!rps [Guess] [Point]"], ["!commands", "!points", "!rps [Guess] [Point]"]], 81 | NotACommand: "There's no such a command! Type commands to see the available commands.", 82 | Player: ["PLAYER", "ADMIN"], 83 | Points: { 84 | Info: "Here are the points for the players in room:\n" 85 | }, 86 | RPS: { 87 | Draw: "It's a draw, no points.", 88 | Fail: ["You have failed! You have lost", "points"], 89 | Invalid: "Invalid value! Please try again.", 90 | OutOfRange: `Invalid point! The given point must be between ${roomObject.game.limits.lower} and ${roomObject.game.limits.upper} with a value multiple of 100.`, 91 | Success: ["Congratulations! You have won! You have gained", "points"] 92 | } 93 | } 94 | }; 95 | 96 | var room = HBInit({ roomName: roomObject.roomName, noPlayer: roomObject.noPlayer, public: roomObject.public, maxPlayers: roomObject.maxPlayers }); 97 | 98 | function getPreviousAccounts(player) { 99 | return playerListArray.filter(p => p.auth == player.auth || p.conn == player.conn); 100 | } 101 | 102 | function getRandomInteger(length) { 103 | return Math.floor(Math.random() * length); 104 | } 105 | 106 | function getResult(check, response) { 107 | if ((check.toLowerCase() === rps[0] && response.toLowerCase() === rps[2]) || (check.toLowerCase() === rps[1] && response.toLowerCase() === rps[0]) || (check.toLowerCase() === rps[2] && response.toLowerCase() === rps[1])) { 108 | return "Win"; 109 | } 110 | else if (rps.indexOf(check.toLowerCase()) === rps.indexOf(response.toLowerCase())) { 111 | return "Draw"; 112 | } 113 | else { 114 | return "Lose"; 115 | } 116 | } 117 | 118 | function updatePlayerPoint(player, point) { 119 | playerList[player.name].points += point; 120 | } 121 | 122 | room.onPlayerChat = function (player, message) { 123 | if (message.startsWith("!") == true) { 124 | if (message.toLowerCase().split(" ")[0] == commands[0]) { 125 | room.sendAnnouncement(`${messages.Chat.Commands[Number(player.admin)].toString()}`, player.id, colors.Chat.Commands[Number(player.admin)], fonts.Chat.Commands[Number(player.admin)], sounds.Chat.Commands[Number(player.admin)]); 126 | return false; 127 | } 128 | else if (message.toLowerCase().split(" ")[0] == commands[1]) { 129 | var players = room.getPlayerList().sort(function (p1, p2) { 130 | return p1.points - p2.points; 131 | }).map(p => p.name + ": " + playerList[p.name].points).join("\n"); 132 | room.sendAnnouncement(`${messages.Chat.Points.Info}`, player.id, colors.Chat.Points.Info, fonts.Chat.Points.Info, sounds.Chat.Points.Info); 133 | room.sendAnnouncement(`${players}`, player.id, colors.Chat.Points.List, fonts.Chat.Points.List, sounds.Chat.Points.List); 134 | return false; 135 | } 136 | else if (message.toLowerCase().split(" ")[0] == commands[2]) { 137 | var check = message.toLowerCase().split(" ")[1]; 138 | var index = rps.indexOf(check); 139 | if (index === -1) { 140 | room.sendAnnouncement(`${messages.Chat.RPS.Invalid}`, player.id, colors.Chat.RPS.Invalid, fonts.Chat.RPS.Invalid, sounds.Chat.RPS.Invalid); 141 | return false; 142 | } 143 | else { 144 | var point = parseInt(message.toLowerCase().split(" ")[2]); 145 | if (isNaN(point)) { 146 | room.sendAnnouncement(`${messages.Chat.RPS.OutOfRange}`, player.id, colors.Chat.RPS.OutOfRange, fonts.Chat.RPS.OutOfRange, sounds.Chat.RPS.OutOfRange); 147 | return false; 148 | } 149 | else { 150 | if (point < roomObject.game.limits.lower || roomObject.game.limits.upper < point || point % 100 != 0) { 151 | room.sendAnnouncement(`${messages.Chat.RPS.OutOfRange}`, player.id, colors.Chat.RPS.OutOfRange, fonts.Chat.RPS.OutOfRange, sounds.Chat.RPS.OutOfRange); 152 | return false; 153 | } 154 | else { 155 | var randomInt = getRandomInteger(rps.length); 156 | var response = rps[randomInt]; 157 | if (getResult(check, response).toString() === "Lose") { 158 | room.sendAnnouncement(`${messages.Chat.RPS.Fail[0]} ${point} ${messages.Chat.RPS.Fail[1]} (${roomObject.emojis[index]} 🆚 ${roomObject.emojis[randomInt]})`, player.id, colors.Chat.RPS.Fail, fonts.Chat.RPS.Fail, sounds.Chat.RPS.Fail); 159 | updatePlayerPoint(player, -point); 160 | return false; 161 | } 162 | else if (getResult(check, response).toString() === "Draw") { 163 | room.sendAnnouncement(`${messages.Chat.RPS.Draw} ${messages.Chat.RPS.Draw} (${roomObject.emojis[index]} 🆚 ${roomObject.emojis[randomInt]})`, player.id, colors.Chat.RPS.Draw, fonts.Chat.RPS.Draw, sounds.Chat.RPS.Draw); 164 | updatePlayerPoint(player, 0); 165 | return false; 166 | } 167 | else if (getResult(check, response).toString() === "Win") { 168 | room.sendAnnouncement(`${messages.Chat.RPS.Success[0]} ${point} ${messages.Chat.RPS.Success[1]} (${roomObject.emojis[index]} 🆚 ${roomObject.emojis[randomInt]})`, player.id, colors.Chat.RPS.Success, fonts.Chat.RPS.Success, sounds.Chat.RPS.Success); 169 | updatePlayerPoint(player, point); 170 | return false; 171 | } 172 | } 173 | } 174 | } 175 | } 176 | else { 177 | room.sendAnnouncement(`${messages.Chat.NotACommand}`, player.id, colors.Chat.NotACommand, fonts.Chat.NotACommand, sounds.Chat.NotACommand); 178 | return false; 179 | } 180 | } 181 | else { 182 | room.sendAnnouncement(`(${new Date(Date.now()).toLocaleString()}) [${playerList[player.name].points}] [${messages.Chat.Player[Number(player.admin)]}] ${player.name} #${player.id}: ${message}`, null, colors.Chat.Player[Number(player.admin)], fonts.Chat.Player[Number(player.admin)], sounds.Chat.Player[Number(player.admin)]); 183 | return false; 184 | } 185 | } 186 | 187 | room.onPlayerJoin = function (player) { 188 | var accounts = getPreviousAccounts(player); 189 | 190 | if (playerList[player.name] == undefined) { 191 | if (accounts.length == 0) { 192 | playerList[player.name] = { name: player.name, auth: player.auth, conn: player.conn, points: 600 }; 193 | } 194 | else { 195 | var lastAccount = accounts[accounts.length - 1]; 196 | playerList[player.name] = { name: player.name, auth: player.auth, conn: player.conn, points: lastAccount.points }; 197 | } 198 | } 199 | else { 200 | if (accounts.length == 0) { 201 | playerList[player.name] = { name: player.name, auth: player.auth, conn: player.conn, points: 600 }; //A rare situation, theorically it's almost impossible to happen. 202 | } 203 | else { 204 | var lastAccount = accounts[accounts.length - 1]; 205 | playerList[player.name] = { name: player.name, auth: player.auth, conn: player.conn, points: lastAccount.points }; 206 | } 207 | } 208 | 209 | playerListArray.push(playerList[player.name]); 210 | } 211 | -------------------------------------------------------------------------------- /Beginner/SlowMode.js: -------------------------------------------------------------------------------- 1 | var playerList = {}; 2 | var removal = 3000; //In milliseconds 3 | 4 | var room = HBInit({roomName:"SlowMode",noPlayer:true,public:true,maxPlayers:12}); 5 | 6 | room.onPlayerChat = function(player,message){ 7 | var administrators = room.getPlayerList(p => p.admin == true); 8 | 9 | if(playerList[player.name].slowMode == false){ 10 | playerList[player.name].slowMode = true; 11 | var name = player.name; 12 | 13 | setTimeout(function(){ 14 | if(playerList[player.name].slowMode == true){ 15 | playerList[name].slowMode = false; 16 | } 17 | },removal); 18 | } 19 | else{ 20 | room.sendAnnouncement(`Slow mode is active. Only the administration can see your messages. (${message})`,player.id,0xFFFF00,"bold",2); 21 | administrators.forEach(p => { 22 | room.sendAnnouncement(`${player.name}: ${message}`,p.id,0xFFFF00,"bold",1); 23 | }); 24 | return false; 25 | } 26 | } 27 | 28 | room.onPlayerJoin = function(player){ 29 | if(playerList[player.name] == undefined){ 30 | playerList[player.name] = {name: player.name, slowMode: false}; 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /Beginner/Spam_Mute.js: -------------------------------------------------------------------------------- 1 | var playerList = {}; 2 | var minMessageLength = 1; 3 | var bound = 3; //You can either decrease or increase this, min = 2; 4 | var spamBanLimit = 3; 5 | var spamTimer = 3000; //In milliseconds 6 | var removal = 60000; //In milliseconds 7 | 8 | var room = HBInit({roomName:"Spam-Mute",noPlayer:true,public:true,maxPlayers:12}); 9 | 10 | room.onPlayerChat = function(player,message){ 11 | playerList[player.name].messageDates.push(Date.now()); 12 | var administrators = room.getPlayerList(p => p.admin == true); 13 | 14 | if(playerList[player.name].messageDates.length == bound){ 15 | playerList[player.name].messageDates.shift(); 16 | } 17 | if(minMessageLength < playerList[player.name].messageDates.length && playerList[player.name].messageDates.length <= bound-1 && playerList[player.name].messageDates[playerList[player.name].messageDates.length-1] - playerList[player.name].messageDates[0] < spamTimer){ 18 | if(playerList[player.name].muted == false){ 19 | var name = player.name; 20 | room.sendAnnouncement(`${player.name} was muted by the reason of spamming!`,null,0x00FF00,"bold",1); 21 | playerList[player.name].muted = true; 22 | 23 | setTimeout(function(){ 24 | if(playerList[name].muted == true){ 25 | playerList[name].muted = false; 26 | room.sendAnnouncement(`${player.name} is now unmuted!`,null,0x00FF00,"bold",1); 27 | } 28 | },removal); 29 | } 30 | else{ 31 | room.sendAnnouncement(`You will be banned if continuing to spam in muted mode!`,player.id,0xFF8000,"bold",2); 32 | 33 | if(playerList[player.name].spamInMute < spamBanLimit){ 34 | playerList[player.name].spamInMute++; 35 | } 36 | else{ 37 | room.kickPlayer(player.id,"Spam",true); 38 | } 39 | 40 | return false; 41 | } 42 | } 43 | if(playerList[player.name].muted == true){ 44 | room.sendAnnouncement(`You are muted. Only the administration can see your messages. (${message})`,player.id,0xFFFF00,"bold",2); 45 | administrators.forEach(p => { 46 | room.sendAnnouncement(`${player.name}: ${message}`,p.id,0xFFFF00,"bold",1); 47 | }); 48 | return false; 49 | } 50 | } 51 | 52 | room.onPlayerJoin = function(player){ 53 | if(playerList[player.name] == undefined){ 54 | playerList[player.name] = {name: player.name, messageDates: [], muted: false, spamInMute: 0}; 55 | } 56 | } 57 | -------------------------------------------------------------------------------- /Beginner/VIP_Roles.js: -------------------------------------------------------------------------------- 1 | var colors = { 2 | onPlayerChat: { 3 | Player: [[0xFFFFFF, 0x95FF8E], [0xFFDB72, 0x95FF8E]] 4 | }, 5 | onPlayerJoin: { 6 | VIP: 0x95FF8E 7 | }, 8 | onPlayerLeave: { 9 | VIP: 0x95FF8E 10 | } 11 | }; 12 | 13 | var fonts = { 14 | onPlayerChat: { 15 | Player: [["normal", "bold"], ["bold", "bold"]] 16 | }, 17 | onPlayerJoin: { 18 | VIP: "bold" 19 | }, 20 | onPlayerLeave: { 21 | VIP: "bold" 22 | } 23 | }; 24 | 25 | var sounds = { 26 | onPlayerChat: { 27 | Player: [[1, 1], [1, 2]], 28 | }, 29 | onPlayerJoin: { 30 | VIP: 1 31 | }, 32 | onPlayerLeave: { 33 | VIP: 1 34 | } 35 | }; 36 | 37 | var messages = { 38 | onPlayerChat: { 39 | Player: [["[PLAYER]", "[VIP][PLAYER]"], ["[ADMIN]", "[VIP][ADMIN]"]] 40 | }, 41 | onPlayerJoin: { 42 | VIP: "✅ A VIP user has joined:" 43 | }, 44 | onPlayerLeave: { 45 | VIP: "➡️ A VIP user has left:" 46 | } 47 | }; 48 | 49 | var roomObject = { 50 | maxPlayers: 4, 51 | noPlayer: true, 52 | public: true, 53 | roomName: "VIP Roles", 54 | }; 55 | 56 | var vips = { 57 | auth: ["auth1", "auth2"], 58 | id: [] 59 | } 60 | 61 | var playerList = []; 62 | 63 | var room = HBInit({ roomName: roomObject.roomName, noPlayer: roomObject.noPlayer, public: roomObject.public, maxPlayers: roomObject.maxPlayers }); 64 | 65 | function checkJoiningHistory(player) { 66 | return playerList.length > 0 && playerList.filter(p => p.name == player.name || p.auth == player.auth || p.conn == player.conn).length > 0; 67 | } 68 | 69 | function checkPlayerAuth(auth) { 70 | return vips.auth.length > 0 && vips.auth.includes(auth); 71 | } 72 | 73 | function checkPlayerID(id) { 74 | return vips.id.length > 0 && vips.id.includes(id); 75 | } 76 | 77 | function setPlayer(name, auth, conn) { 78 | playerList.push({ name: name, auth: auth, conn: conn }); 79 | } 80 | 81 | room.onPlayerChat = function (player, message) { 82 | room.sendAnnouncement(`${messages.onPlayerChat.Player[Number(player.admin)][Number(checkPlayerID(player.id))]} ${player.name}: ${message}`, null, colors.onPlayerChat.Player[Number(player.admin)][Number(checkPlayerID(player.id))], fonts.onPlayerChat.Player[Number(player.admin)][Number(checkPlayerID(player.id))], sounds.onPlayerChat.Player[Number(player.admin)][Number(checkPlayerID(player.id))]); 83 | return false; 84 | } 85 | 86 | room.onPlayerJoin = function (player) { 87 | if (playerList.length == 0) { 88 | setPlayer(player.name, player.auth, player.conn); 89 | } 90 | else { 91 | var data = checkJoiningHistory(player); 92 | if (data) { 93 | var checkAuth = checkPlayerAuth(player.auth); 94 | var checkID = checkPlayerID(player.id); 95 | if (checkAuth && !checkID) { 96 | vips.id.push(player.id); 97 | room.sendAnnouncement(`${messages.onPlayerJoin.VIP} ${player.name}`, null, colors.onPlayerJoin.VIP, fonts.onPlayerJoin.VIP, sounds.onPlayerJoin.VIP); 98 | } 99 | } 100 | else{ 101 | setPlayer(player.name, player.auth, player.conn); 102 | var checkAuth = checkPlayerAuth(player.auth); 103 | var checkID = checkPlayerID(player.id); 104 | if (checkAuth && !checkID) { 105 | vips.id.push(player.id); 106 | room.sendAnnouncement(`${messages.onPlayerJoin.VIP} ${player.name}`, null, colors.onPlayerJoin.VIP, fonts.onPlayerJoin.VIP, sounds.onPlayerJoin.VIP); 107 | } 108 | } 109 | } 110 | } 111 | 112 | room.onPlayerLeave = function (player) { 113 | if (checkPlayerID(player.id)) { 114 | var index = vips.id.findIndex(p => p == player.id); 115 | if (index !== -1) { 116 | room.sendAnnouncement(`${messages.onPlayerLeave.VIP} ${player.name}`, null, colors.onPlayerLeave.VIP, fonts.onPlayerLeave.VIP, sounds.onPlayerLeave.VIP); 117 | vips.id.splice(index, 1); 118 | } 119 | } 120 | } 121 | -------------------------------------------------------------------------------- /Beginner/Webhooks.js: -------------------------------------------------------------------------------- 1 | var room = HBInit({ roomName: "Webhooks", noPlayer:true, public:true, maxPlayers: 30}); 2 | 3 | function sendAnnouncementToDiscord(message) { 4 | 5 | var request = new XMLHttpRequest(); 6 | request.open("POST","https://discord.com/api/webhooks/..."); 7 | 8 | request.setRequestHeader('Content-type', 'application/json'); 9 | 10 | var params = { 11 | avatar_url: '', 12 | username: 'Your Discord Webhook', 13 | content: message 14 | }; 15 | 16 | request.send(JSON.stringify(params)); 17 | } 18 | 19 | room.onPlayerJoin = function(player){ 20 | console.log(player.name + " has joined."); 21 | } 22 | 23 | room.onPlayerLeave = function(player){ 24 | console.log(player.name + " has left."); 25 | } 26 | 27 | room.onPlayerChat = function(player,msg){ 28 | console.log(player.name + ": " + msg); 29 | sendAnnouncementToDiscord(msg); 30 | }; 31 | -------------------------------------------------------------------------------- /Beginner/ZoneCheck.js: -------------------------------------------------------------------------------- 1 | var zone = {MinX: -370, MaxX: 370, MinY: -170, MaxY: 170}; 2 | var playerList = {}; 3 | 4 | var room = HBInit({ roomName: "Zone Check", noPlayer: true, public: true, maxPlayers: 2 }); 5 | 6 | function checkIfPlayerInZone(player){ 7 | return player != null && player.position != null && (zone.MinX <= player.position.x && player.position.x <= zone.MaxX) && (zone.MinY <= player.position.y && player.position.y <= zone.MaxY); 8 | } 9 | 10 | function warnIfPlayerInZone(){ 11 | var players = room.getPlayerList().filter(p => room.getPlayerDiscProperties(p.id) != null); 12 | players.forEach(p => { 13 | if(checkIfPlayerInZone(p) == true){ 14 | if(playerList[p.name].isInZoneWarning == false){ 15 | room.sendAnnouncement(`You are inside the zone!`,p.id,0xFFFFFF,"bold",2); 16 | playerList[p.name].isInZoneWarning = true; 17 | } 18 | } 19 | else{ 20 | if(playerList[p.name].isInZoneWarning == true){ 21 | room.sendAnnouncement(`You are outside the zone!`,p.id,0xFFFFFF,"bold",2); 22 | playerList[p.name].isInZoneWarning = false; 23 | } 24 | } 25 | }); 26 | } 27 | 28 | room.onGameTick = function(){ 29 | warnIfPlayerInZone(); 30 | } 31 | 32 | room.onPlayerJoin = function(player){ 33 | if(playerList[player.name] == undefined) playerList[player.name] = {name: player.name, isInZoneWarning: false}; 34 | } 35 | -------------------------------------------------------------------------------- /Intermediate/3DefLines.js: -------------------------------------------------------------------------------- 1 | var Map = `{"name":"Big","width":600,"height":270,"spawnDistance":100,"bg":{"type":"grass","width":550,"height":240,"kickOffRadius":80,"cornerRadius":0},"vertexes":[{"x":-550,"y":240,"trait":"ballArea"},{"x":-550,"y":80,"trait":"ballArea"},{"x":-550,"y":-80,"trait":"ballArea"},{"x":-550,"y":-240,"trait":"ballArea"},{"x":550,"y":240,"trait":"ballArea"},{"x":550,"y":80,"trait":"ballArea"},{"x":550,"y":-80,"trait":"ballArea"},{"x":550,"y":-240,"trait":"ballArea"},{"x":0,"y":270,"trait":"kickOffBarrier"},{"x":0,"y":80,"trait":"kickOffBarrier"},{"x":0,"y":-80,"trait":"kickOffBarrier"},{"x":0,"y":-270,"trait":"kickOffBarrier"},{"x":-560,"y":-80,"trait":"goalNet"},{"x":-580,"y":-60,"trait":"goalNet"},{"x":-580,"y":60,"trait":"goalNet"},{"x":-560,"y":80,"trait":"goalNet"},{"x":560,"y":-80,"trait":"goalNet"},{"x":580,"y":-60,"trait":"goalNet"},{"x":580,"y":60,"trait":"goalNet"},{"x":560,"y":80,"trait":"goalNet"},{"x":-300,"y":-270,"cMask":["c0"],"trait":"threeDefLine"},{"x":300,"y":-270,"cMask":["c1"],"trait":"threeDefLine"},{"x":-300,"y":270,"cMask":["c0"],"trait":"threeDefLine"},{"x":300,"y":270,"cMask":["c1"],"trait":"threeDefLine"}],"segments":[{"v0":0,"v1":1,"trait":"ballArea"},{"v0":2,"v1":3,"trait":"ballArea"},{"v0":4,"v1":5,"trait":"ballArea"},{"v0":6,"v1":7,"trait":"ballArea"},{"v0":12,"v1":13,"curve":-90,"trait":"goalNet"},{"v0":13,"v1":14,"trait":"goalNet"},{"v0":14,"v1":15,"curve":-90,"trait":"goalNet"},{"v0":16,"v1":17,"curve":90,"trait":"goalNet"},{"v0":17,"v1":18,"trait":"goalNet"},{"v0":18,"v1":19,"curve":90,"trait":"goalNet"},{"v0":8,"v1":9,"trait":"kickOffBarrier"},{"v0":9,"v1":10,"curve":180,"cGroup":["blueKO"],"trait":"kickOffBarrier"},{"v0":9,"v1":10,"curve":-180,"cGroup":["redKO"],"trait":"kickOffBarrier"},{"v0":10,"v1":11,"trait":"kickOffBarrier"},{"v0":22,"v1":20,"cMask":["c0"],"trait":"threeDefLine"},{"v0":21,"v1":23,"cMask":["c1"],"trait":"threeDefLine"}],"goals":[{"p0":[-550,80],"p1":[-550,-80],"team":"red"},{"p0":[550,80],"p1":[550,-80],"team":"blue"}],"discs":[{"pos":[-550,80],"color":"FFCCCC","trait":"goalPost"},{"pos":[-550,-80],"color":"FFCCCC","trait":"goalPost"},{"pos":[550,80],"color":"CCCCFF","trait":"goalPost"},{"pos":[550,-80],"color":"CCCCFF","trait":"goalPost"},{"pos":[-300,-240],"trait":"threeDefLineBall_RedFirst"},{"pos":[-300,240],"trait":"threeDefLineBall_RedFirst"},{"pos":[-1300,-240],"trait":"threeDefLineBall_RedSecond"},{"pos":[-1300,240],"trait":"threeDefLineBall_RedSecond"},{"pos":[300,-240],"trait":"threeDefLineBall_BlueFirst"},{"pos":[300,240],"trait":"threeDefLineBall_BlueFirst"},{"pos":[1300,-240],"trait":"threeDefLineBall_BlueSecond"},{"pos":[1300,240],"trait":"threeDefLineBall_BlueSecond"}],"planes":[{"normal":[0,1],"dist":-240,"trait":"ballArea","_data":{"extremes":{"normal":[0,1],"dist":-240,"canvas_rect":[-1300,-270,1300,270],"a":[-1300,-240],"b":[1300,-240]}}},{"normal":[0,-1],"dist":-240,"trait":"ballArea","_data":{"extremes":{"normal":[0,-1],"dist":-240,"canvas_rect":[-1300,-270,1300,270],"a":[-1300,240],"b":[1300,240]}}},{"normal":[0,1],"dist":-270,"bCoef":0.1,"_data":{"extremes":{"normal":[0,1],"dist":-270,"canvas_rect":[-1300,-270,1300,270],"a":[-1300,-270],"b":[1300,-270]}}},{"normal":[0,-1],"dist":-270,"bCoef":0.1,"_data":{"extremes":{"normal":[0,-1],"dist":-270,"canvas_rect":[-1300,-270,1300,270],"a":[-1300,270],"b":[1300,270]}}},{"normal":[1,0],"dist":-600,"bCoef":0.1,"_data":{"extremes":{"normal":[1,0],"dist":-600,"canvas_rect":[-1300,-270,1300,270],"a":[-600,-270],"b":[-600,270]}}},{"normal":[-1,0],"dist":-600,"bCoef":0.1,"_data":{"extremes":{"normal":[-1,0],"dist":-600,"canvas_rect":[-1300,-270,1300,270],"a":[600,-270],"b":[600,270]}}}],"traits":{"ballArea":{"vis":false,"bCoef":1,"cMask":["ball"]},"goalPost":{"radius":8,"invMass":0,"bCoef":0.5},"goalNet":{"vis":true,"bCoef":0.1,"cMask":["ball"]},"kickOffBarrier":{"vis":false,"bCoef":0.1,"cGroup":["redKO","blueKO"],"cMask":["red","blue"]},"threeDefLine":{"bCoef":0,"cGroup":["wall"],"bias":-300,"vis":false},"threeDefLineBall_RedFirst":{"radius":0,"invMass":0,"damping":0,"cMask":["none"],"cGroup":["none"]},"threeDefLineBall_RedSecond":{"radius":0,"invMass":0,"damping":0,"cMask":["none"],"cGroup":["none"]},"threeDefLineBall_BlueFirst":{"radius":0,"invMass":0,"damping":0,"cMask":["none"],"cGroup":["none"]},"threeDefLineBall_BlueSecond":{"radius":0,"invMass":0,"damping":0,"cMask":["none"],"cGroup":["none"]}},"redSpawnPoints":[[-100,-50],[-100,50],[-100,0]],"blueSpawnPoints":[[100,-50],[100,50],[100,0]],"canBeStored":false,"joints":[{"d0":5,"d1":6,"color":"C7E6BD"},{"d0":7,"d1":8,"color":"FF0000"},{"d0":9,"d1":10,"color":"C7E6BD"},{"d0":11,"d1":12,"color":"0000FF"}],"kickOffReset":"full","cameraWidth":1200,"cameraHeight":540,"maxViewWidth":2000}` 2 | 3 | var room = HBInit({roomName:"3v3 Big with Def Lines",noPlayer:true,public:true,maxPlayers:8}); 4 | 5 | var defLines = []; 6 | var cf = room.CollisionFlags; 7 | 8 | var JMap = JSON.parse(Map); 9 | 10 | var def_zone_player_count_bound = 2; 11 | 12 | var number_indicators_red_first = []; 13 | var number_indicators_red_second = []; 14 | var number_indicators_blue_first = []; 15 | var number_indicators_blue_second = []; 16 | 17 | var isRoomSet = false; 18 | 19 | room.setScoreLimit(3); 20 | room.setTimeLimit(3); 21 | room.setTeamsLock(true); 22 | room.setCustomStadium(Map); 23 | 24 | function fillIndicators(){ 25 | for(var d=0; d player.id != 0 && player.team == id); 43 | } 44 | 45 | function updateAdmins(){ 46 | var players = room.getPlayerList().filter(player => player.id != 0); 47 | if(players.length == 0) return; 48 | if(players.find(player => player.admin) != null) return; 49 | room.setPlayerAdmin(players[0].id,true); 50 | } 51 | 52 | function adjustDefLines(player){ 53 | var players = room.getPlayerList(); 54 | var mfp_red = mostForwardPlayer(1); 55 | var mfp_blue = mostForwardPlayer(2); 56 | var non_mfp_red = GetTeam(1).filter(p => p.id !== mfp_red.id); 57 | var non_mfp_blue = GetTeam(2).filter(p => p.id !== mfp_blue.id); 58 | 59 | if(room.getPlayerDiscProperties(mfp_red.id).cGroup === cf.red){ 60 | room.setPlayerDiscProperties(mfp_red.id,{cGroup:cf.red | cf.c0}); 61 | } 62 | if(room.getPlayerDiscProperties(mfp_blue.id).cGroup === cf.blue){ 63 | room.setPlayerDiscProperties(mfp_blue.id,{cGroup:cf.blue | cf.c1}); 64 | } 65 | 66 | for(r in non_mfp_red){ 67 | if(room.getPlayerDiscProperties(non_mfp_red[r].id).cGroup !== cf.red){ 68 | room.setPlayerDiscProperties(non_mfp_red[r].id,{cGroup:cf.red}); 69 | } 70 | } 71 | for(b in non_mfp_blue){ 72 | if(room.getPlayerDiscProperties(non_mfp_blue[b].id).cGroup !== cf.blue){ 73 | room.setPlayerDiscProperties(non_mfp_blue[b].id,{cGroup:cf.blue}); 74 | } 75 | } 76 | } 77 | 78 | function findDefLines(){ 79 | defLines = JMap.segments.filter(s => s.trait == "threeDefLine"); 80 | } 81 | 82 | function redDefPlayerCount(){ 83 | return room.getPlayerList().filter(p => room.getPlayerDiscProperties(p.id) != null && p.team == 1 && room.getPlayerDiscProperties(p.id).x <= JMap.vertexes[defLines[0].v0].x).length; 84 | } 85 | 86 | function blueDefPlayerCount(){ 87 | return room.getPlayerList().filter(p => room.getPlayerDiscProperties(p.id) != null && p.team == 2 && room.getPlayerDiscProperties(p.id).x >= JMap.vertexes[defLines[1].v0].x).length; 88 | } 89 | 90 | function moveDefLines(){ 91 | if(redDefPlayerCount() >= def_zone_player_count_bound){ 92 | for(var n in number_indicators_red_first){ 93 | if(room.getDiscProperties(number_indicators_red_first[n]).x > -JMap.width){ 94 | room.setDiscProperties(number_indicators_red_first[n],{x:room.getDiscProperties(number_indicators_red_first[n]).x - 1000}); 95 | } 96 | } 97 | for(var n in number_indicators_red_second){ 98 | if(room.getDiscProperties(number_indicators_red_second[n]).x < -JMap.width){ 99 | room.setDiscProperties(number_indicators_red_second[n],{x:room.getDiscProperties(number_indicators_red_second[n]).x + 1000}); 100 | } 101 | } 102 | } 103 | 104 | if(redDefPlayerCount() < def_zone_player_count_bound){ 105 | for(var n in number_indicators_red_first){ 106 | if(room.getDiscProperties(number_indicators_red_first[n]).x < -JMap.width){ 107 | room.setDiscProperties(number_indicators_red_first[n],{x:room.getDiscProperties(number_indicators_red_first[n]).x + 1000}); 108 | } 109 | } 110 | for(var n in number_indicators_red_second){ 111 | if(room.getDiscProperties(number_indicators_red_second[n]).x > -JMap.width){ 112 | room.setDiscProperties(number_indicators_red_second[n],{x:room.getDiscProperties(number_indicators_red_second[n]).x - 1000}); 113 | } 114 | } 115 | } 116 | 117 | if(blueDefPlayerCount() >= def_zone_player_count_bound){ 118 | for(var n in number_indicators_blue_first){ 119 | if(room.getDiscProperties(number_indicators_blue_first[n]).x < JMap.width){ 120 | room.setDiscProperties(number_indicators_blue_first[n],{x:room.getDiscProperties(number_indicators_blue_first[n]).x + 1000}); 121 | } 122 | } 123 | for(var n in number_indicators_blue_second){ 124 | if(room.getDiscProperties(number_indicators_blue_second[n]).x > JMap.width){ 125 | room.setDiscProperties(number_indicators_blue_second[n],{x:room.getDiscProperties(number_indicators_blue_second[n]).x - 1000}); 126 | } 127 | } 128 | } 129 | 130 | if(blueDefPlayerCount() < def_zone_player_count_bound){ 131 | for(var n in number_indicators_blue_first){ 132 | if(room.getDiscProperties(number_indicators_blue_first[n]).x > JMap.width){ 133 | room.setDiscProperties(number_indicators_blue_first[n],{x:room.getDiscProperties(number_indicators_blue_first[n]).x - 1000}); 134 | } 135 | } 136 | for(var n in number_indicators_blue_second){ 137 | if(room.getDiscProperties(number_indicators_blue_second[n]).x < JMap.width){ 138 | room.setDiscProperties(number_indicators_blue_second[n],{x:room.getDiscProperties(number_indicators_blue_second[n]).x + 1000}); 139 | } 140 | } 141 | } 142 | } 143 | 144 | function sortByPosition(players) { 145 | return players.sort(function(p1,p2) { 146 | return p1.position.x - p2.position.x; 147 | }); 148 | } 149 | 150 | function mostForwardPlayer(teamID){ 151 | var players = room.getPlayerList(); 152 | var playersTeam = players.filter(p => p.team === teamID); 153 | var redTeam = GetTeam(1); 154 | var blueTeam = GetTeam(2); 155 | var redTeamLength = GetTeam(1).length; 156 | var blueTeamLength = GetTeam(2).length; 157 | teamSorted = sortByPosition(playersTeam); 158 | if(teamID === 1){ 159 | return teamSorted[redTeamLength-1]; 160 | } 161 | else if(teamID === 2){ 162 | return teamSorted[0]; 163 | } 164 | } 165 | 166 | room.onPlayerJoin = function(player){ 167 | console.log(player.name + " has joined. - Auth: " + player.auth + " Conn: " + player.conn); 168 | updateAdmins(); 169 | room.sendAnnouncement("Hoş geldiniz",player.id,0x00FFFF,"bold",2); 170 | } 171 | 172 | room.onPlayerLeave = function(player){ 173 | console.log(player.name + " has left."); 174 | updateAdmins(); 175 | } 176 | 177 | room.onPlayerChat = function(player,message){ 178 | console.log(player.name + ": " + message); 179 | if(player.admin==true){ 180 | room.sendAnnouncement(player.name + ": " + message,null,0x00FFFF,"bold",1); 181 | return false; 182 | } 183 | else{ 184 | room.sendAnnouncement(player.name + ": " + message,null,0xFFFF00,"normal",1); 185 | return false; 186 | } 187 | }; 188 | 189 | room.onGameStart = function(byPlayer){ 190 | findDefLines(); 191 | } 192 | 193 | room.onGameStop = function(byPlayer){ 194 | defLines = []; 195 | } 196 | 197 | room.onGameTick = function(){ 198 | if(GetTeam(1).length > 0 && GetTeam(2).length > 0){ 199 | mostForwardPlayer(); 200 | adjustDefLines(); 201 | moveDefLines(); 202 | redDefPlayerCount(); 203 | blueDefPlayerCount(); 204 | } 205 | } 206 | 207 | room.onRoomLink = function(url){ 208 | if(isRoomSet == false){ 209 | fillIndicators(); 210 | isRoomSet = true; 211 | } 212 | } 213 | -------------------------------------------------------------------------------- /Intermediate/Badwords.js: -------------------------------------------------------------------------------- 1 | var playerList = {}; 2 | var playerListArray = []; 3 | 4 | var badwords = [/[a4@][s$5][s$5]h[o0][l1][e€]+/, /[bß][a4@]rm[iy7]+/, /[bß][a4@][s$5][t₺][a4@]rd+/, /[bß][ıi1][t₺][cç¢]h+/, /[c¢]un[t₺]+/, /f[uü][cç¢]k+/, /[l1]m[a4@][o0]+/, /[l1]mf[a4@][o0]+/, /pu[s5$][s5$][y7]+/, /r[e€][t₺][a4@]rd+/, /[s$5][t₺]fu+/, /wh[o0]r[e€]+/, /w[t₺]f+/]; 5 | 6 | var roomObject = { 7 | limits: { 8 | Chat: { 9 | Badwords: 2 10 | } 11 | }, 12 | maxPlayers: 12, 13 | name: "Bad words", 14 | noPlayer: true, 15 | public: true, 16 | timeout: { 17 | Chat: { 18 | Badwords: 600000 19 | } 20 | } 21 | }; 22 | 23 | var colors = { 24 | Chat: { 25 | Admin: { 26 | Badwords: 0xFF8000, 27 | Muted: 0xFFFF00 28 | }, 29 | Badwords: { 30 | Mute: 0xFF0000, 31 | Unmute: 0x00FF00, 32 | }, 33 | Mute: { 34 | Still: 0xFFFF00 35 | }, 36 | Player: [0xFFFFFF, 0xFFDB72] 37 | }, 38 | Join: { 39 | Muted: 0xFFFF00, 40 | Welcome: 0xFFFFFF 41 | }, 42 | }; 43 | 44 | var fonts = { 45 | Chat: { 46 | Admin: { 47 | Badwords: "bold", 48 | Muted: "bold" 49 | }, 50 | Badwords: { 51 | Mute: "bold", 52 | Unmute: "normal", 53 | }, 54 | Mute: { 55 | Still: "bold" 56 | }, 57 | Player: ["normal", "bold"] 58 | }, 59 | Join: { 60 | Muted: "bold", 61 | Welcome: "normal" 62 | }, 63 | }; 64 | 65 | var sounds = { 66 | Chat: { 67 | Admin: { 68 | Badwords: 2, 69 | Muted: 1 70 | }, 71 | Badwords: { 72 | Mute: 2, 73 | Unmute: 1, 74 | }, 75 | Mute: { 76 | Still: 2 77 | }, 78 | Player: [1, 1] 79 | }, 80 | Join: { 81 | Muted: 2, 82 | Welcome: 1 83 | } 84 | }; 85 | 86 | var messages = { 87 | Chat: { 88 | Badwords: { 89 | Kick: "You were banned for keeping using bad words.", 90 | Mute: `was muted for ${roomObject.timeout.Chat.Badwords / 60000 == 1 ? roomObject.timeout.Chat.Badwords / 60000 + " minute. A further attempt will result in ban!" : roomObject.timeout.Chat.Badwords / 60000 + " minutes. A further attempt will result in ban!"}`, 91 | Unmute: "is now unmuted!" 92 | }, 93 | Mute: { 94 | Still: "You are still muted! Only the administration can see your messages." 95 | } 96 | }, 97 | Join: { 98 | Badwords: "You were banned due to joining the room with bad name.", 99 | Blacklisted: "You are banned forever!", 100 | Muted: "You have an active mute punishment so you cannot talk before your punishment ends.", 101 | Welcome: "Welcome!" 102 | } 103 | }; 104 | 105 | var kickTypes = { 106 | Chat: { 107 | Badwords: true 108 | }, 109 | Join: { 110 | Badwords: true, 111 | Blacklisted: true 112 | } 113 | }; 114 | 115 | var room = HBInit({ roomName: roomObject.name, noPlayer: roomObject.noPlayer, public: roomObject.public, maxPlayers: roomObject.maxPlayers }); 116 | 117 | function getPreviousAccounts(player) { 118 | return playerListArray.length > 0 && playerListArray.filter(p => p.auth == player.auth || p.conn == player.conn); 119 | } 120 | 121 | function isBadword(str) { 122 | return badwords.filter(b => str.match(b)).length > 0; 123 | } 124 | 125 | room.onPlayerChat = function (player, message) { 126 | var administrators = room.getPlayerList().filter(p => p.admin == true); 127 | 128 | if (isBadword(message) == true) { 129 | playerList[player.name].badwords++; 130 | if (playerList[player.name].badwords < roomObject.limits.Chat.Badwords) { 131 | if (playerList[player.name].muted == false) { 132 | var name = player.name; 133 | administrators.forEach(p => { 134 | room.sendAnnouncement(`${player.name}: ${message}`, p.id, colors.Chat.Admin.Badwords, fonts.Chat.Admin.Badwords, sounds.Chat.Admin.Badwords); 135 | }); 136 | room.sendAnnouncement(`${name} ${messages.Chat.Badwords.Mute}`, null, colors.Chat.Badwords.Mute, fonts.Chat.Badwords.Mute, sounds.Chat.Badwords.Mute); 137 | playerList[name].muted = true; 138 | 139 | setTimeout(function () { 140 | if (playerList[name].muted == true) { 141 | playerList[name].muted = false; 142 | room.sendAnnouncement(`${player.name} ${messages.Chat.Badwords.Unmute}`, null, colors.Chat.Badwords.Unmute, fonts.Chat.Badwords.Unmute, sounds.Chat.Badwords.Unmute); 143 | } 144 | }, roomObject.timeout.Chat.Badwords); 145 | } 146 | return false; 147 | } 148 | else { 149 | room.kickPlayer(player.id, `${messages.Chat.Badwords.Kick}`, kickTypes.Chat.Badwords); 150 | return false; 151 | } 152 | } 153 | if (playerList[player.name].muted == true) { 154 | room.sendAnnouncement(`${messages.Chat.Mute.Still} (${message})`, player.id, colors.Chat.Mute.Still, fonts.Chat.Mute.Still, sounds.Chat.Mute.Still); 155 | administrators.forEach(p => { 156 | room.sendAnnouncement(`${player.name}: ${message}`, p.id, colors.Chat.Admin.Muted, fonts.Chat.Admin.Muted, sounds.Chat.Admin.Muted); 157 | }); 158 | return false; 159 | } 160 | else if (playerList[player.name].muted == false) { 161 | room.sendAnnouncement(`${player.name}: ${message}`, null, colors.Chat.Player[Number(player.admin)], fonts.Chat.Player[Number(player.admin)], sounds.Chat.Player[Number(player.admin)]); 162 | return false; 163 | } 164 | } 165 | 166 | room.onPlayerJoin = function (player) { 167 | if (isBadword(player.name) == true) { 168 | room.kickPlayer(player.id, `${messages.Join.Badwords}`, kickTypes.Join.Badwords); 169 | } 170 | else { 171 | if (playerList[player.name] == undefined) { 172 | playerList[player.name] = { name: player.name, auth: player.auth, conn: player.conn, muted: false, badwords: 0 }; 173 | } 174 | var accounts = getPreviousAccounts(player); 175 | if (accounts.length > 0) { 176 | var blacklisted = accounts.filter(a => a.badwords >= roomObject.limits.Chat.Badwords); 177 | var muted = accounts.filter(a => a.muted == true); 178 | 179 | if (blacklisted.length > 0) { 180 | room.kickPlayer(player.id, `${messages.Join.Blacklisted}`, kickTypes.Join.Blacklisted); 181 | } 182 | else if (muted.length > 0) { 183 | room.sendAnnouncement(`${messages.Join.Muted}`, player.id, colors.Join.Muted, fonts.Join.Muted, sounds.Join.Muted); 184 | playerList[player.name].muted = true; 185 | } 186 | } 187 | 188 | playerListArray.push(playerList[player.name]); 189 | room.sendAnnouncement(`${messages.Join.Welcome}`, player.id, colors.Join.Welcome, fonts.Join.Welcome, sounds.Join.Welcome); 190 | } 191 | } 192 | -------------------------------------------------------------------------------- /Intermediate/CollisionDetection_Counter.js: -------------------------------------------------------------------------------- 1 | var room = HBInit({ roomName: "Collision Detection / Counter", noPlayer:true, public:false, maxPlayers: 10 }); 2 | 3 | var tolerance = 0.01; 4 | var collisionCounter = 0; 5 | 6 | function getDistance(p1,p2){ 7 | return Math.hypot((p2.x-p1.x),(p2.y-p1.y)); 8 | } 9 | 10 | function checkIfColliding(p1,p2){ 11 | var collision = false; 12 | if(room.getPlayerDiscProperties(p1.id) != null && room.getPlayerDiscProperties(p2.id) != null){ 13 | var p1Disc = room.getPlayerDiscProperties(p1.id); 14 | var p2Disc = room.getPlayerDiscProperties(p2.id); 15 | var p1Radius = p1Disc.radius; 16 | var p2Radius = p2Disc.radius; 17 | var p1Name = room.getPlayer(p1.id).name; 18 | var p2Name = room.getPlayer(p2.id).name; 19 | var distance = getDistance(p1Disc,p2Disc); 20 | var distanceCheck = p1Radius + p2Radius + tolerance; 21 | if(distance < distanceCheck && collision == false){ 22 | collisionCounter++; 23 | room.sendAnnouncement(`${p1Name} and ${p2Name} are colliding with each other! Total collisions so far: ${collisionCounter}`,null,0xFFFF00,"bold",2); 24 | collision = true; 25 | } 26 | else if(distance >= distanceCheck + tolerance && collision == true){ 27 | collision = false; 28 | } 29 | } 30 | } 31 | 32 | function checkForCollisions(){ 33 | var players = room.getPlayerList(); 34 | var length = players.length; 35 | for(var i=0; i= counterEnd; t += variation) sendTimedAnnouncement(`${t}`, null, colors.white, fonts.normal, sounds.normal, (counterStart + Math.abs(variation) - t) / Math.abs(variation) * 1000); 40 | //timeout (after the countup) = (|counterEnd - counterStart| + 2 * |variation|) / |variation| * 1000 41 | sendTimedAnnouncement(`${endMessage}`, null, colors.white, fonts.normal, sounds.normal, (Math.abs(counterEnd - counterStart) + 2 * Math.abs(variation)) / Math.abs(variation) * 1000); 42 | } 43 | else if (Math.sign(variation) > 0) { //timeout (in for loop) = (t + variation - counterStart) / variation * 1000 44 | for (var t = counterStart; t <= counterEnd; t += variation) sendTimedAnnouncement(`${t}`, null, colors.white, fonts.normal, sounds.normal, (t + variation - counterStart) / variation * 1000); 45 | //timeout (after the countup) = (counterEnd - counterStart + 2 * variation) / variation * 1000 46 | sendTimedAnnouncement(`${endMessage}`, null, colors.white, fonts.normal, sounds.normal, (counterEnd - counterStart + 2 * variation) / variation * 1000); 47 | } 48 | else return false; 49 | } 50 | 51 | function sendTimedAnnouncement(message, target, color, font, sound, timeout) { 52 | setTimeout(function () { room.sendAnnouncement(`${message}`, target, color, font, sound) }, timeout); 53 | } 54 | -------------------------------------------------------------------------------- /Intermediate/FinishLine.js: -------------------------------------------------------------------------------- 1 | var Map = `{"name":"Finish Line","width":420,"height":205,"cameraFollow":"player","spawnDistance":170,"canBeStored":false,"kickOffReset":"full","bg":{"type":"grass","color":"6699CC"},"traits":{"ballArea":{"vis":false,"bCoef":1,"cMask":["ball"]},"goalPost":{"radius":8,"invMass":0,"bCoef":0.5},"goalNet":{"vis":true,"bCoef":0.1,"cMask":["ball"]},"kickOffBarrier":{"vis":false,"bCoef":0.1,"cGroup":["redKO","blueKO"],"cMask":["red","blue"]},"border":{"cMask":["none"],"cGroup":["none"],"color":"008000"},"finishLine":{"cMask":["none"],"cGroup":["none"],"color":"FFFFFF"},"disc0":{"radius":0,"invMass":0,"damping":0,"cMask":["none"],"cGroup":["none"]}},"vertexes":[{"x":300,"y":-205,"trait":"finishLine"},{"x":300,"y":205,"trait":"finishLine"},{"x":-420,"y":-205,"trait":"border"},{"x":420,"y":-205,"trait":"border"},{"x":420,"y":205,"trait":"border"},{"x":-420,"y":205,"trait":"border"}],"segments":[{"v0":0,"v1":1,"trait":"finishLine"},{"v0":2,"v1":3,"trait":"border"},{"v0":3,"v1":4,"trait":"border"},{"v0":4,"v1":5,"trait":"border"},{"v0":5,"v1":2,"trait":"border"}],"goals":[],"discs":[{"pos":[0,0],"trait":"disc0"}],"planes":[{"normal":[0,1],"dist":-205,"bCoef":0,"_data":{"extremes":{"normal":[0,1],"dist":-205,"canvas_rect":[-710,-209,710,210],"a":[-710,-205],"b":[710,-205]}}},{"normal":[0,-1],"dist":-205,"bCoef":0,"_data":{"extremes":{"normal":[0,-1],"dist":-205,"canvas_rect":[-710,-209,710,210],"a":[-710,205],"b":[710,205]}}},{"normal":[1,0],"dist":-420,"bCoef":0,"_data":{"extremes":{"normal":[1,0],"dist":-420,"canvas_rect":[-710,-209,710,210],"a":[-420,-209],"b":[-420,210]}}},{"normal":[-1,0],"dist":-420,"bCoef":0,"_data":{"extremes":{"normal":[-1,0],"dist":-420,"canvas_rect":[-710,-209,710,210],"a":[420,-209],"b":[420,210]}}}],"playerPhysics":{},"ballPhysics":"disc0","cameraWidth":1200,"cameraHeight":600,"maxViewWidth":1200}`; 2 | 3 | var JMap = JSON.parse(Map); //You can check it just for this map. 4 | var finishLine = JMap.vertexes.filter(s => s.trait == "finishLine"); //If your line is vertical, then you should use X coordinate of player position, if horizontal use Y coordinate. In our case, it's vertical. Here we don't evaluate the cases with diagonal or curved line segments. 5 | 6 | var direction = getLineVector(finishLine[0],finishLine[1]); //It's calculated for a single line. For more lines you should create a collection. 7 | var rules = ["H-1","H+1","V-1","V+1"]; 8 | var rule = rules[3]; 9 | 10 | var _room = { 11 | roomName: "Finish Line", 12 | noPlayer: true, 13 | public: false, 14 | maxPlayers: 2, 15 | password: "1234567890", 16 | token: null 17 | }; 18 | 19 | var room = HBInit({ roomName: _room.roomName, noPlayer: _room.noPlayer, public: _room.public, maxPlayers: _room.maxPlayers, password: _room.password, token: _room.token }); 20 | 21 | function checker(){ 22 | var player = room.getPlayerList().filter(p => p.team == 1)[0]; 23 | if(room.getPlayerDiscProperties(player.id) != null){ 24 | if(direction == "Horizontal"){ 25 | if(rule == rules[0]){ 26 | if(room.getPlayerDiscProperties(player.id).y < finishLine[1].y){ 27 | room.stopGame(); 28 | } 29 | } 30 | else if(rule == rules[1]){ 31 | if(room.getPlayerDiscProperties(player.id).y > finishLine[1].y){ 32 | room.stopGame(); 33 | } 34 | } 35 | else{ 36 | return false; 37 | } 38 | } 39 | else if(direction == "Vertical"){ 40 | if(rule == rules[2]){ 41 | if(room.getPlayerDiscProperties(player.id).x < finishLine[1].x){ 42 | room.stopGame(); 43 | } 44 | } 45 | else if(rule == rules[3]){ 46 | if(room.getPlayerDiscProperties(player.id).x > finishLine[1].x){ 47 | room.stopGame(); 48 | } 49 | } 50 | else{ 51 | return false; 52 | } 53 | } 54 | else if(direction == "Diagonal"){ 55 | return false; 56 | } 57 | else{ 58 | return false; 59 | } 60 | } 61 | } 62 | 63 | function getLineVector(v0,v1){ 64 | var division = (v1.y - v0.y) / (v1.x - v0.x); 65 | var direction = Math.abs(division) == 0 ? "Horizontal" : Math.abs(division) == Infinity ? "Vertical" : "Diagonal"; 66 | return direction; 67 | } 68 | 69 | room.onGameStart = function(byPlayer){ 70 | getLineVector(finishLine[0],finishLine[1]); 71 | } 72 | 73 | room.onGameTick = function(){ 74 | checker(); 75 | } 76 | -------------------------------------------------------------------------------- /Intermediate/Goal_AfterEffects.js: -------------------------------------------------------------------------------- 1 | var Map = `{"name":"Classic","width":420,"height":200,"spawnDistance":170,"bg":{"type":"grass","width":370,"height":170,"kickOffRadius":75,"cornerRadius":0},"vertexes":[{"x":-370,"y":170,"trait":"ballArea"},{"x":-370,"y":64,"trait":"ballArea"},{"x":-370,"y":-64,"trait":"ballArea"},{"x":-370,"y":-170,"trait":"ballArea"},{"x":370,"y":170,"trait":"ballArea"},{"x":370,"y":64,"trait":"ballArea"},{"x":370,"y":-64,"trait":"ballArea"},{"x":370,"y":-170,"trait":"ballArea"},{"x":0,"y":200,"trait":"kickOffBarrier"},{"x":0,"y":75,"trait":"kickOffBarrier"},{"x":0,"y":-75,"trait":"kickOffBarrier"},{"x":0,"y":-200,"trait":"kickOffBarrier"},{"x":-380,"y":-64,"trait":"goalNet"},{"x":-400,"y":-44,"trait":"goalNet"},{"x":-400,"y":44,"trait":"goalNet"},{"x":-380,"y":64,"trait":"goalNet"},{"x":380,"y":-64,"trait":"goalNet"},{"x":400,"y":-44,"trait":"goalNet"},{"x":400,"y":44,"trait":"goalNet"},{"x":380,"y":64,"trait":"goalNet"}],"segments":[{"v0":0,"v1":1,"trait":"ballArea"},{"v0":2,"v1":3,"trait":"ballArea"},{"v0":4,"v1":5,"trait":"ballArea"},{"v0":6,"v1":7,"trait":"ballArea"},{"v0":12,"v1":13,"curve":-90,"trait":"goalNet"},{"v0":13,"v1":14,"trait":"goalNet"},{"v0":14,"v1":15,"curve":-90,"trait":"goalNet"},{"v0":16,"v1":17,"curve":90,"trait":"goalNet"},{"v0":17,"v1":18,"trait":"goalNet"},{"v0":18,"v1":19,"curve":90,"trait":"goalNet"},{"v0":8,"v1":9,"trait":"kickOffBarrier"},{"v0":9,"v1":10,"curve":180,"cGroup":["blueKO"],"trait":"kickOffBarrier"},{"v0":9,"v1":10,"curve":-180,"cGroup":["redKO"],"trait":"kickOffBarrier"},{"v0":10,"v1":11,"trait":"kickOffBarrier"}],"goals":[{"p0":[-370,64],"p1":[-370,-64],"team":"red"},{"p0":[370,64],"p1":[370,-64],"team":"blue"}],"discs":[{"pos":[-370,64],"color":"FFCCCC","trait":"goalPost"},{"pos":[-370,-64],"color":"FFCCCC","trait":"goalPost"},{"pos":[370,64],"color":"CCCCFF","trait":"goalPost"},{"pos":[370,-64],"color":"CCCCFF","trait":"goalPost"},{"radius":100,"invMass":0,"pos":[2000,2000],"color":"transparent","bCoef":0,"trait":"circle","damping":0,"speed":[0,0]}],"planes":[{"normal":[0,1],"dist":-170,"trait":"ballArea","_data":{"extremes":{"normal":[0,1],"dist":-170,"canvas_rect":[-710,-213,2100,2100],"a":[-710,-170],"b":[2100,-170]}}},{"normal":[0,-1],"dist":-170,"trait":"ballArea","_data":{"extremes":{"normal":[0,-1],"dist":-170,"canvas_rect":[-710,-213,2100,2100],"a":[-710,170],"b":[2100,170]}}},{"normal":[0,1],"dist":-200,"bCoef":0.1,"_data":{"extremes":{"normal":[0,1],"dist":-200,"canvas_rect":[-710,-213,2100,2100],"a":[-710,-200],"b":[2100,-200]}}},{"normal":[0,-1],"dist":-200,"bCoef":0.1,"_data":{"extremes":{"normal":[0,-1],"dist":-200,"canvas_rect":[-710,-213,2100,2100],"a":[-710,200],"b":[2100,200]}}},{"normal":[1,0],"dist":-420,"bCoef":0.1,"_data":{"extremes":{"normal":[1,0],"dist":-420,"canvas_rect":[-710,-213,2100,2100],"a":[-420,-213],"b":[-420,2100]}}},{"normal":[-1,0],"dist":-420,"bCoef":0.1,"_data":{"extremes":{"normal":[-1,0],"dist":-420,"canvas_rect":[-710,-213,2100,2100],"a":[420,-213],"b":[420,2100]}}}],"traits":{"ballArea":{"vis":false,"bCoef":1,"cMask":["ball"]},"goalPost":{"radius":8,"invMass":0,"bCoef":0.5},"goalNet":{"vis":true,"bCoef":0.1,"cMask":["ball"]},"kickOffBarrier":{"vis":false,"bCoef":0.1,"cGroup":["redKO","blueKO"],"cMask":["red","blue"]},"circle":{"cMask":["c0"],"cGroup":["c0"]}},"joints":[],"redSpawnPoints":[],"blueSpawnPoints":[],"cameraWidth":1500,"cameraHeight":1500,"maxViewWidth":3000,"canBeStored":false,"cameraFollow":"player","kickOffReset":"full"}`; 2 | 3 | var JMap = JSON.parse(Map); 4 | 5 | var discID = JMap.discs.findIndex(x => x.trait == "circle"); //Set a trait with name "circle" 6 | var ballGoalSetProps = {x:0,y:0,xspeed:0,yspeed:0,radius:100}; //You can set it anywhere on stadium 7 | var ballGoalSetTimeout = 5000; //In milliseconds 8 | 9 | var colors = [0xFFFFFF,0xFF0000,0x0000FF]; 10 | var teams = ["Spectators","Red","Blue"]; 11 | var emojis = ["⚪️","🔴","🔵"]; 12 | 13 | var colors = {goalScored: 0xFFFFFF}; 14 | var fonts = {goalScored: "normal"}; 15 | var sounds = {goalScored: 1}; 16 | 17 | var room = HBInit({roomName:"Goal - After Effects",noPlayer:true,public:true,maxPlayers:12}); 18 | 19 | room.onGameStart = function(byPlayer){ 20 | ballGoalSetProps.x = 0; 21 | ballGoalSetProps.y = 0; 22 | } 23 | 24 | room.onGameStop = function(byPlayer){ 25 | ballGoalSetProps.x = 0; 26 | ballGoalSetProps.y = 0; 27 | } 28 | 29 | room.onPlayerBallKick = function(player){ 30 | var ballPosition = room.getBallPosition(); 31 | console.log(`${player.name} has kicked the ball at location {x:${ballPosition.x},y:${ballPosition.y}}`); 32 | 33 | ballGoalSetProps.x = ballPosition.x; 34 | ballGoalSetProps.y = ballPosition.y; 35 | } 36 | 37 | room.onPositionsReset = function(){ 38 | ballGoalSetProps.x = 0; 39 | ballGoalSetProps.y = 0; 40 | } 41 | 42 | room.onTeamGoal = function(team){ 43 | room.sendAnnouncement(`[${emojis[team]}] Goal by ${teams[team]}`,null,colors.goalScored,fonts.goalScored,sounds.goalScored); 44 | room.setDiscProperties(1+discID,{x: ballGoalSetProps.x, y: ballGoalSetProps.y, xspeed: ballGoalSetProps.xspeed, yspeed: ballGoalSetProps.yspeed, radius: ballGoalSetProps.radius, color: colors[team]}); 45 | 46 | setTimeout(function(){ 47 | room.setDiscProperties(1+discID,{x: JMap.discs[discID].pos[0], y: JMap.discs[discID].pos[1], xspeed: JMap.discs[discID].speed[0], yspeed: JMap.discs[discID].speed[1], radius: JMap.discs[discID].radius, color: JMap.discs[discID].color}); 48 | },ballGoalSetTimeout); 49 | } 50 | -------------------------------------------------------------------------------- /Intermediate/Ignore.js: -------------------------------------------------------------------------------- 1 | var messageBlocks = {}; 2 | var ignoreCommands = ["!chatoff","!chaton"]; 3 | 4 | var ignoreSetMessages = [ 5 | "You can't ignore your own messages", 6 | " has been ignored successfully. You won't see their messages.", 7 | "This player is already ignored.", 8 | "There's no such a player with the given ID.", 9 | ]; 10 | var ignoreRemovalMessages = [ 11 | "This operation cannot be executed on yourselves.", 12 | "'s ignore status has been removed. You can now see their messages.", 13 | "This player is not in your ignore list.", 14 | "There's no such a player with the given ID." 15 | ] 16 | 17 | var ignoreMessageSets = [ignoreSetMessages,ignoreRemovalMessages]; 18 | 19 | var colors = [0xFFFF00,0x00FF00,0xFFFF00,0xFF0000,0xFFFFFF,0x97FFFF]; 20 | var fonts = ["bold","bold","bold","bold","bold","bold"]; 21 | var sounds = [2,1,2,2,1,1]; 22 | 23 | var room = HBInit({roomName:"Ignore Messages from Certain Players",noPlayer:true,public:false,maxPlayers:12}); 24 | 25 | room.onPlayerJoin = function(player){ 26 | console.log(`${player.name} has joined`); 27 | if(messageBlocks[player.name] == undefined){ 28 | messageBlocks[player.name] = {name: player.name, blocking: []}; 29 | } 30 | } 31 | 32 | room.onPlayerChat = function(player,message){ 33 | console.log(`${player.name}: ${message}`); 34 | var players = room.getPlayerList(); 35 | var recipients = players.filter(p => messageBlocks[p.name].blocking.includes(player.id) == false); 36 | var command = message.toLowerCase().split(" ")[0]; 37 | 38 | if(ignoreCommands.includes(command) == true){ 39 | var index = ignoreCommands.indexOf(command); 40 | var ID = parseInt(message.toLowerCase().split(" ")[1]); 41 | var p = players.find(x => x.id == ID); 42 | 43 | if(p){ 44 | if(p.id == player.id){ 45 | room.sendAnnouncement(`${ignoreMessageSets[index][0]} (ID: ${ID})`,player.id,colors[0],fonts[0],sounds[0]); 46 | return false; 47 | } 48 | else{ 49 | if(messageBlocks[player.name].blocking.includes(p.id) == false){ 50 | if(index == 0){ 51 | messageBlocks[player.name].blocking.push(p.id); 52 | room.sendAnnouncement(`${p.name}${ignoreMessageSets[index][1]} (ID: ${ID})`,player.id,colors[1],fonts[1],sounds[1]); 53 | return false; 54 | } 55 | else if(index == 1){ 56 | room.sendAnnouncement(`${ignoreMessageSets[index][2]} (ID: ${ID})`,player.id,colors[2],fonts[2],sounds[2]); 57 | return false; 58 | } 59 | else{ 60 | console.log("Error"); 61 | return false; 62 | } 63 | } 64 | else{ 65 | if(index == 0){ 66 | room.sendAnnouncement(`${ignoreMessageSets[index][2]} (ID: ${ID})`,player.id,colors[2],fonts[2],sounds[2]); 67 | return false; 68 | } 69 | else if(index == 1){ 70 | var i = messageBlocks[player.name].blocking.indexOf(p.id); 71 | messageBlocks[player.name].blocking.splice(i,1); 72 | room.sendAnnouncement(`${p.name}${ignoreMessageSets[index][1]} (ID: ${ID})`,player.id,colors[1],fonts[1],sounds[1]); 73 | return false; 74 | } 75 | else{ 76 | console.log("Error"); 77 | return false; 78 | } 79 | } 80 | } 81 | } 82 | else{ 83 | room.sendAnnouncement(`${ignoreMessageSets[index][3]} (ID: ${ID})`,player.id,colors[3],fonts[3],sounds[3]); 84 | return false; 85 | } 86 | } 87 | else{ 88 | if(player.admin == false){ 89 | recipients.forEach(p => { 90 | room.sendAnnouncement(`${player.name}: ${message}`,p.id,colors[4],fonts[4],sounds[4]); 91 | }); 92 | return false; 93 | } 94 | else{ 95 | recipients.forEach(p => { 96 | room.sendAnnouncement(`${player.name}: ${message}`,p.id,colors[5],fonts[5],sounds[5]); 97 | }); 98 | return false; 99 | } 100 | } 101 | } 102 | -------------------------------------------------------------------------------- /Intermediate/Login.js: -------------------------------------------------------------------------------- 1 | var banTimeout = 60000; //In milliseconds 2 | var pcTimeout = 20000; //In milliseconds 3 | var playerList = {}; 4 | var teams = ["spectators","red","blue"]; 5 | var templist = []; 6 | var timeLimit = 300; //In seconds 7 | 8 | var room = HBInit({roomName:"Login",noPlayer:true,public:true,maxPlayers:20}); 9 | 10 | function increaseInGameTime(){ 11 | room.getPlayerList().filter(p => p.team != 0).forEach(p => { 12 | playerList[p.name].timeSpentInGame += 1/60 13 | }); 14 | } 15 | 16 | function resetInGameTime(){ 17 | room.getPlayerList().filter(p => playerList[p.name].timeSpentInGame != 0).forEach(p => { 18 | playerList[p.name].timeSpentInGame = 0 19 | }); 20 | } 21 | 22 | room.onGameStop = function(byPlayer){ 23 | resetInGameTime(); 24 | } 25 | 26 | room.onGameTick = function(){ 27 | increaseInGameTime(); 28 | } 29 | 30 | room.onPlayerJoin = function(player){ 31 | var passCheckTimeout; 32 | 33 | if(templist.includes(player.auth) == true){ 34 | if(playerList[player.name] == undefined){ 35 | console.log("Something went wrong"); 36 | } 37 | else{ 38 | room.kickPlayer(player.id,"You are temporarily banned from this room. Please wait for your punishment to end. (" + playerList[player.name].punishmentRemoval + ")",false); 39 | } 40 | } 41 | else{ 42 | if(playerList[player.name] == undefined){ 43 | playerList[player.name] = {name: player.name, auth: player.auth, conn: player.conn, timeSpentInGame: 0, pass: "1234", passCheck: true, punishmentRemoval: undefined}; //Burayı bir tür kayıt sistemi gibi kullanabilirsin. Oyuncu daha önceden odaya giriş yapmışsa, pass bilgisini istesin. 44 | } 45 | else{ 46 | playerList[player.name] = {name: player.name, auth: player.auth, conn: player.conn, timeSpentInGame: 0, pass: "1234", passCheck: false, punishmentRemoval: undefined}; 47 | room.sendAnnouncement("You must be logged in to continue.",player.id,0xFFFF00,"bold",2); 48 | 49 | passCheckTimeout = setTimeout(function(){ 50 | if(player && playerList[player.name].passCheck == false){ 51 | room.kickPlayer(player.id,"Login failed.",false); 52 | } 53 | },pcTimeout); 54 | } 55 | } 56 | } 57 | 58 | room.onPlayerChat = function(player,message){ 59 | if(playerList[player.name].passCheck == false){ 60 | if(message == playerList[player.name].pass){ 61 | playerList[player.name].passCheck = true; 62 | room.sendAnnouncement("You have successfully logged in!",player.id,0x00FF00,"bold",2); 63 | return false; 64 | } 65 | } 66 | } 67 | 68 | room.onPlayerLeave = function(player){ 69 | var name = player.name; 70 | var date = (new Date(Date.now() + banTimeout)).toLocaleTimeString(); 71 | 72 | if(room.getScores() != null){ 73 | if(player.team != 0 && playerList[name].timeSpentInGame > timeLimit){ //Oyunda belli bir süreden uzun süre kalmış oyuncular odadan çıktığında burası devreye girer. 74 | if(templist && templist.includes(playerList[name].auth) == false){ 75 | templist.push(playerList[name].auth); 76 | playerList[name].punishmentRemoval = date; 77 | setTimeout(function(){ 78 | if(templist && templist.includes(playerList[name].auth) == true){ 79 | let index = templist.indexOf(playerList[name].auth); 80 | templist.splice(index,1); 81 | } 82 | },banTimeout); 83 | 84 | room.sendAnnouncement(`${name} from the ${teams[player.team]} has been punished until ${date} due to leaving the room during the match!`,null,0xFFFF00,"bold",1); 85 | } 86 | } 87 | } 88 | } 89 | -------------------------------------------------------------------------------- /Intermediate/MapVote.js: -------------------------------------------------------------------------------- 1 | var Map1 = `{"name":"New Stadium 1","width":420,"height":200,"cameraWidth":0,"cameraHeight":0,"maxViewWidth":0,"cameraFollow":"ball","spawnDistance":170,"redSpawnPoints":[],"blueSpawnPoints":[],"canBeStored":false,"kickOffReset":"partial","bg":{"color":"718C5A"},"traits":{"ballArea":{"vis":false,"bCoef":1,"cMask":["ball"]},"goalPost":{"radius":8,"invMass":0,"bCoef":0.5},"goalNet":{"vis":true,"bCoef":0.1,"cMask":["ball"]},"kickOffBarrier":{"vis":false,"bCoef":0.1,"cGroup":["redKO","blueKO"],"cMask":["red","blue"]}},"vertexes":[],"segments":[],"goals":[],"discs":[],"planes":[],"joints":[],"playerPhysics":{"radius":15,"bCoef":0.5,"invMass":0.5,"damping":0.96,"cGroup":["red","blue"],"acceleration":0.1,"gravity":[0,0],"kickingAcceleration":0.07,"kickingDamping":0.96,"kickStrength":5,"kickback":0},"ballPhysics":{"radius":10,"bCoef":0.5,"cMask":["all"],"damping":0.99,"invMass":1,"gravity":[0,0],"color":"ffffff","cGroup":["ball"]}}` 2 | var Map2 = `{"name":"New Stadium 2","width":420,"height":200,"cameraWidth":0,"cameraHeight":0,"maxViewWidth":0,"cameraFollow":"ball","spawnDistance":170,"redSpawnPoints":[],"blueSpawnPoints":[],"canBeStored":false,"kickOffReset":"partial","bg":{"color":"718C5A"},"traits":{"ballArea":{"vis":false,"bCoef":1,"cMask":["ball"]},"goalPost":{"radius":8,"invMass":0,"bCoef":0.5},"goalNet":{"vis":true,"bCoef":0.1,"cMask":["ball"]},"kickOffBarrier":{"vis":false,"bCoef":0.1,"cGroup":["redKO","blueKO"],"cMask":["red","blue"]}},"vertexes":[],"segments":[],"goals":[],"discs":[],"planes":[],"joints":[],"playerPhysics":{"radius":15,"bCoef":0.5,"invMass":0.5,"damping":0.96,"cGroup":["red","blue"],"acceleration":0.1,"gravity":[0,0],"kickingAcceleration":0.07,"kickingDamping":0.96,"kickStrength":5,"kickback":0},"ballPhysics":{"radius":10,"bCoef":0.5,"cMask":["all"],"damping":0.99,"invMass":1,"gravity":[0,0],"color":"ffffff","cGroup":["ball"]}}` 3 | var Map3 = `{"name":"New Stadium 3","width":420,"height":200,"cameraWidth":0,"cameraHeight":0,"maxViewWidth":0,"cameraFollow":"ball","spawnDistance":170,"redSpawnPoints":[],"blueSpawnPoints":[],"canBeStored":false,"kickOffReset":"partial","bg":{"color":"718C5A"},"traits":{"ballArea":{"vis":false,"bCoef":1,"cMask":["ball"]},"goalPost":{"radius":8,"invMass":0,"bCoef":0.5},"goalNet":{"vis":true,"bCoef":0.1,"cMask":["ball"]},"kickOffBarrier":{"vis":false,"bCoef":0.1,"cGroup":["redKO","blueKO"],"cMask":["red","blue"]}},"vertexes":[],"segments":[],"goals":[],"discs":[],"planes":[],"joints":[],"playerPhysics":{"radius":15,"bCoef":0.5,"invMass":0.5,"damping":0.96,"cGroup":["red","blue"],"acceleration":0.1,"gravity":[0,0],"kickingAcceleration":0.07,"kickingDamping":0.96,"kickStrength":5,"kickback":0},"ballPhysics":{"radius":10,"bCoef":0.5,"cMask":["all"],"damping":0.99,"invMass":1,"gravity":[0,0],"color":"ffffff","cGroup":["ball"]}}` 4 | 5 | var MapVote = `{"name":"Map Vote","width":420,"height":200,"cameraWidth":0,"cameraHeight":0,"maxViewWidth":0,"cameraFollow":"ball","spawnDistance":170,"redSpawnPoints":[],"blueSpawnPoints":[],"canBeStored":false,"kickOffReset":"partial","bg":{"color":"718C5A"},"traits":{"ballArea":{"vis":false,"bCoef":1,"cMask":["ball"]},"goalPost":{"radius":8,"invMass":0,"bCoef":0.5},"goalNet":{"vis":true,"bCoef":0.1,"cMask":["ball"]},"kickOffBarrier":{"vis":false,"bCoef":0.1,"cGroup":["redKO","blueKO"],"cMask":["red","blue"]}},"vertexes":[],"segments":[],"goals":[],"discs":[],"planes":[],"joints":[],"playerPhysics":{"radius":15,"bCoef":0.5,"invMass":0.5,"damping":0.96,"cGroup":["red","blue"],"acceleration":0.1,"gravity":[0,0],"kickingAcceleration":0.07,"kickingDamping":0.96,"kickStrength":5,"kickback":0},"ballPhysics":{"radius":10,"bCoef":0.5,"cMask":["all"],"damping":0.99,"invMass":1,"gravity":[0,0],"color":"ffffff","cGroup":["ball"]}}` 6 | 7 | var JMap1 = JSON.parse(Map1); 8 | var JMap2 = JSON.parse(Map2); 9 | var JMap3 = JSON.parse(Map3); 10 | 11 | var _Map1 = {MapObject: Map1, Name: JMap1.Name, ScoreLimit: 1, TimeLimit: 1, Votes: 0}; 12 | var _Map2 = {MapObject: Map2, Name: JMap2.Name, ScoreLimit: 2, TimeLimit: 2, Votes: 0}; 13 | var _Map3 = {MapObject: Map3, Name: JMap3.Name, ScoreLimit: 3, TimeLimit: 3, Votes: 0}; 14 | 15 | var Maps = [_Map1,_Map2,_Map3]; 16 | 17 | var VoteCommand = "!vote"; 18 | var VotedPlayers = []; 19 | var Votes = []; 20 | var VoteSession = false; 21 | 22 | var GetVotesAndAnnounceResults_Timeout_1; 23 | var GetVotesAndAnnounceResults_Timeout_2; 24 | 25 | var MapStartWaitTimeout = 3000; //In milliseconds 26 | var VoteTimeout = 15000; //In milliseconds 27 | 28 | var room = HBInit({roomName:"Map Vote",noPlayer:true,public:true,maxPlayers:30}); 29 | 30 | function getVotesAndAnnounceResults(){ 31 | if(VoteSession == false){ 32 | VoteSession = true; 33 | } 34 | 35 | room.sendAnnouncement(`Map voting session has begun! You have ${VoteTimeout/1000} seconds to vote a map.`,null,0x00FFFF,"bold",2); 36 | GetVotesAndAnnounceResults_Timeout_1 = setTimeout(function(){ 37 | room.sendAnnouncement(`Map voting session has ended! Here's the results:`,null,0x00FFFF,"bold",2); 38 | for(var Map in Maps){ 39 | room.sendAnnouncement(`${Map.Name}: ${Map.Votes}`,null,0xFFFFFF,"normal",1); 40 | Votes.push(Map.Votes); 41 | } 42 | if(VoteSession == true){ 43 | VoteSession = false; 44 | } 45 | },VoteTimeout); 46 | 47 | var sorted = Votes.sort(function(v1,v2){ 48 | return v1-v2; 49 | }); 50 | 51 | var MaxVotedMaps = Maps.filter(m => m.Votes == sorted[0]); 52 | 53 | GetVotesAndAnnounceResults_Timeout_2 = setTimeout(function(){ 54 | if(MaxVotedMaps.length == 0){ 55 | console.log("Something went wrong."); 56 | var admins = room.getPlayerList().filter(p => p.admin == true); 57 | var nonadmins = room.getPlayerList().filter(p => p.admin == false); 58 | admins.forEach(a => { 59 | room.sendAnnouncement("Oops! Something went wrong! Please open a map manually.",0xFFFF00,a.id,"bold",2) 60 | }); 61 | nonadmins.forEach(n => { 62 | room.sendAnnouncement("Map will be loaded manually by an human administrator. Please wait...",0xFFFF00,n.id,"bold",2) 63 | }); 64 | 65 | //var randomInt = Math.floor(Maps.length * Math.random()); 66 | //loadMap(Maps[randomInt].MapObject,MaxVotedMaps[randomInt].ScoreLimit,MaxVotedMaps[randomInt].TimeLimit); 67 | //room.sendAnnouncement(`${MaxVotedMaps[randomInt].Name} was loaded randomly as the result of the voting session. Good games!`,null,0x00FF00,"bold",2); 68 | } 69 | else if(MaxVotedMaps.length == 1){ 70 | loadMap(MaxVotedMaps[0].MapObject,MaxVotedMaps[0].ScoreLimit,MaxVotedMaps[0].TimeLimit); 71 | room.sendAnnouncement(`${MaxVotedMaps[0].Name} was loaded as the result of the voting session. Good games!`,null,0x00FF00,"bold",2); 72 | } 73 | else{ 74 | var randomInt = Math.floor(MaxVotedMaps.length * Math.random()); 75 | loadMap(MaxVotedMaps[randomInt].MapObject,MaxVotedMaps[randomInt].ScoreLimit,MaxVotedMaps[randomInt].TimeLimit); 76 | room.sendAnnouncement(`${MaxVotedMaps[randomInt].Name} was loaded randomly between the max voted maps as the result of the voting session. Good games!`,null,0x00FF00,"bold",2); 77 | } 78 | },MapStartWaitTimeout); 79 | 80 | resetVotes(); 81 | } 82 | 83 | function loadMap(Map,ScoreLimit,TimeLimit){ 84 | room.setCustomStadium(Map); 85 | room.setScoreLimit(ScoreLimit); 86 | room.setTimeLimit(TimeLimit); 87 | room.startGame(); 88 | } 89 | 90 | function resetVotes(){ 91 | if(VotedPlayers.length != 0){ 92 | VotedPlayers = []; 93 | } 94 | if(Votes.length != 0){ 95 | Votes = []; 96 | } 97 | for(var Map in Maps){ 98 | if(Map.Votes != 0){ 99 | Map.Votes = 0; 100 | } 101 | } 102 | } 103 | 104 | function voteMap(player,message){ //Command example: !vote 1 105 | var mapToVote = parseInt(message.split(" ")[1]); 106 | 107 | if(VotedPlayers.length == 0){ 108 | VotedPlayers.push(player.name); 109 | Maps[mapToVote-1].Votes++; 110 | room.sendAnnouncement(`${player.name} has voted for ${Maps[mapToVote-1].Name}`,null,0x00FF00,"bold",2); 111 | } 112 | else{ 113 | if(VotedPlayers.includes(player.name) == true){ 114 | room.sendAnnouncement("You have already voted for a map! Please wait for the voting session to end.",player.id,0xFF0000,"bold",2); 115 | } 116 | else{ 117 | VotedPlayers.push(player.name); 118 | Maps[mapToVote-1].Votes++; 119 | room.sendAnnouncement(`${player.name} has voted for ${Maps[mapToVote-1].Name}`,null,0x00FF00,"bold",2); 120 | } 121 | } 122 | } 123 | 124 | room.onGameStop = function(byPlayer){ 125 | clearTimeout(GetVotesAndAnnounceResults_Timeout_1); 126 | clearTimeout(GetVotesAndAnnounceResults_Timeout_2); 127 | loadMap(MapVote,0,0); 128 | } 129 | 130 | room.onPlayerChat = function(player,message){ 131 | var admins = room.getPlayerList().filter(p => p.admin == true); 132 | 133 | if(VoteSession == true){ 134 | if(message.split(" ")[0] == VoteCommand){ 135 | voteMap(player,message); 136 | } 137 | else{ 138 | room.sendAnnouncement("Please wait for the voting session to end.",player.id,0xFFFF00,"bold",2); 139 | admins.forEach(a => { 140 | room.sendAnnouncement(`${player.name}: ${message}`,0xFFFF00,a.id,"bold",1) 141 | }); 142 | } 143 | return false; 144 | } 145 | } 146 | 147 | room.onStadiumChange = function(newStadiumName,byPlayer){ 148 | if(newStadiumName == "Map Vote"){ 149 | getVotesAndAnnounceResults(); 150 | } 151 | } 152 | -------------------------------------------------------------------------------- /Intermediate/PlayerFreeze.js: -------------------------------------------------------------------------------- 1 | var freeze = []; //Holds the name of the frozen players. 2 | var playerInformations = []; //Holds players names, ID's and positions (undefined if not frozen). 3 | 4 | var room = HBInit({ roomName: "Player Freeze", noPlayer: true, public: false, maxPlayers: 2}); 5 | 6 | function createPlayer(player){ //Create player informations, it will be used in the room.onPlayerJoin() event. 7 | playerInformations[playerInformations.length] = { 8 | name:player.name, 9 | id:player.id, 10 | freezePoint:{ 11 | x:undefined, 12 | y:undefined 13 | } 14 | } 15 | } 16 | 17 | function deletePlayer(id){ //Delete player informations, it will be used in the room.onPlayerLeave() event. 18 | for(var i=0; i 0){ 43 | room.setPlayerDiscProperties(players[i].id,{x:getPlayerByID(players[i].id).freezePoint.x,y:getPlayerByID(players[i].id).freezePoint.y,xspeed:0,yspeed:0}); 44 | } 45 | } 46 | } 47 | 48 | room.onPlayerJoin = function (player){ //Creates player informations as they join the room. 49 | console.log(player.name + " has joined."); 50 | createPlayer(player); 51 | } 52 | 53 | room.onPlayerLeave = function (player){ //Deletes player informations as they leave the room. 54 | console.log(player.name + " has left."); 55 | deletePlayer(player); 56 | } 57 | 58 | room.onPlayerKicked = function(kickedPlayer,reason,ban,byPlayer){ //Here is triggered if a player is kicked or banned. 59 | if(byPlayer==null){ 60 | if(ban==0){ 61 | console.log(kickedPlayer.name + " was kicked (" + reason + ")"); 62 | } 63 | else if(ban==1){ 64 | console.log(kickedPlayer.name + " was banned (" + reason + ")"); 65 | } 66 | } 67 | else if(byPlayer!=null){ 68 | if(ban==0){ 69 | console.log(kickedPlayer.name + " was kicked by " + byPlayer.name + " (" + reason + ")"); 70 | } 71 | else if(ban==1){ 72 | console.log(kickedPlayer.name + " was banned by " + byPlayer.name + " (" + reason + ")"); 73 | } 74 | } 75 | }; 76 | 77 | room.onPlayerTeamChange = function(changedPlayer,byPlayer){ //If the team of a player is changed, then it's also should be checked. For example, if a player is moved to spectators, then they have to be deleted from frozen players. Or if a player is moved to any of the teams, then their freeze point has to be negatiated. 78 | if(byPlayer==null){ 79 | if(changedPlayer.team==0){ 80 | console.log(changedPlayer.name + " was moved to Spectators"); 81 | if(freeze.includes(changedPlayer.name) == true){ 82 | freeze.splice(freeze.indexOf(changedPlayer.name),1); 83 | getPlayerByID(changedPlayer.id).freezePoint = {x:undefined,y:undefined}; 84 | } 85 | } 86 | else if(changedPlayer.team==1){ 87 | console.log(changedPlayer.name + " was moved to Red"); 88 | if(freeze.includes(changedPlayer.name) == true){ 89 | getPlayerByID(changedPlayer.id).freezePoint.x = -getPlayerByID(changedPlayer.id).freezePoint.x; 90 | } 91 | } 92 | else if(changedPlayer.team==2){ 93 | console.log(changedPlayer.name + " was moved to Blue"); 94 | if(freeze.includes(changedPlayer.name) == true){ 95 | getPlayerByID(changedPlayer.id).freezePoint.x = -getPlayerByID(changedPlayer.id).freezePoint.x; 96 | } 97 | } 98 | } 99 | else if(byPlayer!=null){ 100 | if(changedPlayer.team==0){ 101 | console.log(changedPlayer.name + " was moved to Spectators by " + byPlayer.name + " [" + byPlayer.id + "]"); 102 | if(freeze.includes(changedPlayer.name) == true){ 103 | freeze.splice(freeze.indexOf(changedPlayer.name),1); 104 | getPlayerByID(changedPlayer.id).freezePoint = {x:undefined,y:undefined}; 105 | } 106 | } 107 | else if(changedPlayer.team==1){ 108 | console.log(changedPlayer.name + " was moved to Red by " + byPlayer.name + " [" + byPlayer.id + "]"); 109 | if(freeze.includes(changedPlayer.name) == true){ 110 | getPlayerByID(changedPlayer.id).freezePoint.x = -getPlayerByID(changedPlayer.id).freezePoint.x; 111 | } 112 | } 113 | else if(changedPlayer.team==2){ 114 | console.log(changedPlayer.name + " was moved to Blue by " + byPlayer.name + " [" + byPlayer.id + "]"); 115 | if(freeze.includes(changedPlayer.name) == true){ 116 | getPlayerByID(changedPlayer.id).freezePoint.x = -getPlayerByID(changedPlayer.id).freezePoint.x; 117 | } 118 | } 119 | } 120 | }; 121 | 122 | room.onPlayerChat = function (player, message){ //Only the admins can freeze the players. Spectators and frozen players cannot be frozen; and spectators and melt players cannot be melt. 123 | console.log(player.name + ": " + message); 124 | var players = room.getPlayerList(); 125 | 126 | if(message.toLowerCase() == "!admin"){ 127 | room.setPlayerAdmin(player.id,!player.admin); 128 | } 129 | 130 | if(player.admin == true){ 131 | if(room.getScores() != null){ 132 | for(var i=0; i 0){ 177 | freeze = []; 178 | } 179 | } 180 | 181 | room.onGameStop = function(byPlayer){ //If the list of frozen players has something as game stops, then it has to be cleared. 182 | if(freeze.length > 0){ 183 | freeze = []; 184 | } 185 | } 186 | 187 | room.onGameTick = function(){ //Frozen player move detector has to be used here, not in room.onPlayerActivity() event. If so, player is not moved to their freeze point as they pressing a direction key. 188 | handleFrozenPlayerMoves(); 189 | } 190 | -------------------------------------------------------------------------------- /Intermediate/Player_Teleport_After_KickOff.js: -------------------------------------------------------------------------------- 1 | var collisionTicks = 0; 2 | var kickCount = 0; 3 | var nextToKickOff = 1; 4 | var teleportPoints = [{ x: -300, y: 0, xspeed: 0, yspeed: 0 }, { x: 300, y: 0, xspeed: 0, yspeed: 0 }]; 5 | 6 | var assistingTouch = ""; 7 | var lastPlayerTouched = undefined; 8 | var lastTeamTouched = 0; 9 | var previousPlayerTouched = undefined; 10 | 11 | var triggerDistance = 25.01; 12 | 13 | var teleportStatus = false; 14 | 15 | var room = HBInit({ roomName: "Player Teleport After Kick-off", noPlayer: true, public: false, maxPlayers: 3 }); 16 | 17 | function ifPlayerIsInGame(player) { 18 | return room.getPlayerDiscProperties(player.id) != null; 19 | } 20 | 21 | function ifPlayerNotTeleported(player) { 22 | return ifPlayerIsInGame(player) == true && (room.getPlayerDiscProperties(player.id).x != teleportPoints[player.team - 1].x || room.getPlayerDiscProperties(player.id).y != teleportPoints[player.team - 1].y); 23 | } 24 | 25 | function increaseKickCount() { 26 | kickCount++; 27 | } 28 | 29 | function increaseCollisionTicks() { 30 | collisionTicks += 1 / 60; 31 | } 32 | 33 | function pointDistance(p1, p2) { 34 | return Math.hypot(p1.x - p2.x, p1.y - p2.y); 35 | } 36 | 37 | function resetCollisionTicks() { 38 | if (collisionTicks != 0) collisionTicks = 0; 39 | } 40 | 41 | function resetKickCount() { 42 | if (kickCount != 0) kickCount = 0; 43 | } 44 | 45 | function resetLastToucher() { 46 | if (assistingTouch != "" || lastPlayerTouched != undefined || lastTeamTouched != 0 || previousPlayerTouched != undefined) { 47 | assistingTouch = ""; 48 | lastPlayerTouched = undefined; 49 | lastPlayerTouched = 0; 50 | previousPlayerTouched = undefined; 51 | } 52 | } 53 | 54 | function resetNextToKickOff() { 55 | if (nextToKickOff != 1) nextToKickOff = 1; 56 | } 57 | 58 | function resetTeleportStatus() { 59 | if (teleportStatus == true) teleportStatus = false; 60 | } 61 | 62 | function setNextToKickOff(team) { 63 | nextToKickOff = 3 - team; 64 | } 65 | 66 | function teleportPlayerAfterKickOff_Kick(player) { 67 | if (nextToKickOff == 1) { 68 | if (kickCount == 1) { 69 | if (ifPlayerIsInGame(player) == true) { 70 | if (player.team == nextToKickOff) { 71 | if (ifPlayerNotTeleported(player) == true) { 72 | if (teleportStatus == false) { 73 | room.setPlayerDiscProperties(player.id, { x: teleportPoints[player.team - 1].x, y: teleportPoints[player.team - 1].y, xspeed: teleportPoints[player.team - 1].xspeed, yspeed: teleportPoints[player.team - 1].yspeed }); 74 | teleportStatus = true; 75 | } 76 | } 77 | } 78 | } 79 | } 80 | } 81 | } 82 | 83 | function teleportPlayerAfterKickOff_Tick(player) { 84 | if (nextToKickOff == 1) { 85 | if (0 < collisionTicks && collisionTicks <= 1 / 60) { 86 | if (ifPlayerIsInGame(player) == true) { 87 | if (player.team == nextToKickOff) { 88 | if (ifPlayerNotTeleported(player) == true) { 89 | if (teleportStatus == false) { 90 | room.setPlayerDiscProperties(player.id, { x: teleportPoints[player.team - 1].x, y: teleportPoints[player.team - 1].y, xspeed: teleportPoints[player.team - 1].xspeed, yspeed: teleportPoints[player.team - 1].yspeed }); 91 | teleportStatus = true; 92 | } 93 | } 94 | } 95 | } 96 | } 97 | } 98 | } 99 | 100 | function updateLastToucher() { 101 | var ballPosition = room.getBallPosition(); 102 | var players = room.getPlayerList(); 103 | for (var i = 0; i < players.length; i++) { 104 | if (players[i].position != null) { 105 | var distanceToBall = pointDistance(players[i].position, ballPosition); 106 | if (distanceToBall < triggerDistance) { 107 | increaseCollisionTicks(); 108 | if (lastPlayerTouched != players[i]) { 109 | if (lastTeamTouched == players[i].team) { 110 | assistingTouch = lastPlayerTouched; 111 | } else assistingTouch = ""; 112 | } 113 | lastTeamTouched = players[i].team; 114 | previousPlayerTouched == lastPlayerTouched; 115 | lastPlayerTouched = players[i]; 116 | point = room.getBallPosition(); 117 | } 118 | } 119 | } 120 | return lastPlayerTouched; 121 | } 122 | 123 | room.onGameStart = function (byPlayer) { 124 | resetCollisionTicks(); 125 | resetKickCount(); 126 | resetLastToucher(); 127 | resetNextToKickOff(); 128 | resetTeleportStatus(); 129 | } 130 | 131 | room.onGameStop = function (byPlayer) { 132 | resetCollisionTicks(); 133 | resetKickCount(); 134 | resetLastToucher(); 135 | resetNextToKickOff(); 136 | resetTeleportStatus(); 137 | } 138 | 139 | room.onGameTick = function () { 140 | if (room.getPlayerList().filter(p => p.team != 0).length > 0) { 141 | room.getPlayerList().filter(p => p.team != 0).forEach(p => teleportPlayerAfterKickOff_Tick(p)); 142 | updateLastToucher(); 143 | } 144 | } 145 | 146 | room.onPlayerJoin = function (player) { 147 | room.setPlayerAdmin(player.id, true); 148 | } 149 | 150 | room.onPlayerBallKick = function (player) { 151 | increaseKickCount(); 152 | teleportPlayerAfterKickOff_Kick(player); 153 | } 154 | 155 | room.onPositionsReset = function () { 156 | resetCollisionTicks(); 157 | resetKickCount(); 158 | resetLastToucher(); 159 | resetTeleportStatus(); 160 | } 161 | 162 | room.onTeamGoal = function (team) { 163 | setNextToKickOff(team); 164 | } 165 | -------------------------------------------------------------------------------- /Intermediate/Register-Login.js: -------------------------------------------------------------------------------- 1 | var room = HBInit({ roomName: "Register & Login", noPlayer: true, public: false, maxPlayers: 20 }); 2 | 3 | var playerList = {}; 4 | var passwordLengths = { min: 4, max: 8 }; 5 | var loginTimeout = 15; 6 | 7 | function findRegisteredUser(player) { 8 | if (Object.keys(playerList).length > 0) { 9 | var otherUserIndex = Object.keys(playerList).findIndex(p => p != player.name && (playerList[p].auth == player.auth || playerList[p].conn == player.conn)); 10 | var otherUserName = otherUserIndex !== -1 ? Object.keys(playerList)[otherUserIndex] : undefined; 11 | return otherUserName; 12 | } else { 13 | return undefined; 14 | } 15 | } 16 | 17 | function isInTheLimits(input, min, max) { 18 | return min <= input && input <= max; 19 | } 20 | 21 | room.onPlayerJoin = function(player) { 22 | if (playerList[player.name] == undefined) { 23 | var otherUserName = findRegisteredUser(player); 24 | if (otherUserName == undefined) { 25 | room.sendAnnouncement(`You are seeming like unregistered. In order to use the functionality, please get registered in ${loginTimeout} seconds (!register [xxxx])`, player.id, 0xFFFFFF, "bold", 2); 26 | setTimeout(function() { 27 | if (playerList[player.name] == undefined || (playerList[player.name] != undefined && playerList[player.name].registered == false)) { 28 | room.kickPlayer(player.id, "You are not registered.", false); 29 | } else { 30 | var password = playerList[player.name].password; 31 | playerList[player.name] = { name: player.name, auth: player.auth, conn: player.conn, password: password, registered: true, loggedIn: false }; 32 | } 33 | }, loginTimeout * 1000); 34 | } else { 35 | room.kickPlayer(player.id, `Might you have joined as ${otherUserName}?`, false); 36 | } 37 | } else { 38 | room.sendAnnouncement(`Registered user... Please type your password and complete login in ${loginTimeout} seconds (!login [xxxx])`, player.id, 0xFFFFFF, "bold", 2); 39 | setTimeout(function() { 40 | if (playerList[player.name].registered == true && playerList[player.name].loggedIn == false) { 41 | if (player) room.kickPlayer(player.id, "You are not logged in.", false); 42 | } else { 43 | if (player) var password = playerList[player.name].password; 44 | playerList[player.name] = { name: player.name, auth: player.auth, conn: player.conn, password: password, registered: true, loggedIn: true }; 45 | } 46 | }, loginTimeout * 1000); 47 | } 48 | } 49 | 50 | room.onPlayerLeave = function(player) { 51 | if (Object.keys(playerList).length > 0) { 52 | if (playerList[player.name] != undefined && playerList[player.name].loggedIn == true) { 53 | playerList[player.name].loggedIn = false; 54 | } 55 | } 56 | } 57 | 58 | room.onPlayerChat = function(player, message) { 59 | var splitted = message.split(" "); 60 | if (splitted[0] == "!register") { 61 | if (playerList[player.name] == undefined || (playerList[player.name] != undefined && playerList[player.name].registered == false)) { 62 | if (splitted.length == 2) { 63 | var password = splitted[1]; 64 | if (password != undefined) { 65 | if (isInTheLimits(password.length, passwordLengths.min, passwordLengths.max)) { 66 | room.sendAnnouncement("You have registered!", player.id, 0x00FF00, "normal", 1); 67 | playerList[player.name] = { name: player.name, auth: null, conn: null, password: password, registered: true, loggedIn: false }; 68 | return false; 69 | } else { 70 | room.sendAnnouncement(`Your password must be within a length between ${passwordLengths.min} and ${passwordLengths.max}!`, player.id, 0xFF0000, "bold", 2); 71 | return false; 72 | } 73 | } else { 74 | room.sendAnnouncement("Please type a correct password!", player.id, 0xFF0000, "bold", 2); 75 | return false; 76 | } 77 | } else { 78 | room.sendAnnouncement("Your password cannot contain empty character!", player.id, 0xFF0000, "bold", 2); 79 | return false; 80 | } 81 | } else { 82 | room.sendAnnouncement("You are already registered!", player.id, 0xFFFF00, "bold", 2); 83 | return false; 84 | } 85 | } else if (splitted[0] == "!login") { 86 | if (playerList[player.name] == undefined) { 87 | room.sendAnnouncement("You must get registered before logging in!", player.id, 0xFFFF00, "bold", 2); 88 | return false; 89 | } else { 90 | if (playerList[player.name].registered == true) { 91 | if (playerList[player.name].loggedIn == false) { 92 | if (splitted.length == 2) { 93 | var password = splitted[1]; 94 | var passwordToBeChecked = playerList[player.name].password; 95 | var passwordCheck = (password == passwordToBeChecked); 96 | if (isInTheLimits(password.length, passwordLengths.min, passwordLengths.max)) { 97 | if (passwordCheck == true) { 98 | room.sendAnnouncement("You have logged in!", player.id, 0x00FF00, "normal", 1); 99 | playerList[player.name].loggedIn = true; 100 | return false; 101 | } else { 102 | room.sendAnnouncement("Incorrect password! Try again please!", player.id, 0xFF0000, "bold", 2); 103 | return false; 104 | } 105 | } else { 106 | room.sendAnnouncement(`Your password must be within a length between ${passwordLengths.min} and ${passwordLengths.max}!`, player.id, 0xFF0000, "bold", 2); 107 | return false; 108 | } 109 | } else { 110 | room.sendAnnouncement("Your password cannot contain empty character!", player.id, 0xFF0000, "bold", 2); 111 | return false; 112 | } 113 | } else { 114 | room.sendAnnouncement("You are already logged in!", player.id, 0xFFFF00, "bold", 2); 115 | return false; 116 | } 117 | } else { 118 | room.sendAnnouncement("You must get registered before logging in!", player.id, 0xFFFF00, "bold", 2); 119 | return false; 120 | } 121 | } 122 | } 123 | } 124 | -------------------------------------------------------------------------------- /Intermediate/ReorderPlayers.js: -------------------------------------------------------------------------------- 1 | var commands = ["!bottom", "!top"]; 2 | 3 | var room = HBInit({ roomName: "Reorder Players", noPlayer: true, public: false, maxPlayers: 8 }); 4 | 5 | room.onPlayerChat = function (player, message) { 6 | var index = commands.indexOf(message); 7 | if (index !== -1) { 8 | var id = []; 9 | id.push(player.id); 10 | room.reorderPlayers(id, Boolean(index)); 11 | room.sendAnnouncement(`You moved to the ${commands[index].slice(1)}.`, player.id, 0xFFFFFF, "bold", 2); 12 | return false; 13 | } 14 | else { 15 | room.sendAnnouncement("Only !bottom and !top are allowed!", player.id, 0xFFFFFF, "bold", 2); 16 | return false; 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /Intermediate/TacticalTimeout.js: -------------------------------------------------------------------------------- 1 | var playerList = {}; 2 | 3 | var room = HBInit({roomName:"Tactical Timeout",noPlayer:true,public:true,maxPlayers:16}); 4 | 5 | var tacticalTimeoutLimit = 5; 6 | var playerLeft = false; 7 | var voteCommand = "p"; 8 | 9 | var redAskedForPause = []; 10 | var blueAskedForPause = []; 11 | 12 | var teamAskedForPause = [redAskedForPause,blueAskedForPause]; 13 | var teams = ["Red","Blue"]; 14 | 15 | var gamePauseState = false; 16 | 17 | room.onGamePause = function(byPlayer){ 18 | gamePauseState = !gamePauseState; 19 | } 20 | 21 | room.onGameStart = function(byPlayer){ 22 | redAskedForPause = []; 23 | blueAskedForPause = []; 24 | } 25 | 26 | room.onGameStop = function(byPlayer){ 27 | redAskedForPause = []; 28 | blueAskedForPause = []; 29 | } 30 | 31 | room.onGameUnpause = function(byPlayer){ 32 | gamePauseState = !gamePauseState; 33 | } 34 | 35 | room.onPlayerChat = function (player, message) { 36 | if (message.toLowerCase() == voteCommand) { 37 | if (player.team != 0) { 38 | if (playerList[player.name].votedForTacticalTimeout == false && teamAskedForPause[player.team - 1].includes(player.name) == false) { 39 | room.sendAnnouncement(`${player.name} has asked for pause!`, player.id, 0xFFFF00, "bold", 2); //If player is able to use his right, then his message will appear on chat to make others witnessed. 40 | playerList[player.name].votedForTacticalTimeout = true; 41 | teamAskedForPause[player.team - 1].push(player.name); 42 | } 43 | if(gamePauseState == true){ 44 | room.sendAnnouncement("You cannot use this command during the paused mode!", player.id, 0xFF0000, "bold", 2); 45 | } 46 | else { 47 | room.sendAnnouncement("Your right for asking pauses has expired!", player.id, 0xFF0000, "bold", 2); 48 | return false; 49 | } 50 | 51 | for (var t in teamAskedForPause) { 52 | if (teamAskedForPause[t].length == tacticalTimeoutLimit && gamePauseState == false) { 53 | room.pauseGame(true); 54 | room.sendAnnouncement(`${teams[t]} has asked for a pause and game paused!`, null, 0xFF0000, "bold", 2); 55 | var team = teams[t]; 56 | setTimeout(function () { 57 | room.pauseGame(false); 58 | room.sendAnnouncement(`The pause time for ${team} team has been expired!`, null, 0xFFFF00, "bold", 2); 59 | redAskedForPause = []; 60 | blueAskedForPause = []; 61 | }, 15000); 62 | } 63 | } 64 | } 65 | else{ 66 | room.sendAnnouncement("Spectators cannot ask for a pause!", player.id, 0xFF0000, "bold", 2); //If used in a abusive manner, then administrators can ban the player. 67 | } 68 | } 69 | } 70 | 71 | room.onPlayerJoin = function(player){ 72 | if(playerList[player.name] == undefined){ 73 | playerList[player.name] = {name: player.name, votedForTacticalTimeout: false}; 74 | } 75 | } 76 | -------------------------------------------------------------------------------- /Intermediate/TeamChat.js: -------------------------------------------------------------------------------- 1 | var kirmizitakim = []; 2 | var mavitakim = []; 3 | var teamMessageCommand = "!t"; 4 | 5 | var room = HBInit({roomName:"Team Chat",noPlayer:true,public:true,maxPlayers:12}); 6 | 7 | room.onPlayerChat = function (player, message) { 8 | if (message.startsWith(teamMessageCommand) == true) { 9 | if (kirmizitakim.includes(player.name) == true) { 10 | for (var i = 0; i < kirmizitakim.length; i++) { //Kırmızı takımdaki bütün oyunculara mesaj gönder 11 | room.sendAnnouncement(player.id + " 🟥 | " + player.name + ": " + message.slice(teamMessageCommand.length), room.getPlayerList().find(p=> p.name == kirmizitakim[i]).id, 0x19FFBA, 'bold', 2); 12 | return false; 13 | } 14 | } 15 | else if (mavitakim.includes(player.name) == true) { 16 | for (var i = 0; i < mavitakim.length; i++) { //Mavi takımdaki bütün oyunculara mesaj gönde 17 | room.sendAnnouncement(player.id + " 🟦 | " + player.name + ": " + message.slice(teamMessageCommand.length), room.getPlayerList().find(p=> p.name == mavitakim[i]).id, 0x19FFBA, 'bold', 2); 18 | return false; 19 | } 20 | } 21 | } 22 | } 23 | 24 | room.onPlayerLeave = function (player) { 25 | if (player.team == 1) { //Kırmızı takımdayken odayı terk ettiyse 26 | if (kirmizitakim.includes(player.name) == true) { 27 | var index = kirmizitakim.indexOf(player.name); 28 | kirmizitakim.splice(index, 1); 29 | } 30 | } 31 | else if (player.team == 2) { //Mavi takımdayken odayı terk ettiyse 32 | if (mavitakim.includes(player.name) == true) { 33 | var index = mavitakim.indexOf(player.name); 34 | mavitakim.splice(index, 1); 35 | } 36 | } 37 | } 38 | 39 | room.onPlayerTeamChange = function (changedPlayer, byPlayer) { 40 | if (changedPlayer.team == 1) { 41 | if (kirmizitakim.includes(changedPlayer.name) == false) { //Kırmızı takımda yoksa 42 | kirmizitakim.push(changedPlayer.name); 43 | } 44 | if (mavitakim.includes(changedPlayer.name) == true) { //Kırmızı takıma mavi takımdan geldiyse 45 | var index = mavitakim.indexOf(changedPlayer.name); 46 | mavitakim.splice(index, 1); 47 | } 48 | } 49 | else if (changedPlayer.team == 2) { 50 | if (mavitakim.includes(changedPlayer.name) == false) { //Mavi takımda yoksa 51 | mavitakim.push(changedPlayer.name); 52 | } 53 | if (kirmizitakim.includes(changedPlayer.name) == true) { //Mavi takıma kırmızı takımdan geldiyse 54 | var index = kirmizitakim.indexOf(changedPlayer.name); 55 | kirmizitakim.splice(index, 1); 56 | } 57 | } 58 | else { 59 | if (kirmizitakim.includes(changedPlayer.name) == true) { //Spec'e kırmızı takımdan geçtiyse 60 | var index = kirmizitakim.indexOf(changedPlayer.name); 61 | kirmizitakim.splice(index, 1); 62 | } 63 | else if (mavitakim.includes(changedPlayer.name) == true) { //Spec'e mavi takımdan geçtiyse 64 | var index = mavitakim.indexOf(changedPlayer.name); 65 | mavitakim.splice(index, 1); 66 | } 67 | } 68 | } 69 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2022 thenorthstar 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # HaxBall-Example-Scripts 2 | Example HaxBall Scripts for HaxBall Coders 3 | 4 | Discord 5 | 6 | ## What scripts are here? 7 | Before checking out the scripts, we partition them into miscellaneous levels by their difficulty or effect in room. At the end of the day, there are three levels as the following: **Beginner**, **Intermediate** and **Advanced**. Now, let's take a look turn by turn: 8 | 9 | ### Beginner 10 | Here, usually easily-made ones take place. 11 | 12 | * Script for making your rooms controllable by administrators: https://github.com/thenorthstar/HaxBall-Example-Scripts/blob/main/Beginner/AdminSlot.js 13 | * Script for teleporting the ball from a certain point to a certain point: https://github.com/thenorthstar/HaxBall-Example-Scripts/blob/main/Beginner/BallZoneCheckAndTeleport.js 14 | * Basketball bot with score controlling (x2 or x3 according to distance): https://github.com/thenorthstar/HaxBall-Example-Scripts/blob/main/Beginner/Basketball.js 15 | * Keep your room clean against toxic players: https://github.com/thenorthstar/HaxBall-Example-Scripts/blob/main/Beginner/Blacklist.js 16 | * Script for clearing the ban of a specific player: https://github.com/thenorthstar/HaxBall-Example-Scripts/blob/main/Beginner/Clearban.js 17 | * Script for determining if the players collide with each other during the game: https://github.com/thenorthstar/HaxBall-Example-Scripts/blob/main/Beginner/Collision.js 18 | * Ban players with command: https://github.com/thenorthstar/HaxBall-Example-Scripts/blob/main/Beginner/CommandBan.js 19 | * Script for preventing duplicated connections from the same source: https://github.com/thenorthstar/HaxBall-Example-Scripts/blob/main/Beginner/DuplicatedConnections.js 20 | * A recently popular script (to see joining history of players) which was also shared on GitHub HaxBall issues wiki: https://github.com/thenorthstar/HaxBall-Example-Scripts/blob/main/Beginner/JoiningHistory.js 21 | * A funny game in which the players try to kick the target player in a certain time (it's recommended to use HaxBall All in one Tool): https://github.com/thenorthstar/HaxBall-Example-Scripts/blob/main/Beginner/KickGame.js (May still have some bugs, will be fixed later) 22 | * A lightweight zone control script ready to be enhanced: https://github.com/thenorthstar/HaxBall-Example-Scripts/blob/main/Beginner/MarkedZone.js 23 | * Script for moving players from a team to another one: https://github.com/thenorthstar/HaxBall-Example-Scripts/blob/main/Beginner/MovePlayers.js 24 | * A script for finding the nearest player to ball during the game: https://github.com/thenorthstar/HaxBall-Example-Scripts/blob/main/Beginner/Nearest_Player.js 25 | * Keep players' avatar constant: https://github.com/thenorthstar/HaxBall-Example-Scripts/blob/main/Beginner/PlayerAvatarControl.js 26 | * A script for adjusting player radiuses and avatars after goals: https://github.com/thenorthstar/HaxBall-Example-Scripts/blob/main/Beginner/PlayerRadiusAvatarSetting.js 27 | * An overrated seeming script to change player radius by command: https://github.com/thenorthstar/HaxBall-Example-Scripts/blob/main/Beginner/RadiusSetting.js 28 | * Ranks with base points: https://github.com/thenorthstar/HaxBall-Example-Scripts/blob/main/Beginner/Ranks.js 29 | * A script for seeing player statistics. Has been created after a topic on GitHub: https://github.com/thenorthstar/HaxBall-Example-Scripts/blob/main/Beginner/RankSystem.js 30 | * A simple rock - paper - scissors game based on randomness: https://github.com/thenorthstar/HaxBall-Example-Scripts/blob/main/Beginner/RockPaperScissors_v1.js 31 | * Rock - paper - scissors game with point check: https://github.com/thenorthstar/HaxBall-Example-Scripts/blob/main/Beginner/RockPaperScissors_v2.js 32 | * Players will gain (or lose) no points on draw: https://github.com/thenorthstar/HaxBall-Example-Scripts/blob/main/Beginner/RockPaperScissors_v3.js 33 | * Slow mode script for keeping clean the chat section: https://github.com/thenorthstar/HaxBall-Example-Scripts/blob/main/Beginner/SlowMode.js 34 | * A script to keep flooders away: https://github.com/thenorthstar/HaxBall-Example-Scripts/blob/main/Beginner/Spam_Mute.js 35 | * A script for separating users according to VIP status: https://github.com/thenorthstar/HaxBall-Example-Scripts/blob/main/Beginner/VIP_Roles.js 36 | * A script for logging the data in your room to discord: https://github.com/thenorthstar/HaxBall-Example-Scripts/blob/main/Beginner/Webhooks.js 37 | * Simple betting system for HaxBall players: https://github.com/thenorthstar/HaxBall-Example-Scripts/blob/main/Beginner/XPSystem_v1.js 38 | * Simple betting system with **localStorage** for HaxBall players: https://github.com/thenorthstar/HaxBall-Example-Scripts/blob/main/Beginner/XPSystem_v2.js 39 | * Another (but easier) script for check whether a player is inside or outside a certain zone: https://github.com/thenorthstar/HaxBall-Example-Scripts/blob/main/Beginner/ZoneCheck.js 40 | 41 | ### Intermediate 42 | Here, average weighted scripts take place. 43 | 44 | * A script which prevents three players of the same team to be in a certain zone in the same time: https://github.com/thenorthstar/HaxBall-Example-Scripts/blob/main/Intermediate/3DefLines.js 45 | * A script for catching the bad words and banning those who used them: https://github.com/thenorthstar/HaxBall-Example-Scripts/blob/main/Intermediate/Badwords.js 46 | * A script for counting player detections during (and at the end of) the game: https://github.com/thenorthstar/HaxBall-Example-Scripts/blob/main/Intermediate/CollisionDetection_Counter.js 47 | * A script for any purpose within counting down or up: https://github.com/thenorthstar/HaxBall-Example-Scripts/blob/main/Intermediate/Counter.js 48 | * Finish line evaluation for some basic cases: https://github.com/thenorthstar/HaxBall-Example-Scripts/blob/main/Intermediate/FinishLine.js 49 | * A script to wait for giveups: https://github.com/thenorthstar/HaxBall-Example-Scripts/blob/main/Intermediate/GiveUp.js 50 | * A script to adjust after-goal effects: https://github.com/thenorthstar/HaxBall-Example-Scripts/blob/main/Intermediate/Goal_AfterEffects.js 51 | * A script to let the players ignore who they don't want to get messages: https://github.com/thenorthstar/HaxBall-Example-Scripts/blob/main/Intermediate/Ignore.js 52 | * Simple login system with some constraints: https://github.com/thenorthstar/HaxBall-Example-Scripts/blob/main/Intermediate/Login.js 53 | * Script for voting maps: https://github.com/thenorthstar/HaxBall-Example-Scripts/blob/main/Intermediate/MapVote.js 54 | * Script for freezing players by command, like as in the case of Mario Kart room but simple: https://github.com/thenorthstar/HaxBall-Example-Scripts/blob/main/Intermediate/PlayerFreeze.js 55 | * A script for teleporting red player immediately after the kick-off: https://github.com/thenorthstar/HaxBall-Example-Scripts/blob/main/Intermediate/Player_Teleport_After_KickOff.js 56 | * A new login script with registration: https://github.com/thenorthstar/HaxBall-Example-Scripts/blob/main/Intermediate/Register-Login.js 57 | * A script for moving yourself to the bottom or the top (logic may be hard to get the point so it's an intermediate example): https://github.com/thenorthstar/HaxBall-Example-Scripts/blob/main/Intermediate/ReorderPlayers.js 58 | * A script for asking pauses during the game in an auto-controlled room: https://github.com/thenorthstar/HaxBall-Example-Scripts/blob/main/Intermediate/TacticalTimeout.js 59 | * Script for chatting with your team's members: https://github.com/thenorthstar/HaxBall-Example-Scripts/blob/main/Intermediate/TeamChat.js 60 | * A wide repository of team uniforms which are able to set by commands but may seem as overrated: https://github.com/thenorthstar/HaxBall-Example-Scripts/blob/main/Intermediate/Uniforms.js 61 | 62 | ### Advanced 63 | Now, let's the time to see hard-coded ones: 64 | 65 | * A script to track admin changes in the room, may seem as underrated but requires a fresh brain and patience: https://github.com/thenorthstar/HaxBall-Example-Scripts/blob/main/Advanced/Admin.js 66 | * Player avatars will be available to be overrided with this script. Impossible is nothing: https://github.com/thenorthstar/HaxBall-Example-Scripts/blob/main/Advanced/AvatarOverride.js 67 | * Bots also should be able to detect collisions: https://github.com/thenorthstar/HaxBall-Example-Scripts/blob/main/Advanced/CollisionDetection.js 68 | * Spammers can abuse the room also by using the commands, now let's make the room great again: https://github.com/thenorthstar/HaxBall-Example-Scripts/blob/main/Advanced/CommandAbuseDetection.js 69 | * MVP Script with localStorage, another underrated seeming script: https://github.com/thenorthstar/HaxBall-Example-Scripts/blob/main/Advanced/MVP.js 70 | * Mute players for a certain time by command: https://github.com/thenorthstar/HaxBall-Example-Scripts/blob/main/Advanced/Mute.js 71 | * Players will be able to adjust their radius during the game with some restrictions: https://github.com/thenorthstar/HaxBall-Example-Scripts/blob/main/Advanced/RadiusSetting_CommandUsage.js 72 | * Vote players to make them banned: https://github.com/thenorthstar/HaxBall-Example-Scripts/blob/main/Advanced/VoteBan.js 73 | 74 | That's all for now. Stay await for the incoming ones... 75 | --------------------------------------------------------------------------------