Professional Documents
Culture Documents
Untitled
Untitled
/* ROOM */
var roomWebhook =
'https://discord.com/api/webhooks/1100134155259490374/9YJjLd1t9ydgQ1-x_c42I-
YeQVrxxXfKhocLI55j67u3qJMy4Dh9TEe22a0gtt9UWCZX';
var gameWebhook =
'https://discord.com/api/webhooks/1100419409278943253/LfEID1_TWL1kz1DY4FL5C5ETpEXXI
-C1aD8qXNGkIRld4XW2VFsAwBfIz_FGnsjMa60g';
var timeLimit = 3;
var scoreLimit = 3;
var gameConfig = {
roomName: roomName,
maxPlayers: maxPlayers,
public: roomPublic,
noPlayer: true,
}
room.setScoreLimit(scoreLimit);
room.setTimeLimit(timeLimit);
room.setTeamsLock(true);
room.setKickRateLimit(6, 0, 0);
/* OPTIONS */
/* OBJECTS */
class Goal {
constructor(time, team, striker, assist) {
this.time = time;
this.team = team;
this.striker = striker;
this.assist = assist;
}
}
class Game {
constructor() {
this.date = Date.now();
this.scores = room.getScores();
this.playerComp = getStartingLineups();
this.goals = [];
this.rec = room.startRecording();
this.touchArray = [];
}
}
class PlayerComposition {
constructor(player, auth, timeEntry, timeExit) {
this.player = player;
this.auth = auth;
this.timeEntry = timeEntry;
this.timeExit = timeExit;
this.inactivityTicks = 0;
this.GKTicks = 0;
}
}
class BallTouch {
constructor(player, time, goal, position) {
this.player = player;
this.time = time;
this.goal = goal;
this.position = position;
}
}
/* PLAYERS */
/* STATS */
/* AUTH */
/* COMMANDS */
var commands = {
help: {
aliases: ['commands'],
roles: Role.PLAYER,
desc: `
This command shows all the available commands. It also can show the
description of a command in particular.
Example: \'!help bb\' will show the description of the \'bb\' command.`,
function: helpCommand,
},
claim: {
aliases: [],
roles: Role.PLAYER,
desc: false,
function: masterCommand,
},
bb: {
aliases: ['bye', 'gn', 'cya'],
roles: Role.PLAYER,
desc: `
This command makes you leave instantly (use recommended).`,
function: leaveCommand,
},
rr: {
aliases: [],
roles: Role.ADMIN_TEMP,
desc: `
This command restarts the game.`,
function: restartCommand,
},
rrs: {
aliases: [],
roles: Role.ADMIN_TEMP,
desc: `
This command swaps the teams and restarts the game.`,
function: restartSwapCommand,
},
swap: {
aliases: ['s'],
roles: Role.ADMIN_TEMP,
desc: `
This command swaps the teams when the game is stopped.`,
function: swapCommand,
},
training: {
aliases: [],
roles: Role.ADMIN_TEMP,
desc: `
This command loads the classic training stadium.`,
function: stadiumCommand,
},
classic: {
aliases: [],
roles: Role.ADMIN_TEMP,
desc: `
This command loads the classic stadium.`,
function: stadiumCommand,
},
big: {
aliases: [],
roles: Role.ADMIN_TEMP,
desc: `
This command loads the big stadium.`,
function: stadiumCommand,
},
kickred: {
aliases: ['kickr'],
roles: Role.ADMIN_TEMP,
desc: `
This command kicks all the players from the red team, including the player that
entered the command. You can give as an argument the reason of the kick.`,
function: kickTeamCommand,
},
kickblue: {
aliases: ['kickb'],
roles: Role.ADMIN_TEMP,
desc: `
This command kicks all the players from the blue team, including the player
that entered the command. You can give as an argument the reason of the kick.`,
function: kickTeamCommand,
},
kickspec: {
aliases: ['kicks'],
roles: Role.ADMIN_TEMP,
desc: `
This command kicks all the players from the spectators team, including the
player that entered the command. You can give as an argument the reason of the
kick.`,
function: kickTeamCommand,
},
clearbans: {
aliases: [],
roles: Role.MASTER,
desc: `
This command unbans everyone. It also can unban one player in particular, by
adding his ID as an argument.`,
function: clearbansCommand,
},
bans: {
aliases: ['banlist'],
roles: Role.MASTER,
desc: `
This command shows all the players that were banned and their IDs.`,
function: banListCommand,
},
admins: {
aliases: ['adminlist'],
roles: Role.MASTER,
desc: `
This command shows all the players that are permanent admins.`,
function: adminListCommand,
},
setadmin: {
aliases: ['admin'],
roles: Role.MASTER,
desc: `
This command allows to set someone as admin. He will be able to connect as
admin, and can be removed at any time by masters.
It takes 1 argument:
Argument 1: #<id> where <id> is the id of the player targeted.
Example: !setadmin #3 will give admin to the player with id 3.`,
function: setAdminCommand,
},
removeadmin: {
aliases: ['unadmin'],
roles: Role.MASTER,
desc: `
This command allows to remove someone as admin.
It takes 1 argument:
Argument 1: #<id> where <id> is the id of the player targeted.
OR
Argument 1: <number> where <number> is the number associated with the admin given
by the 'adminList' command.
Example: !removeadmin #300 will remove admin to the player with id 300,
!removeadmin 2 will remove the admin n°2 according to the 'adminList'
command.`,
function: removeAdminCommand,
},
password: {
aliases: ['pw'],
roles: Role.MASTER,
desc: `
This command allows to add a password to the room.
It takes 1 argument:
Argument 1: <password> where <password> is the password you want for the room.
/* GAME */
/* COLORS */
/* AUXILIARY */
var stopTimeout;
var startTimeout;
var unpauseTimeout;
var emptyPlayer = {
id: 0,
};
stadiumCommand(emptyPlayer, "!big");
/* FUNCTIONS */
/* AUXILIARY FUNCTIONS */
function getDate() {
let d = new Date();
return d.toLocaleDateString() + ' ' + d.toLocaleTimeString();
}
/* MATH FUNCTIONS */
function getRandomInt(max) {
// returns a random number between 0 and max-1
return Math.floor(Math.random() * Math.floor(max));
}
/* TIME FUNCTIONS */
function getMinutesGame(time) {
var t = Math.floor(time / 60);
return `${Math.floor(t / 10)}${Math.floor(t % 10)}`;
}
function getMinutesReport(time) {
return Math.floor(Math.round(time) / 60);
}
function getMinutesEmbed(time) {
var t = Math.floor(Math.round(time) / 60);
return `${Math.floor(t / 10)}${Math.floor(t % 10)}`;
}
function getSecondsGame(time) {
var t = Math.floor(time - Math.floor(time / 60) * 60);
return `${Math.floor(t / 10)}${Math.floor(t % 10)}`;
}
function getSecondsReport(time) {
var t = Math.round(time);
return Math.floor(t - Math.floor(t / 60) * 60);
}
function getSecondsEmbed(time) {
var t = Math.round(time);
var t2 = Math.floor(t - Math.floor(t / 60) * 60);
return `${Math.floor(t2 / 10)}${Math.floor(t2 % 10)}`;
}
function getTimeGame(time) {
return `[${getMinutesGame(time)}:${getSecondsGame(time)}]`;
}
function getTimeEmbed(time) {
return `[${getMinutesEmbed(time)}:${getSecondsEmbed(time)}]`;
}
function getGoalGame() {
return game.scores.red + game.scores.blue;
}
/* REPORT FUNCTIONS */
function findFirstNumberCharString(str) {
let str_number = str[str.search(/[0-9]/g)];
return str_number === undefined ? "0" : str_number;
}
function getIdReport() {
var d = new Date();
return `${d.getFullYear() % 100}${d.getMonth() < 9 ? '0' : ''}${d.getMonth() +
1}${d.getDate() < 10 ? '0' : ''}${d.getDate()}${d.getHours() < 10 ? '0' : ''}$
{d.getHours()}${d.getMinutes() < 10 ? '0' : ''}${d.getMinutes()}${d.getSeconds() <
10 ? '0' : ''}${d.getSeconds()}${findFirstNumberCharString(roomName)}`;
}
function getRecordingName(game) {
let d = new Date();
let redCap = game.playerComp[0][0] != undefined ? game.playerComp[0]
[0].player.name : 'Red';
let blueCap = game.playerComp[1][0] != undefined ? game.playerComp[1]
[0].player.name : 'Blue';
let day = d.getDate() < 10 ? '0' + d.getDate() : d.getDate();
let month = d.getMonth() < 10 ? '0' + (d.getMonth() + 1) : (d.getMonth() + 1);
let year = d.getFullYear() % 100 < 10 ? '0' + (d.getFullYear() % 100) :
(d.getFullYear() % 100);
let hour = d.getHours() < 10 ? '0' + d.getHours() : d.getHours();
let minute = d.getMinutes() < 10 ? '0' + d.getMinutes() : d.getMinutes();
return `${day}-${month}-${year}-${hour}h${minute}-${redCap}vs${blueCap}.hbr2`;
}
function fetchRecording(game) {
if (gameWebhook != "") {
let form = new FormData();
form.append(null, new File([game.rec], getRecordingName(game), { "type":
"text/plain" }));
form.append("payload_json", JSON.stringify({
"username": roomName
}));
fetch(gameWebhook, {
method: 'POST',
body: form,
}).then((res) => res);
}
}
/* FEATURE FUNCTIONS */
function getCommand(commandStr) {
if (commands.hasOwnProperty(commandStr)) return commandStr;
for (const [key, value] of Object.entries(commands)) {
for (let alias of value.aliases) {
if (alias == commandStr) return key;
}
}
return false;
}
function getPlayerComp(player) {
if (player == null || player.id == 0) return null;
var comp = game.playerComp;
var index = comp[0].findIndex((c) => c.auth == authArray[player.id][0]);
if (index != -1) return comp[0][index];
index = comp[1].findIndex((c) => c.auth == authArray[player.id][0]);
if (index != -1) return comp[1][index];
return null;
}
function getTeamArray(team) {
return team == Team.RED ? teamRed : team == Team.BLUE ? teamBlue : teamSpec;
}
room.sendAnnouncement(
messageFrom,
player.id,
privateMessageColor,
'bold',
HaxNotification.CHAT
);
room.sendAnnouncement(
messageTo,
playerTarget.id,
privateMessageColor,
'bold',
HaxNotification.CHAT
);
}
/* PHYSICS FUNCTIONS */
function calculateStadiumVariables() {
if (checkStadiumVariable && teamRed.length + teamBlue.length > 0) {
checkStadiumVariable = false;
setTimeout(() => {
let ballDisc = room.getDiscProperties(0);
let playerDisc = room.getPlayerDiscProperties(teamRed.concat(teamBlue)
[0].id);
ballRadius = ballDisc.radius;
playerRadius = playerDisc.radius;
triggerDistance = ballRadius + playerRadius + 0.01;
speedCoefficient = 100 / (5 * ballDisc.invMass * (ballDisc.damping **
60 + 1));
}, 1);
}
}
/* BUTTONS */
function swapButton() {
for (let player of teamBlue) {
room.setPlayerTeam(player.id, Team.RED);
}
for (let player of teamRed) {
room.setPlayerTeam(player.id, Team.BLUE);
}
}
/* COMMAND FUNCTIONS */
/* PLAYER COMMANDS */
/* ADMIN COMMANDS */
/* MASTER COMMANDS */
function checkTime() {
const scores = room.getScores();
if (game != undefined) game.scores = scores;
if (Math.abs(scores.time - scores.timeLimit) <= 0.01 && scores.timeLimit != 0
&& playSituation == Situation.PLAY) {
if (scores.red != scores.blue) {
if (!checkTimeVariable) {
checkTimeVariable = true;
setTimeout(() => {
checkTimeVariable = false;
}, 3000);
scores.red > scores.blue ? endGame(Team.RED) : endGame(Team.BLUE);
stopTimeout = setTimeout(() => {
room.stopGame();
}, 2000);
}
return;
}
if (drawTimeLimit != 0) {
goldenGoal = true;
room.sendAnnouncement(
'⚽ First goal wins !',
null,
announcementColor,
'bold',
HaxNotification.CHAT
);
}
}
if (Math.abs(scores.time - drawTimeLimit * 60 - scores.timeLimit) <= 0.01 &&
scores.timeLimit != 0) {
if (!checkTimeVariable) {
checkTimeVariable = true;
setTimeout(() => {
checkTimeVariable = false;
}, 10);
endGame(Team.SPECTATORS);
room.stopGame();
goldenGoal = false;
}
}
}
function instantRestart() {
room.stopGame();
startTimeout = setTimeout(() => {
room.startGame();
}, 10);
}
function resumeGame() {
startTimeout = setTimeout(() => {
room.startGame();
}, 1000);
setTimeout(() => {
room.pauseGame(false);
}, 500);
}
function endGame(winner) {
const scores = room.getScores();
game.scores = scores;
endGameVariable = true;
if (winner == Team.RED) {
room.sendAnnouncement(
`✨ Red Team won ${scores.red} - ${scores.blue} !`,
null,
redColor,
'bold',
HaxNotification.CHAT
);
} else if (winner == Team.BLUE) {
room.sendAnnouncement(
`✨ Blue Team won ${scores.blue} - ${scores.red} !`,
null,
blueColor,
'bold',
HaxNotification.CHAT
);
} else {
room.sendAnnouncement(
'💤 Draw limit reached !',
null,
announcementColor,
'bold',
HaxNotification.CHAT
);
}
let possessionRedPct = (possession[0] / (possession[0] + possession[1])) * 100;
let possessionBluePct = 100 - possessionRedPct;
let possessionString = `🔴 ${possessionRedPct.toFixed(0)}% - $
{possessionBluePct.toFixed(0)}% 🔵`;
let actionRedPct = (actionZoneHalf[0] / (actionZoneHalf[0] +
actionZoneHalf[1])) * 100;
let actionBluePct = 100 - actionRedPct;
let actionString = `🔴 ${actionRedPct.toFixed(0)}% - $
{actionBluePct.toFixed(0)}% 🔵`;
let CSString = getCSString(scores);
room.sendAnnouncement(
`📊 Possession: 🔴 ${possessionString}\n` +
`📊 Action Zone: 🔴 ${actionString}\n` +
`${CSString}`,
null,
announcementColor,
'bold',
HaxNotification.NONE
);
}
/* PLAYER FUNCTIONS */
function updateTeams() {
players = room.getPlayerList();
teamRed = players.filter((p) => p.team == Team.RED);
teamBlue = players.filter((p) => p.team == Team.BLUE);
teamSpec = players.filter((p) => p.team == Team.SPECTATORS);
}
function updateAdmins(excludedPlayerID = 0) {
if (players.length != 0 && players.filter((p) => p.admin).length < maxAdmins) {
let playerArray = players.filter((p) => p.id != excludedPlayerID && !
p.admin);
let arrayID = playerArray.map((player) => player.id);
room.setPlayerAdmin(Math.min(...arrayID), true);
}
}
function getRole(player) {
return (
!!masterList.find((a) => a == authArray[player.id][0]) * 2 +
!!adminList.find((a) => a[0] == authArray[player.id][0]) * 1 +
player.admin * 1
);
}
/* ACTIVITY FUNCTIONS */
function handleActivityPlayer(player) {
let pComp = getPlayerComp(player);
if (pComp != null) {
pComp.inactivityTicks++;
return pComp.inactivityTicks;
}
return 0;
}
function handleActivityPlayerTeamChange(changedPlayer) {
if (changedPlayer.team == Team.SPECTATORS) {
let pComp = getPlayerComp(changedPlayer);
if (pComp != null) pComp.inactivityTicks = 0;
}
}
function handleActivityStop() {
for (let player of players) {
let pComp = getPlayerComp(player);
if (pComp != null) pComp.inactivityTicks = 0;
}
}
function handleActivity() {
if (gameState == State.PLAY && players.length > 1) {
var playerMaxInactivity = 0;
for (let player of teamRed) {
var playerInactivity = handleActivityPlayer(player);
playerMaxInactivity = Math.max(playerInactivity, playerMaxInactivity);
}
for (let player of teamBlue) {
var playerInactivity = handleActivityPlayer(player);
playerMaxInactivity = Math.max(playerInactivity, playerMaxInactivity);
}
if (playerMaxInactivity >= maxInactivity * 60 * 60) {
cancelGameVariable = true;
room.stopGame();
room.sendAnnouncement(
'⚠️ Game was stopped due to inactivity !',
null,
announcementColor,
'bold',
HaxNotification.CHAT
);
handleActivityStop();
}
}
}
/* LINEUP FUNCTIONS */
function getStartingLineups() {
var compositions = [[], []];
for (let player of teamRed) {
compositions[0].push(
new PlayerComposition(player, authArray[player.id][0], [0], [])
);
}
for (let player of teamBlue) {
compositions[1].push(
new PlayerComposition(player, authArray[player.id][0], [0], [])
);
}
return compositions;
}
function handleLineupChangeTeamChange(changedPlayer) {
if (gameState != State.STOP) {
var playerLineup;
if (changedPlayer.team == Team.RED) {
// player gets in red team
var redLineupAuth = game.playerComp[0].map((p) => p.auth);
var ind = redLineupAuth.findIndex((auth) => auth ==
authArray[changedPlayer.id][0]);
if (ind != -1) {
// Player goes back in
playerLineup = game.playerComp[0][ind];
if (playerLineup.timeExit.includes(game.scores.time)) {
// gets subbed off then in at the exact same time -> no sub
playerLineup.timeExit = playerLineup.timeExit.filter((t) => t !
= game.scores.time);
} else {
playerLineup.timeEntry.push(game.scores.time);
}
} else {
playerLineup = new PlayerComposition(
changedPlayer,
authArray[changedPlayer.id][0],
[game.scores.time],
[]
);
game.playerComp[0].push(playerLineup);
}
} else if (changedPlayer.team == Team.BLUE) {
// player gets in blue team
var blueLineupAuth = game.playerComp[1].map((p) => p.auth);
var ind = blueLineupAuth.findIndex((auth) => auth ==
authArray[changedPlayer.id][0]);
if (ind != -1) {
// Player goes back in
playerLineup = game.playerComp[1][ind];
if (playerLineup.timeExit.includes(game.scores.time)) {
// gets subbed off then in at the exact same time -> no sub
playerLineup.timeExit = playerLineup.timeExit.filter((t) => t !
= game.scores.time);
} else {
playerLineup.timeEntry.push(game.scores.time);
}
} else {
playerLineup = new PlayerComposition(
changedPlayer,
authArray[changedPlayer.id][0],
[game.scores.time],
[]
);
game.playerComp[1].push(playerLineup);
}
}
if (teamRed.some((r) => r.id == changedPlayer.id)) {
// player leaves red team
var redLineupAuth = game.playerComp[0].map((p) => p.auth);
var ind = redLineupAuth.findIndex((auth) => auth ==
authArray[changedPlayer.id][0]);
playerLineup = game.playerComp[0][ind];
if (playerLineup.timeEntry.includes(game.scores.time)) {
// gets subbed off then in at the exact same time -> no sub
if (game.scores.time == 0) {
game.playerComp[0].splice(ind, 1);
} else {
playerLineup.timeEntry = playerLineup.timeEntry.filter((t) => t
!= game.scores.time);
}
} else {
playerLineup.timeExit.push(game.scores.time);
}
} else if (teamBlue.some((r) => r.id == changedPlayer.id)) {
// player leaves blue team
var blueLineupAuth = game.playerComp[1].map((p) => p.auth);
var ind = blueLineupAuth.findIndex((auth) => auth ==
authArray[changedPlayer.id][0]);
playerLineup = game.playerComp[1][ind];
if (playerLineup.timeEntry.includes(game.scores.time)) {
// gets subbed off then in at the exact same time -> no sub
if (game.scores.time == 0) {
game.playerComp[1].splice(ind, 1);
} else {
playerLineup.timeEntry = playerLineup.timeEntry.filter((t) => t
!= game.scores.time);
}
} else {
playerLineup.timeExit.push(game.scores.time);
}
}
}
}
function handleLineupChangeLeave(player) {
if (playSituation != Situation.STOP) {
if (player.team == Team.RED) {
// player gets in red team
var redLineupAuth = game.playerComp[0].map((p) => p.auth);
var ind = redLineupAuth.findIndex((auth) => auth ==
authArray[player.id][0]);
var playerLineup = game.playerComp[0][ind];
if (playerLineup.timeEntry.includes(game.scores.time)) {
// gets subbed off then in at the exact same time -> no sub
if (game.scores.time == 0) {
game.playerComp[0].splice(ind, 1);
} else {
playerLineup.timeEntry = playerLineup.timeEntry.filter((t) => t
!= game.scores.time);
}
} else {
playerLineup.timeExit.push(game.scores.time);
}
} else if (player.team == Team.BLUE) {
// player gets in blue team
var blueLineupAuth = game.playerComp[1].map((p) => p.auth);
var ind = blueLineupAuth.findIndex((auth) => auth ==
authArray[player.id][0]);
var playerLineup = game.playerComp[1][ind];
if (playerLineup.timeEntry.includes(game.scores.time)) {
// gets subbed off then in at the exact same time -> no sub
if (game.scores.time == 0) {
game.playerComp[1].splice(ind, 1);
} else {
playerLineup.timeEntry = playerLineup.timeEntry.filter((t) => t
!= game.scores.time);
}
} else {
playerLineup.timeExit.push(game.scores.time);
}
}
}
}
/* STATS FUNCTIONS */
/* GK FUNCTIONS */
function handleGKTeam(team) {
if (team == Team.SPECTATORS) {
return null;
}
let teamArray = team == Team.RED ? teamRed : teamBlue;
let playerGK = teamArray.reduce((prev, current) => {
if (team == Team.RED) {
return (prev?.position.x < current.position.x) ? prev : current
} else {
return (prev?.position.x > current.position.x) ? prev : current
}
}, null);
let playerCompGK = getPlayerComp(playerGK);
return playerCompGK;
}
function handleGK() {
let redGK = handleGKTeam(Team.RED);
if (redGK != null) {
redGK.GKTicks++;
}
let blueGK = handleGKTeam(Team.BLUE);
if (blueGK != null) {
blueGK.GKTicks++;
}
}
function getGK(team) {
if (team == Team.SPECTATORS) {
return null;
}
let teamArray = team == Team.RED ? game.playerComp[0] : game.playerComp[1];
let playerGK = teamArray.reduce((prev, current) => {
return (prev?.GKTicks > current.GKTicks) ? prev : current
}, null);
return playerGK;
}
function getCS(scores) {
let playersNameCS = [];
let redGK = getGK(Team.RED);
let blueGK = getGK(Team.BLUE);
if (redGK != null && scores.blue == 0) {
playersNameCS.push(redGK.player.name);
}
if (blueGK != null && scores.red == 0) {
playersNameCS.push(blueGK.player.name);
}
return playersNameCS;
}
function getCSString(scores) {
let playersCS = getCS(scores);
if (playersCS.length == 0) {
return "🥅 No CS";
} else if (playersCS.length == 1) {
return `🥅 ${playersCS[0]} had a CS.`;
} else {
return `🥅 ${playersCS[0]} and ${playersCS[1]} had a CS.`;
}
}
function getLastTouchOfTheBall() {
const ballPosition = room.getBallPosition();
updateTeams();
let playerArray = [];
for (let player of players) {
if (player.position != null) {
var distanceToBall = pointDistance(player.position, ballPosition);
if (distanceToBall < triggerDistance) {
if (playSituation == Situation.KICKOFF) playSituation =
Situation.PLAY;
playerArray.push([player, distanceToBall]);
}
}
}
if (playerArray.length != 0) {
let playerTouch = playerArray.sort((a, b) => a[1] - b[1])[0][0];
if (lastTeamTouched == playerTouch.team || lastTeamTouched ==
Team.SPECTATORS) {
if (lastTouches[0] == null || (lastTouches[0] != null &&
lastTouches[0].player.id != playerTouch.id)) {
game.touchArray.push(
new BallTouch(
playerTouch,
game.scores.time,
getGoalGame(),
ballPosition
)
);
lastTouches[0] = checkGoalKickTouch(
game.touchArray,
game.touchArray.length - 1,
getGoalGame()
);
lastTouches[1] = checkGoalKickTouch(
game.touchArray,
game.touchArray.length - 2,
getGoalGame()
);
}
}
lastTeamTouched = playerTouch.team;
}
}
function getBallSpeed() {
var ballProp = room.getDiscProperties(0);
return Math.sqrt(ballProp.xspeed ** 2 + ballProp.yspeed ** 2) *
speedCoefficient;
}
function getGameStats() {
if (playSituation == Situation.PLAY && gameState == State.PLAY) {
lastTeamTouched == Team.RED ? possession[0]++ : possession[1]++;
var ballPosition = room.getBallPosition();
ballPosition.x < 0 ? actionZoneHalf[0]++ : actionZoneHalf[1]++;
}
}
function getGoalAttribution(team) {
var goalAttribution = Array(2).fill(null);
if (lastTouches[0] != null) {
if (lastTouches[0].player.team == team) {
// Direct goal scored by player
if (lastTouches[1] != null && lastTouches[1].player.team == team) {
goalAttribution = [lastTouches[0].player, lastTouches[1].player];
} else {
goalAttribution = [lastTouches[0].player, null];
}
} else {
// Own goal
goalAttribution = [lastTouches[0].player, null];
}
}
return goalAttribution;
}
function getGoalString(team) {
var goalString;
var scores = game.scores;
var goalAttribution = getGoalAttribution(team);
if (goalAttribution[0] != null) {
if (goalAttribution[0].team == team) {
if (goalAttribution[1] != null && goalAttribution[1].team == team) {
goalString = `⚽ ${getTimeGame(scores.time)} Goal by $
{goalAttribution[0].name} ! Assist by ${goalAttribution[1].name}. Goal speed : $
{ballSpeed.toFixed(2)}km/h.`;
game.goals.push(
new Goal(
scores.time,
team,
goalAttribution[0],
goalAttribution[1]
)
);
} else {
goalString = `⚽ ${getTimeGame(scores.time)} Goal by $
{goalAttribution[0].name} ! Goal speed : ${ballSpeed.toFixed(2)}km/h.`;
game.goals.push(
new Goal(scores.time, team, goalAttribution[0], null)
);
}
} else {
goalString = `😂 ${getTimeGame(scores.time)} Own goal by $
{goalAttribution[0].name} ! Goal speed : ${ballSpeed.toFixed(2)}km/h.`;
game.goals.push(
new Goal(scores.time, team, goalAttribution[0], null)
);
}
} else {
goalString = `⚽ ${getTimeGame(scores.time)} Goal for ${team == Team.RED ?
'red' : 'blue'} team ! Goal speed : ${ballSpeed.toFixed(2)}km/h.`;
game.goals.push(
new Goal(scores.time, team, null, null)
);
}
return goalString;
}
/* FETCH FUNCTIONS */
function fetchGametimeReport(game) {
var fieldGametimeRed = {
name: '🔴 **RED TEAM STATS**',
value: '⌛ __**Game Time:**__\n\n',
inline: true,
};
var fieldGametimeBlue = {
name: '🔵 **BLUE TEAM STATS**',
value: '⌛ __**Game Time:**__\n\n',
inline: true,
};
var redTeamTimes = game.playerComp[0].map((p) => [p.player, 0]);
for (let i = 0; i < game.playerComp[0].length; i++) {
var player = game.playerComp[0][i];
for (let j = 0; j < player.timeEntry.length; j++) {
if (player.timeExit.length < j + 1) {
redTeamTimes[i][1] += game.scores.time - player.timeEntry[j];
} else {
redTeamTimes[i][1] += player.timeExit[j] - player.timeEntry[j];
}
}
}
var blueTeamTimes = game.playerComp[1].map((p) => [p.player, 0]);
for (let i = 0; i < game.playerComp[1].length; i++) {
var player = game.playerComp[1][i];
for (let j = 0; j < player.timeEntry.length; j++) {
if (player.timeExit.length < j + 1) {
blueTeamTimes[i][1] += game.scores.time - player.timeEntry[j];
} else {
blueTeamTimes[i][1] += player.timeExit[j] - player.timeEntry[j];
}
}
}
function fetchActionsSummaryReport(game) {
var fieldReportRed = {
name: '🔴 **RED TEAM STATS**',
value: '📊 __**Player Stats:**__\n\n',
inline: true,
};
var fieldReportBlue = {
name: '🔵 **BLUE TEAM STATS**',
value: '📊 __**Player Stats:**__\n\n',
inline: true,
};
var goals = [[], []];
for (let goal of game.goals) {
goals[goal.team - 1].push([goal.striker, goal.assist]);
}
var redActions = actionReportCountTeam(goals, Team.RED);
if (redActions.length > 0) {
for (let act of redActions) {
fieldReportRed.value += `> **${act[0].team != Team.RED ? '[OG] ' : ''}$
{act[0].name}:**` +
`${act[1] > 0 ? ` ${act[1]}G` : ''}` +
`${act[2] > 0 ? ` ${act[2]}A` : ''}` +
`${act[3] > 0 ? ` ${act[3]}CS` : ''}\n`;
}
}
var blueActions = actionReportCountTeam(goals, Team.BLUE);
if (blueActions.length > 0) {
for (let act of blueActions) {
fieldReportBlue.value += `> **${act[0].team != Team.BLUE ? '[OG] ' :
''}${act[0].name}:**` +
`${act[1] > 0 ? ` ${act[1]}G` : ''}` +
`${act[2] > 0 ? ` ${act[2]}A` : ''}` +
`${act[3] > 0 ? ` ${act[3]}CS` : ''}\n`;
}
}
function fetchSummaryEmbed(game) {
var fetchEndgame = [fetchGametimeReport, fetchActionsSummaryReport];
var logChannel = gameWebhook;
var fields = [
{
name: '🔴 **RED TEAM STATS**',
value: '=====================\n\n',
inline: true,
},
{
name: '🔵 **BLUE TEAM STATS**',
value: '=====================\n\n',
inline: true,
},
];
for (let i = 0; i < fetchEndgame.length; i++) {
var fieldsReport = fetchEndgame[i](game);
fields[0].value += fieldsReport[0].value + '\n\n';
fields[1].value += fieldsReport[1].value + '\n\n';
}
fields[0].value = fields[0].value.substring(0, fields[0].value.length - 2);
fields[1].value = fields[1].value.substring(0, fields[1].value.length - 2);
/* EVENTS */
/* PLAYER MOVEMENT */
room.onPlayerJoin = function (player) {
authArray[player.id] = [player.auth, player.conn];
if (roomWebhook != '') {
fetch(roomWebhook, {
method: 'POST',
body: JSON.stringify({
content: `[${getDate()}] ➡️ JOIN (${players.length + 1}/$
{maxPlayers})\n**` +
`${player.name}** [${authArray[player.id][0]}] {$
{authArray[player.id][1]}}`,
username: roomName,
}),
headers: {
'Content-Type': 'application/json',
},
}).then((res) => res);
}
room.sendAnnouncement(
`👋 Welcome ${player.name} !\nEnter "t" before your message to use team
chat and "@@" followed by a player name to PM him !`,
player.id,
welcomeColor,
'bold',
HaxNotification.CHAT
);
updateTeams();
updateAdmins();
if (masterList.findIndex((auth) => auth == player.auth) != -1) {
room.sendAnnouncement(
`Master ${player.name} has connected to the room !`,
null,
announcementColor,
'bold',
HaxNotification.CHAT
);
room.setPlayerAdmin(player.id, true);
} else if (adminList.map((a) => a[0]).findIndex((auth) => auth ==
player.auth) != -1) {
room.sendAnnouncement(
`Admin ${player.name} has connected to the room !`,
null,
announcementColor,
'bold',
HaxNotification.CHAT
);
room.setPlayerAdmin(player.id, true);
}
var sameAuthCheck = players.filter((p) => p.id != player.id && authArray[p.id]
[0] == player.auth);
if (sameAuthCheck.length > 0 && !debugMode) {
var oldPlayerArray = players.filter((p) => p.id != player.id &&
authArray[p.id][0] == player.auth);
for (let oldPlayer of oldPlayerArray) {
ghostKickHandle(oldPlayer, player);
}
}
};
/* PLAYER ACTIVITY */
/* GAME MANAGEMENT */
room.onPositionsReset = function () {
lastTouches = Array(2).fill(null);
lastTeamTouched = Team.SPECTATORS;
playSituation = Situation.KICKOFF;
};
/* MISCELLANEOUS */
room.onGameTick = function () {
checkTime();
getLastTouchOfTheBall();
getGameStats();
handleActivity();
};