3661 lines
148 KiB
JavaScript
3661 lines
148 KiB
JavaScript
// CHANGES BY BORRAGEIROS
|
||
//
|
||
// -Momento en el que se cambia al mapa grande, changeToBigMapOn variable
|
||
// -
|
||
// CHANGES BY BORRAGEIROS
|
||
|
||
|
||
/* VARIABLES */
|
||
|
||
/* ROOM */
|
||
|
||
const roomName = '🇪🇸..3️⃣🆚3️⃣..5️⃣🆚5️⃣..⚽FUTBOL SALA⚽';
|
||
const maxPlayers = 15;
|
||
const roomPublic = true;
|
||
const token = ""; // Insert token here
|
||
|
||
var roomWebhook = ''; // this webhook is used to send the details of the room (chat, join, leave) ; it should be in a private discord channel
|
||
var gameWebhook = ''; // this webhook is used to send the summary of the games ; it should be in a public discord channel
|
||
var fetchRecordingVariable = true;
|
||
var timeLimit = 7;
|
||
var scoreLimit = 3;
|
||
|
||
var gameConfig = {
|
||
roomName: roomName,
|
||
maxPlayers: maxPlayers,
|
||
public: roomPublic,
|
||
noPlayer: true,
|
||
}
|
||
|
||
if (typeof token == 'string' && token.length == 39) {
|
||
gameConfig.token = token;
|
||
}
|
||
|
||
var room = HBInit(gameConfig);
|
||
|
||
const trainingMap = `{"name":"Futsal 3x3","width":755,"height":339,"spawnDistance":310,"bg":{"type":"hockey","width":665,"height":290,"kickOffRadius":80,"cornerRadius":0},"vertexes":[{"x":-665,"y":290,"trait":"ballArea","cMask":["ball"],"bCoef":1},{"x":-665,"y":80,"trait":"ballArea","cMask":["ball"],"bCoef":1},{"x":-665,"y":-80,"trait":"ballArea","cMask":["ball"],"bCoef":1},{"x":-665,"y":-290,"trait":"ballArea","bCoef":1,"cMask":["ball"]},{"x":665,"y":290,"trait":"ballArea","cMask":["ball"],"bCoef":1},{"x":665,"y":80,"trait":"ballArea","cMask":["ball"],"bCoef":1},{"x":665,"y":-80,"trait":"ballArea","cMask":["ball"],"bCoef":1},{"x":665,"y":-290,"trait":"ballArea","cMask":["ball"],"bCoef":1},{"x":0,"y":306,"trait":"kickOffBarrier"},{"x":0,"y":80,"trait":"kickOffBarrier"},{"x":0,"y":-80,"trait":"line"},{"x":0,"y":-306,"trait":"kickOffBarrier"},{"bCoef":0.1,"cMask":["ball"],"trait":"goalNet","x":-693,"y":-80},{"bCoef":0.1,"cMask":["ball"],"trait":"goalNet","x":693,"y":-80},{"bCoef":0.1,"cMask":["ball"],"trait":"goalNet","x":-693,"y":80},{"bCoef":0.1,"cMask":["ball"],"trait":"goalNet","x":693,"y":80},{"trait":"line","x":-665,"y":-215},{"trait":"line","x":-500,"y":-50},{"trait":"line","x":665,"y":-215},{"trait":"line","x":500,"y":-50},{"trait":"line","x":-665,"y":215},{"trait":"line","x":-500,"y":50},{"trait":"line","x":665,"y":215},{"trait":"line","x":500,"y":50},{"bCoef":1,"trait":"ballArea","x":665,"y":290},{"bCoef":1,"trait":"ballArea","x":665,"y":-290},{"bCoef":0,"trait":"line","x":0,"y":290},{"bCoef":0,"trait":"line","x":0,"y":-290},{"x":0,"y":80,"trait":"kickOffBarrier"},{"x":0,"y":-80,"trait":"kickOffBarrier"},{"x":674,"y":-80,"trait":"line","cMask":["ball"],"bCoef":1},{"x":674,"y":-290,"trait":"ballArea","cMask":["ball"],"bCoef":1},{"x":-674,"y":-80,"trait":"line","cMask":["ball"],"bCoef":1},{"x":-674,"y":-290,"trait":"ballArea","cMask":["ball"],"bCoef":1},{"x":-674,"y":80,"trait":"line","cMask":["ball"],"bCoef":1},{"x":-674,"y":290,"trait":"ballArea","cMask":["ball"],"bCoef":1},{"x":674,"y":80,"trait":"line","cMask":["ball"],"bCoef":1},{"x":674,"y":290,"trait":"ballArea","cMask":["ball"],"bCoef":1}],"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":8,"v1":9,"trait":"kickOffBarrier"},{"v0":9,"v1":10,"trait":"kickOffBarrier","curve":180,"cGroup":["blueKO"]},{"v0":9,"v1":10,"trait":"kickOffBarrier","curve":-180,"cGroup":["redKO"]},{"v0":10,"v1":11,"trait":"kickOffBarrier"},{"vis":true,"bCoef":0.1,"cMask":["ball"],"trait":"goalNet","v0":2,"v1":12,"color":"FFFFFF","curve":-35},{"vis":true,"bCoef":0.1,"cMask":["ball"],"trait":"goalNet","v0":6,"v1":13,"color":"FFFFFF","curve":35},{"vis":true,"bCoef":0.1,"cMask":["ball"],"trait":"goalNet","v0":1,"v1":14,"color":"FFFFFF","curve":35},{"vis":true,"bCoef":0.1,"cMask":["ball"],"trait":"goalNet","v0":5,"v1":15,"color":"FFFFFF","curve":-35},{"vis":true,"bCoef":0.1,"cMask":["ball"],"trait":"goalNet","v0":12,"v1":14,"x":-585,"color":"FFFFFF","curve":-35},{"vis":true,"bCoef":0.1,"cMask":["ball"],"trait":"goalNet","v0":13,"v1":15,"x":585,"color":"FFFFFF","curve":35},{"color":"FFFFFF","trait":"line","v0":16,"v1":17,"curve":90},{"color":"FFFFFF","trait":"line","v0":18,"v1":19,"curve":-90},{"color":"FFFFFF","trait":"line","v0":20,"v1":21,"curve":-90},{"color":"FFFFFF","trait":"line","v0":22,"v1":23,"curve":90},{"vis":true,"color":"FFFFFF","bCoef":0,"trait":"line","v0":17,"v1":21,"curve":0},{"vis":true,"color":"FFFFFF","bCoef":0,"trait":"line","v0":19,"v1":23,"curve":0},{"vis":true,"color":"FFFFFF","bCoef":1,"trait":"ballArea","v0":1,"v1":0,"cMask":["ball"],"x":-665},{"vis":true,"color":"FFFFFF","bCoef":1,"trait":"ballArea","v0":5,"v1":4,"cMask":["ball"],"x":665},{"vis":true,"color":"FFFFFF","bCoef":1,"trait":"ballArea","v0":2,"v1":3,"cMask":["ball"],"x":-665},{"vis":true,"color":"FFFFFF","bCoef":1,"trait":"ballArea","v0":6,"v1":7,"cMask":["ball"],"x":665},{"vis":true,"color":"FFFFFF","bCoef":1,"trait":"ballArea","v0":0,"v1":24,"y":290},{"vis":true,"color":"FFFFFF","bCoef":1,"trait":"ballArea","v0":3,"v1":25,"y":-290},{"curve":0,"vis":true,"color":"FFFFFF","bCoef":0,"trait":"line","v0":26,"v1":27},{"curve":-180,"vis":true,"color":"FFFFFF","bCoef":0,"trait":"line","v0":10,"v1":9},{"curve":180,"vis":true,"color":"FFFFFF","bCoef":0,"trait":"line","v0":29,"v1":28},{"curve":0,"vis":true,"color":"FFFFFF","bCoef":0,"trait":"line","v0":2,"v1":1},{"curve":0,"vis":true,"color":"FFFFFF","bCoef":0,"trait":"line","v0":6,"v1":5},{"vis":false,"color":"FFFFFF","bCoef":1,"trait":"ballArea","v0":30,"v1":31,"cMask":["ball"],"x":614},{"vis":false,"color":"FFFFFF","bCoef":1,"trait":"ballArea","v0":32,"v1":33,"cMask":["ball"],"x":-614},{"vis":false,"color":"FFFFFF","bCoef":1,"trait":"ballArea","v0":34,"v1":35,"cMask":["ball"],"x":-614},{"vis":false,"color":"FFFFFF","bCoef":1,"trait":"ballArea","v0":36,"v1":37,"cMask":["ball"],"x":614}],"goals":[{"p0":[-674,-80],"p1":[-674,80],"team":"red"},{"p0":[674,80],"p1":[674,-80],"team":"blue"}],"discs":[{"pos":[-665,80],"trait":"goalPost","color":"FFFFFF","radius":5},{"pos":[-665,-80],"trait":"goalPost","color":"FFFFFF","radius":5},{"pos":[665,80],"trait":"goalPost","color":"FFFFFF","radius":5},{"pos":[665,-80],"trait":"goalPost","color":"FFFFFF","radius":5}],"planes":[{"normal":[0,1],"dist":-290,"trait":"ballArea"},{"normal":[0,-1],"dist":-290,"trait":"ballArea"},{"normal":[0,1],"dist":-339,"bCoef":0.2,"cMask":["all"]},{"normal":[0,-1],"dist":-339,"bCoef":0.2,"cMask":["all"]},{"normal":[1,0],"dist":-755,"bCoef":0.2,"cMask":["all"]},{"normal":[-1,0],"dist":-755,"bCoef":0.2,"cMask":["all"]}],"traits":{"ballArea":{"vis":false,"bCoef":1,"cMask":["ball"]},"goalPost":{"radius":8,"invMass":0,"bCoef":1},"goalNet":{"vis":true,"bCoef":0.1,"cMask":["all"]},"kickOffBarrier":{"vis":false,"bCoef":0.1,"cGroup":["redKO","blueKO"],"cMask":["red","blue"]},"line":{"vis":true,"bCoef":0,"cMask":[""]},"arco":{"radius":2,"cMask":["n/d"],"color":"cccccc"}},"playerPhysics":{"acceleration":0.11,"kickingAcceleration":0.1,"kickStrength":7},"ballPhysics":{"radius":6.4,"color":"EAFF00"}}`;
|
||
const classicMap = trainingMap;
|
||
const bigMap = `{"name":"Futsal 5x5","width":1080,"height":532,"spawnDistance":310,"bg":{"type":"hockey","width":950,"height":460,"kickOffRadius":6,"cornerRadius":0},"vertexes":[{"x":-950,"y":460,"bCoef":1,"cMask":["ball"],"trait":"ballArea","curve":0},{"x":-950,"y":90,"bCoef":1,"cMask":["ball"],"trait":"ballArea","curve":0,"color":"ffffff"},{"x":-950,"y":-90,"bCoef":1,"cMask":["ball"],"trait":"ballArea","curve":0,"color":"ffffff"},{"x":-950,"y":-460,"bCoef":1,"cMask":["ball"],"trait":"ballArea","curve":0},{"x":950,"y":456,"bCoef":1,"cMask":["ball"],"trait":"ballArea","curve":0},{"x":950,"y":90,"bCoef":1,"cMask":["ball"],"trait":"ballArea","curve":0,"color":"ffffff"},{"x":950,"y":-90,"bCoef":1,"cMask":["ball"],"trait":"ballArea","curve":0,"color":"ffffff"},{"x":950,"y":-456,"bCoef":1,"cMask":["ball"],"trait":"ballArea","curve":0},{"x":0,"y":508,"trait":"kickOffBarrier"},{"x":0,"y":150,"trait":"kickOffBarrier"},{"x":0,"y":-150,"trait":"line"},{"x":0,"y":-508,"trait":"kickOffBarrier"},{"x":-995,"y":-90,"bCoef":0.1,"cMask":["ball"],"trait":"goalNet","curve":0},{"x":995,"y":-90,"bCoef":0.1,"cMask":["ball"],"trait":"goalNet","curve":0},{"x":-995,"y":90,"bCoef":0.1,"cMask":["ball"],"trait":"goalNet","curve":0},{"x":995,"y":90,"bCoef":0.1,"cMask":["ball"],"trait":"goalNet","curve":0},{"x":951,"y":460,"bCoef":1,"trait":"ballArea"},{"x":951,"y":-460,"bCoef":1,"trait":"ballArea"},{"x":0,"y":460,"bCoef":0,"trait":"line","curve":0},{"x":0,"y":-460,"bCoef":0,"trait":"line","curve":0},{"x":0,"y":150,"trait":"kickOffBarrier"},{"x":0,"y":-150,"trait":"kickOffBarrier"},{"x":958,"y":-90,"bCoef":1,"cMask":["ball"],"trait":"line","curve":0},{"x":958,"y":-456,"bCoef":1,"cMask":["ball"],"trait":"ballArea","curve":0},{"x":-958,"y":-90,"bCoef":1,"cMask":["ball"],"trait":"line","curve":0},{"x":-958,"y":-456,"bCoef":1,"cMask":["ball"],"trait":"ballArea","curve":0},{"x":-958,"y":90,"bCoef":1,"cMask":["ball"],"trait":"line","curve":0},{"x":-958,"y":456,"bCoef":1,"cMask":["ball"],"trait":"ballArea","curve":0},{"x":958,"y":90,"bCoef":1,"cMask":["ball"],"trait":"line","curve":0},{"x":958,"y":456,"bCoef":1,"cMask":["ball"],"trait":"ballArea","curve":0},{"x":0,"y":-9,"trait":"line","curve":-180},{"x":0,"y":9,"trait":"line","curve":-180},{"x":0,"y":-9,"trait":"line","curve":180},{"x":0,"y":9,"trait":"line","curve":180},{"x":634.21528583524,"y":-109.20953737271,"bCoef":0,"cMask":[""],"trait":"line","curve":0},{"x":634.21528583524,"y":114.16613046747,"bCoef":0,"cMask":[""],"trait":"line","curve":44.336382176589},{"x":634.21528583524,"y":114.16613046747,"bCoef":0,"cMask":[""],"trait":"line","curve":-90},{"x":950,"y":324.62551819445,"bCoef":0,"cMask":[""],"trait":"line","curve":-90},{"x":634.21528583524,"y":-109.20953737271,"bCoef":0,"cMask":[""],"trait":"line","curve":90},{"x":-423.82978278939,"y":449,"bCoef":0.1,"trait":"line"},{"x":-423.82978278939,"y":471,"bCoef":0.1,"trait":"line"},{"x":-222.35509186163,"y":449,"bCoef":0.1,"trait":"line"},{"x":-222.35509186163,"y":471,"bCoef":0.1,"trait":"line"},{"x":386.06898092163,"y":449,"bCoef":0.1,"trait":"line"},{"x":386.06898092163,"y":471,"bCoef":0.1,"trait":"line"},{"x":184.59428999387,"y":449,"bCoef":0.1,"trait":"line"},{"x":184.59428999387,"y":471,"bCoef":0.1,"trait":"line"},{"x":-657.56254462949,"y":460,"bCoef":0.1,"trait":"line"},{"x":-657.56254462949,"y":473,"bCoef":0.1,"trait":"line"},{"x":975,"y":193.91895440419,"bCoef":0.1,"trait":"line"},{"x":956,"y":193.91895440419,"bCoef":0.1,"trait":"line"},{"x":975,"y":-188.96236130943,"bCoef":0.1,"trait":"line"},{"x":956,"y":-188.96236130943,"bCoef":0.1,"trait":"line"},{"x":-667.82213435646,"y":-460,"bCoef":0.1,"trait":"line"},{"x":-667.82213435646,"y":-473,"bCoef":0.1,"trait":"line"},{"x":621.80174276174,"y":460,"bCoef":0.1,"trait":"line"},{"x":621.80174276174,"y":473,"bCoef":0.1,"trait":"line"},{"x":644.74331148229,"y":-460,"bCoef":0.1,"trait":"line"},{"x":644.74331148229,"y":-473,"bCoef":0.1,"trait":"line"},{"x":634.35340467604,"y":4.2212921610516,"bCoef":0.1,"trait":"line","curve":180},{"x":634.35340467604,"y":1.7712285482462,"bCoef":0.1,"trait":"line","curve":180},{"x":634.35340467604,"y":6.6713557738571,"bCoef":0.1,"trait":"line","curve":180},{"x":634.35340467604,"y":-0.67883506455928,"bCoef":0.1,"trait":"line","curve":180},{"x":634.35340467604,"y":0.54619674184346,"bCoef":0.1,"trait":"line","curve":180},{"x":634.35340467604,"y":5.4463239674544,"bCoef":0.1,"trait":"line","curve":180},{"x":634.35340467604,"y":-1.2913509677606,"bCoef":0.1,"trait":"line","curve":180},{"x":634.35340467604,"y":7.2838716770584,"bCoef":0.1,"trait":"line","curve":180},{"x":484.86942705432,"y":4.2212921610516,"bCoef":0.1,"trait":"line","curve":180},{"x":484.86942705432,"y":1.7712285482462,"bCoef":0.1,"trait":"line","curve":180},{"x":484.86942705432,"y":6.6713557738571,"bCoef":0.1,"trait":"line","curve":180},{"x":484.86942705432,"y":-0.67883506455928,"bCoef":0.1,"trait":"line","curve":180},{"x":484.86942705432,"y":0.54619674184346,"bCoef":0.1,"trait":"line","curve":180},{"x":484.86942705432,"y":5.4463239674544,"bCoef":0.1,"trait":"line","curve":180},{"x":484.86942705432,"y":-1.2913509677606,"bCoef":0.1,"trait":"line","curve":180},{"x":484.86942705432,"y":7.2838716770584,"bCoef":0.1,"trait":"line","curve":180},{"x":-975,"y":-191.85660774843,"bCoef":0.1,"trait":"line"},{"x":-956,"y":-191.96236130943,"bCoef":0.1,"trait":"line"},{"x":-975,"y":190.91895440419,"bCoef":0.1,"trait":"line"},{"x":-956,"y":190.91895440419,"bCoef":0.1,"trait":"line"},{"x":-950,"y":432.90041943973,"bCoef":0.1,"trait":"line","curve":-90},{"x":-926.21802170761,"y":460,"bCoef":0.1,"trait":"line","curve":-90},{"x":-950,"y":-433.32499678239,"bCoef":0.1,"trait":"line","curve":90},{"x":-925.43621788149,"y":-460,"bCoef":0.1,"trait":"line","curve":90},{"x":950,"y":-433.36622514797,"bCoef":0.1,"trait":"line","curve":-90},{"x":927.73220749769,"y":-460,"bCoef":0.1,"trait":"line","curve":-90},{"x":950,"y":434.55334331787,"bCoef":0.1,"trait":"line","curve":90},{"x":925.51401132381,"y":460,"bCoef":0.1,"trait":"line","curve":90},{"x":950,"y":-319.66892509968,"bCoef":0,"trait":"line","curve":90},{"x":-635.67083595539,"y":111.16613046747,"bCoef":0,"cMask":[""],"trait":"line","curve":0},{"x":-635.67083595539,"y":-112.20953737271,"bCoef":0,"cMask":[""],"trait":"line","curve":44.336382176589},{"x":-950,"y":-322.66892509968,"bCoef":0,"cMask":[""],"trait":"line","curve":-90},{"x":-635.82253673536,"y":-2.314063297901,"bCoef":0.1,"trait":"line","curve":180},{"x":-635.83851134042,"y":0.13595112921681,"bCoef":0.1,"trait":"line","curve":180},{"x":-635.80656213031,"y":-4.764077725019,"bCoef":0.1,"trait":"line","curve":180},{"x":-635.85448594547,"y":2.5859655563347,"bCoef":0.1,"trait":"line","curve":180},{"x":-635.84649864294,"y":1.3609583427757,"bCoef":0.1,"trait":"line","curve":180},{"x":-635.81454943284,"y":-3.53907051146,"bCoef":0.1,"trait":"line","curve":180},{"x":-635.85847959673,"y":3.1984691631142,"bCoef":0.1,"trait":"line","curve":180},{"x":-635.80256847905,"y":-5.3765813317984,"bCoef":0.1,"trait":"line","curve":180},{"x":-486.3415600448,"y":-1.3935524756233,"bCoef":0.1,"trait":"line","curve":180},{"x":-486.35753464985,"y":1.0564619514946,"bCoef":0.1,"trait":"line","curve":180},{"x":-486.32558543975,"y":-3.8435669027412,"bCoef":0.1,"trait":"line","curve":180},{"x":-486.3735092549,"y":3.5064763786125,"bCoef":0.1,"trait":"line","curve":180},{"x":-486.36552195238,"y":2.2814691650535,"bCoef":0.1,"trait":"line","curve":180},{"x":-486.33357274227,"y":-2.6185596891822,"bCoef":0.1,"trait":"line","curve":180},{"x":-486.37750290617,"y":4.1189799853919,"bCoef":0.1,"trait":"line","curve":180},{"x":-486.32159178848,"y":-4.4560705095206,"bCoef":0.1,"trait":"line","curve":180},{"x":-950,"y":321.62551819445,"bCoef":0,"trait":"line","curve":90},{"x":486.4717644406,"y":-216.68073468914,"bCoef":0.1,"trait":"line","curve":200},{"x":486.26181026907,"y":-213.90354363921,"bCoef":0.1,"trait":"line","curve":200},{"x":484.90815678836,"y":227.79125744183,"bCoef":0.1,"trait":"line","curve":200},{"x":484.69820261683,"y":230.56844849177,"bCoef":0.1,"trait":"line","curve":200},{"x":-487.89251107699,"y":-222.71985942166,"bCoef":0.1,"trait":"line","curve":200},{"x":-488.10246524852,"y":-219.94266837173,"bCoef":0.1,"trait":"line","curve":200},{"x":-487.11070725087,"y":223.27169507557,"bCoef":0.1,"trait":"line","curve":200},{"x":-487.3206614224,"y":226.04888612551,"bCoef":0.1,"trait":"line","curve":200},{"x":-0.077614373673782,"y":-2.4626457981722,"bCoef":0.1,"trait":"line","curve":180},{"x":-0.10499941090626,"y":2.3835365851378,"bCoef":0.1,"trait":"line","curve":180},{"x":-0.050229336441873,"y":-7.3088281814824,"bCoef":0.1,"trait":"line","curve":180},{"x":-0.13238444813857,"y":7.2297189684479,"bCoef":0.1,"trait":"line","curve":180},{"x":-0.11869192952281,"y":4.8066277767929,"bCoef":0.1,"trait":"line","curve":180},{"x":-0.063921855057799,"y":-4.8857369898273,"bCoef":0.1,"trait":"line","curve":180},{"x":-0.13923070744664,"y":8.4412645642754,"bCoef":0.1,"trait":"line","curve":180},{"x":-0.043383077133171,"y":-8.5203737773099,"bCoef":0.1,"trait":"line","curve":180},{"x":0.77952848346911,"y":1.5373542018278,"bCoef":0.1,"trait":"line","curve":180},{"x":2.7521434462366,"y":3.3835365851378,"bCoef":0.1,"trait":"line","curve":180},{"x":0.80691352070102,"y":-3.3088281814824,"bCoef":0.1,"trait":"line","curve":180},{"x":1.7247584090043,"y":2.2297189684479,"bCoef":0.1,"trait":"line","curve":180},{"x":2.73845092762,"y":5.8066277767929,"bCoef":0.1,"trait":"line","curve":180},{"x":0.79322100208503,"y":-0.88573698982727,"bCoef":0.1,"trait":"line","curve":180},{"x":1.7179121496962,"y":3.4412645642754,"bCoef":0.1,"trait":"line","curve":180},{"x":0.81375978000966,"y":-4.5203737773099,"bCoef":0.1,"trait":"line","curve":180},{"x":-950,"y":-322.66892509968,"bCoef":0,"cMask":[""],"trait":"line","curve":-90},{"x":-950,"y":321.62551819445,"bCoef":0,"trait":"line","curve":90},{"x":-635.67083595539,"y":111.16613046747,"bCoef":0,"cMask":[""],"trait":"line","curve":90},{"x":-950,"y":321.62551819445,"bCoef":0,"trait":"line","curve":90},{"x":-635.67083595539,"y":-112.20953737271,"bCoef":0,"cMask":[""],"trait":"line","curve":-90},{"x":-950,"y":-322.66892509968,"bCoef":0,"cMask":[""],"trait":"line","curve":-90}],"segments":[{"v0":0,"v1":1,"curve":0,"trait":"ballArea"},{"v0":2,"v1":3,"trait":"ballArea"},{"v0":4,"v1":5,"trait":"ballArea","x":951},{"v0":6,"v1":7,"trait":"ballArea","x":951},{"v0":8,"v1":9,"trait":"kickOffBarrier","x":0},{"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","x":0},{"v0":2,"v1":12,"curve":0,"vis":true,"color":"FFFFFF","bCoef":0.1,"cMask":["ball"],"trait":"goalNet","y":-95},{"v0":6,"v1":13,"curve":0,"vis":true,"color":"FFFFFF","bCoef":0.1,"cMask":["ball"],"trait":"goalNet","y":-95},{"v0":1,"v1":14,"curve":0,"vis":true,"color":"FFFFFF","bCoef":0.1,"cMask":["ball"],"trait":"goalNet","y":95},{"v0":5,"v1":15,"curve":0,"vis":true,"color":"FFFFFF","bCoef":0.1,"cMask":["ball"],"trait":"goalNet","y":95},{"v0":12,"v1":14,"curve":0,"vis":true,"color":"FFFFFF","bCoef":0.1,"cMask":["ball"],"trait":"goalNet","x":-821},{"v0":13,"v1":15,"curve":0,"vis":true,"color":"FFFFFF","bCoef":0.1,"cMask":["ball"],"trait":"goalNet","x":585},{"v0":1,"v1":0,"curve":0,"vis":true,"color":"FFFFFF","bCoef":1,"cMask":["ball"],"trait":"ballArea","x":-950},{"v0":5,"v1":4,"curve":0,"vis":true,"color":"FFFFFF","bCoef":1,"cMask":["ball"],"trait":"ballArea","x":950},{"v0":2,"v1":3,"curve":0,"vis":true,"color":"FFFFFF","bCoef":1,"cMask":["ball"],"trait":"ballArea","x":-950},{"v0":6,"v1":7,"curve":0,"vis":true,"color":"FFFFFF","bCoef":1,"cMask":["ball"],"trait":"ballArea","x":950},{"v0":0,"v1":16,"vis":true,"color":"FFFFFF","bCoef":1,"trait":"ballArea","y":460},{"v0":3,"v1":17,"vis":true,"color":"FFFFFF","bCoef":1,"trait":"ballArea","y":-460},{"v0":18,"v1":19,"curve":0,"vis":true,"color":"FFFFFF","bCoef":0,"trait":"line"},{"v0":10,"v1":9,"curve":-180,"vis":true,"color":"FFFFFF","bCoef":0,"trait":"line"},{"v0":21,"v1":20,"curve":180,"vis":true,"color":"FFFFFF","bCoef":0,"trait":"line"},{"v0":2,"v1":1,"curve":0,"vis":true,"color":"ffffff","bCoef":0,"trait":"line","x":-950},{"v0":6,"v1":5,"curve":0,"vis":true,"color":"ffffff","bCoef":0,"trait":"line"},{"v0":22,"v1":23,"curve":0,"vis":false,"color":"FFFFFF","bCoef":1,"cMask":["ball"],"trait":"ballArea","x":958},{"v0":24,"v1":25,"curve":0,"vis":false,"color":"FFFFFF","bCoef":1,"cMask":["ball"],"trait":"ballArea","x":-958},{"v0":26,"v1":27,"curve":0,"vis":false,"color":"FFFFFF","bCoef":1,"cMask":["ball"],"trait":"ballArea","x":-958},{"v0":28,"v1":29,"curve":0,"vis":false,"color":"FFFFFF","bCoef":1,"cMask":["ball"],"trait":"ballArea","x":958},{"v0":30,"v1":31,"curve":-180,"vis":true,"color":"FFFFFF","bCoef":0,"trait":"line","x":572},{"v0":32,"v1":33,"curve":180,"vis":true,"color":"FFFFFF","bCoef":0,"trait":"line","x":0},{"v0":34,"v1":35,"curve":0,"vis":true,"color":"F8F8F8","bCoef":0,"cMask":[""],"trait":"line"},{"v0":36,"v1":37,"curve":-90,"vis":true,"color":"F8F8F8","bCoef":0,"cMask":[""],"trait":"line"},{"v0":39,"v1":40,"curve":0,"vis":true,"color":"F8F8F8","bCoef":0.1,"trait":"line","x":-240},{"v0":41,"v1":42,"curve":0,"vis":true,"color":"F8F8F8","bCoef":0.1,"trait":"line","x":-120},{"v0":43,"v1":44,"curve":0,"vis":true,"color":"F8F8F8","bCoef":0.1,"trait":"line","x":240},{"v0":45,"v1":46,"curve":0,"vis":true,"color":"F8F8F8","bCoef":0.1,"trait":"line","x":120},{"v0":47,"v1":48,"curve":0,"vis":true,"color":"F8F8F8","bCoef":0.1,"trait":"line","x":-381},{"v0":49,"v1":50,"curve":0,"vis":true,"color":"F8F8F8","bCoef":0.1,"trait":"line","x":-240,"y":251.96814834},{"v0":51,"v1":52,"curve":0,"vis":true,"color":"F8F8F8","bCoef":0.1,"trait":"line","x":-240,"y":-251.96814834},{"v0":53,"v1":54,"curve":0,"vis":true,"color":"F8F8F8","bCoef":0.1,"trait":"line","x":-381},{"v0":55,"v1":56,"curve":0,"vis":true,"color":"F8F8F8","bCoef":0.1,"trait":"line","x":381},{"v0":57,"v1":58,"curve":0,"vis":true,"color":"F8F8F8","bCoef":0.1,"trait":"line","x":381},{"v0":60,"v1":59,"curve":180.00000000015,"vis":true,"color":"F8F8F8","bCoef":0.1,"trait":"line","x":375},{"v0":59,"v1":60,"curve":180.00000000011,"vis":true,"color":"F8F8F8","bCoef":0.1,"trait":"line","x":375},{"v0":62,"v1":61,"curve":179.99999999999,"vis":true,"color":"F8F8F8","bCoef":0.1,"trait":"line","x":375},{"v0":61,"v1":62,"curve":180.00000000001,"vis":true,"color":"F8F8F8","bCoef":0.1,"trait":"line","x":375},{"v0":64,"v1":63,"curve":180.00000000006,"vis":true,"color":"F8F8F8","bCoef":0.1,"trait":"line","x":375},{"v0":63,"v1":64,"curve":180.00000000001,"vis":true,"color":"F8F8F8","bCoef":0.1,"trait":"line","x":375},{"v0":66,"v1":65,"curve":179.99999999999,"vis":true,"color":"F8F8F8","bCoef":0.1,"trait":"line","x":375},{"v0":65,"v1":66,"curve":179.99999999999,"vis":true,"color":"F8F8F8","bCoef":0.1,"trait":"line","x":375},{"v0":68,"v1":67,"curve":179.99999999994,"vis":true,"color":"F8F8F8","bCoef":0.1,"trait":"line","x":277.5},{"v0":67,"v1":68,"curve":180.00000000006,"vis":true,"color":"F8F8F8","bCoef":0.1,"trait":"line","x":277.5},{"v0":70,"v1":69,"curve":180,"vis":true,"color":"F8F8F8","bCoef":0.1,"trait":"line","x":277.5},{"v0":69,"v1":70,"curve":180,"vis":true,"color":"F8F8F8","bCoef":0.1,"trait":"line","x":277.5},{"v0":72,"v1":71,"curve":179.99999999998,"vis":true,"color":"F8F8F8","bCoef":0.1,"trait":"line","x":277.5},{"v0":71,"v1":72,"curve":179.99999999998,"vis":true,"color":"F8F8F8","bCoef":0.1,"trait":"line","x":277.5},{"v0":74,"v1":73,"curve":180,"vis":true,"color":"F8F8F8","bCoef":0.1,"trait":"line","x":277.5},{"v0":73,"v1":74,"curve":180,"vis":true,"color":"F8F8F8","bCoef":0.1,"trait":"line","x":277.5},{"v0":75,"v1":76,"curve":0,"vis":true,"color":"F8F8F8","bCoef":0.1,"trait":"line","x":-240,"y":123},{"v0":77,"v1":78,"curve":0,"vis":true,"color":"F8F8F8","bCoef":0.1,"trait":"line","x":-240,"y":251.96814834},{"v0":80,"v1":79,"curve":-91.636910923379,"vis":true,"color":"F8F8F8","bCoef":0.1,"trait":"line"},{"v0":82,"v1":81,"curve":91.636910923384,"vis":true,"color":"F8F8F8","bCoef":0.1,"trait":"line"},{"v0":84,"v1":83,"curve":-91.636910923386,"vis":true,"color":"F8F8F8","bCoef":0.1,"trait":"line"},{"v0":86,"v1":85,"curve":91.636910923367,"vis":true,"color":"F8F8F8","bCoef":0.1,"trait":"line"},{"v0":38,"v1":87,"curve":90,"vis":true,"color":"F8F8F8","bCoef":0,"trait":"line"},{"v0":88,"v1":89,"curve":0,"vis":true,"color":"F8F8F8","bCoef":0,"cMask":[""],"trait":"line"},{"v0":92,"v1":91,"curve":180.04149903472,"vis":true,"color":"F8F8F8","bCoef":0.1,"trait":"line","x":375},{"v0":91,"v1":92,"curve":180.04149903448,"vis":true,"color":"F8F8F8","bCoef":0.1,"trait":"line","x":375},{"v0":94,"v1":93,"curve":180.04149903461,"vis":true,"color":"F8F8F8","bCoef":0.1,"trait":"line","x":375},{"v0":93,"v1":94,"curve":180.04149903457,"vis":true,"color":"F8F8F8","bCoef":0.1,"trait":"line","x":375},{"v0":96,"v1":95,"curve":180.0414990346,"vis":true,"color":"F8F8F8","bCoef":0.1,"trait":"line","x":375},{"v0":95,"v1":96,"curve":180.04149903458,"vis":true,"color":"F8F8F8","bCoef":0.1,"trait":"line","x":375},{"v0":98,"v1":97,"curve":180.04149903458,"vis":true,"color":"F8F8F8","bCoef":0.1,"trait":"line","x":375},{"v0":97,"v1":98,"curve":180.0414990346,"vis":true,"color":"F8F8F8","bCoef":0.1,"trait":"line","x":375},{"v0":100,"v1":99,"curve":180.04149903447,"vis":true,"color":"F8F8F8","bCoef":0.1,"trait":"line","x":277.5},{"v0":99,"v1":100,"curve":180.04149903471,"vis":true,"color":"F8F8F8","bCoef":0.1,"trait":"line","x":277.5},{"v0":102,"v1":101,"curve":180.0414990346,"vis":true,"color":"F8F8F8","bCoef":0.1,"trait":"line","x":277.5},{"v0":101,"v1":102,"curve":180.04149903457,"vis":true,"color":"F8F8F8","bCoef":0.1,"trait":"line","x":277.5},{"v0":104,"v1":103,"curve":180.04149903454,"vis":true,"color":"F8F8F8","bCoef":0.1,"trait":"line","x":277.5},{"v0":103,"v1":104,"curve":180.04149903457,"vis":true,"color":"F8F8F8","bCoef":0.1,"trait":"line","x":277.5},{"v0":106,"v1":105,"curve":180.04149903458,"vis":true,"color":"F8F8F8","bCoef":0.1,"trait":"line","x":277.5},{"v0":105,"v1":106,"curve":180.04149903459,"vis":true,"color":"F8F8F8","bCoef":0.1,"trait":"line","x":277.5},{"v0":108,"v1":109,"curve":-196.43548932859,"vis":true,"color":"F8F8F8","bCoef":0.1,"trait":"line"},{"v0":109,"v1":108,"curve":-211.97212519444,"vis":true,"color":"F8F8F8","bCoef":0.1,"trait":"line"},{"v0":110,"v1":111,"curve":-196.43548932841,"vis":true,"color":"F8F8F8","bCoef":0.1,"trait":"line"},{"v0":111,"v1":110,"curve":-211.97212519486,"vis":true,"color":"F8F8F8","bCoef":0.1,"trait":"line"},{"v0":112,"v1":113,"curve":-196.43548932818,"vis":true,"color":"F8F8F8","bCoef":0.1,"trait":"line"},{"v0":113,"v1":112,"curve":-211.97212519503,"vis":true,"color":"F8F8F8","bCoef":0.1,"trait":"line"},{"v0":114,"v1":115,"curve":-196.4354893283,"vis":true,"color":"F8F8F8","bCoef":0.1,"trait":"line"},{"v0":115,"v1":114,"curve":-211.97212519445,"vis":true,"color":"F8F8F8","bCoef":0.1,"trait":"line"},{"v0":117,"v1":116,"curve":179.83332296199,"vis":true,"color":"F8F8F8","bCoef":0.1,"trait":"line","x":277.5},{"v0":116,"v1":117,"curve":179.8333229623,"vis":true,"color":"F8F8F8","bCoef":0.1,"trait":"line","x":277.5},{"v0":119,"v1":118,"curve":179.83332296215,"vis":true,"color":"F8F8F8","bCoef":0.1,"trait":"line","x":277.5},{"v0":118,"v1":119,"curve":179.8333229621,"vis":true,"color":"F8F8F8","bCoef":0.1,"trait":"line","x":277.5},{"v0":121,"v1":120,"curve":179.83332296204,"vis":true,"color":"F8F8F8","bCoef":0.1,"trait":"line","x":277.5},{"v0":120,"v1":121,"curve":179.83332296211,"vis":true,"color":"F8F8F8","bCoef":0.1,"trait":"line","x":277.5},{"v0":123,"v1":122,"curve":179.8333229621,"vis":true,"color":"F8F8F8","bCoef":0.1,"trait":"line","x":277.5},{"v0":122,"v1":123,"curve":179.83332296208,"vis":true,"color":"F8F8F8","bCoef":0.1,"trait":"line","x":277.5},{"v0":125,"v1":124,"curve":179.83332296199,"vis":true,"color":"F8F8F8","bCoef":0.1,"trait":"line","x":277.5},{"v0":124,"v1":125,"curve":179.8333229623,"vis":true,"color":"F8F8F8","bCoef":0.1,"trait":"line","x":277.5},{"v0":127,"v1":126,"curve":179.83332296215,"vis":true,"color":"F8F8F8","bCoef":0.1,"trait":"line","x":277.5},{"v0":126,"v1":127,"curve":179.8333229621,"vis":true,"color":"F8F8F8","bCoef":0.1,"trait":"line","x":277.5},{"v0":129,"v1":128,"curve":179.83332296204,"vis":true,"color":"F8F8F8","bCoef":0.1,"trait":"line","x":277.5},{"v0":128,"v1":129,"curve":179.83332296211,"vis":true,"color":"F8F8F8","bCoef":0.1,"trait":"line","x":277.5},{"v0":131,"v1":130,"curve":179.8333229621,"vis":true,"color":"F8F8F8","bCoef":0.1,"trait":"line","x":277.5},{"v0":130,"v1":131,"curve":179.83332296208,"vis":true,"color":"F8F8F8","bCoef":0.1,"trait":"line","x":277.5},{"v0":134,"v1":135,"curve":90,"vis":true,"color":"F8F8F8","bCoef":0,"trait":"line"},{"v0":136,"v1":137,"curve":-90,"vis":true,"color":"F8F8F8","bCoef":0,"cMask":[""],"trait":"line"}],"goals":[{"p0":[-957.4,-90],"p1":[-957.4,90],"team":"red"},{"p0":[957.4,90],"p1":[957.4,-90],"team":"blue"}],"discs":[{"radius":5,"pos":[-950,90],"color":"6666CC","trait":"goalPost"},{"radius":5,"pos":[-950,-90],"color":"6666CC","trait":"goalPost"},{"radius":5,"pos":[950,90],"color":"6666CC","trait":"goalPost"},{"radius":5,"pos":[950,-90],"color":"6666CC","trait":"goalPost"},{"radius":3,"invMass":0,"pos":[-950,460],"color":"FFCC00","bCoef":0.1,"trait":"line"},{"radius":3,"invMass":0,"pos":[-950,-460],"color":"FFCC00","bCoef":0.1,"trait":"line"},{"radius":3,"invMass":0,"pos":[950,-460],"color":"FFCC00","bCoef":0.1,"trait":"line"},{"radius":3,"invMass":0,"pos":[950,460],"color":"FFCC00","bCoef":0.1,"trait":"line"}],"planes":[{"normal":[0,1],"dist":-456,"trait":"ballArea"},{"normal":[0,-1],"dist":-456,"trait":"ballArea"},{"normal":[0,1],"dist":-508,"bCoef":0.2,"cMask":["all"]},{"normal":[0,-1],"dist":-508,"bCoef":0.2,"cMask":["all"]},{"normal":[1,0],"dist":-1002,"bCoef":0.2,"cMask":["all"]},{"normal":[-1,0],"dist":-1002,"bCoef":0.2,"cMask":["all"]}],"traits":{"ballArea":{"vis":false,"bCoef":1,"cMask":["ball"]},"goalPost":{"radius":8,"invMass":0,"bCoef":1},"goalNet":{"vis":true,"bCoef":0.1,"cMask":["all"]},"kickOffBarrier":{"vis":false,"bCoef":0.1,"cGroup":["redKO","blueKO"],"cMask":["red","blue"]},"line":{"vis":true,"bCoef":0,"cMask":[""]},"arco":{"radius":2,"cMask":["n/d"],"color":"cccccc"}},"playerPhysics":{"bCoef":0,"acceleration":0.11,"kickingAcceleration":0.083,"kickStrength":5},"ballPhysics":{"radius":6.4,"bCoef":0.4,"invMass":1.5,"damping":0.99,"color":"FFCC00"}}`;
|
||
|
||
var currentStadium = 'training';
|
||
var bigMapObj = JSON.parse(trainingMap);
|
||
|
||
room.setScoreLimit(scoreLimit);
|
||
room.setTimeLimit(timeLimit);
|
||
room.setTeamsLock(true);
|
||
room.setKickRateLimit(6, 0, 0);
|
||
|
||
var masterPassword = 10000 + getRandomInt(90000);
|
||
var roomPassword = '';
|
||
|
||
/* OPTIONS */
|
||
|
||
// by borrageiros
|
||
var changeToBigMapOn = 8;
|
||
// by borrageiros
|
||
|
||
var drawTimeLimit = Infinity;
|
||
var teamSize = 5;
|
||
var maxAdmins = 0;
|
||
var disableBans = false;
|
||
var debugMode = false;
|
||
var afkLimit = debugMode ? Infinity : 12;
|
||
|
||
var defaultSlowMode = 0.5;
|
||
var chooseModeSlowMode = 1;
|
||
var slowMode = defaultSlowMode;
|
||
var SMSet = new Set();
|
||
|
||
var hideClaimMessage = true;
|
||
var mentionPlayersUnpause = true;
|
||
|
||
/* 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 MutePlayer {
|
||
constructor(name, id, auth) {
|
||
this.id = MutePlayer.incrementId();
|
||
this.name = name;
|
||
this.playerId = id;
|
||
this.auth = auth;
|
||
this.unmuteTimeout = null;
|
||
}
|
||
|
||
static incrementId() {
|
||
if (!this.latestId) this.latestId = 1
|
||
else this.latestId++
|
||
return this.latestId
|
||
}
|
||
|
||
setDuration(minutes) {
|
||
this.unmuteTimeout = setTimeout(() => {
|
||
room.sendAnnouncement(
|
||
`You have been unmuted.`,
|
||
this.playerId,
|
||
announcementColor,
|
||
"bold",
|
||
HaxNotification.CHAT
|
||
);
|
||
this.remove();
|
||
}, minutes * 60 * 1000);
|
||
muteArray.add(this);
|
||
}
|
||
|
||
remove() {
|
||
this.unmuteTimeout = null;
|
||
muteArray.removeById(this.id);
|
||
}
|
||
}
|
||
|
||
class MuteList {
|
||
constructor() {
|
||
this.list = [];
|
||
}
|
||
|
||
add(mutePlayer) {
|
||
this.list.push(mutePlayer);
|
||
return mutePlayer;
|
||
}
|
||
|
||
getById(id) {
|
||
var index = this.list.findIndex(mutePlayer => mutePlayer.id === id);
|
||
if (index !== -1) {
|
||
return this.list[index];
|
||
}
|
||
return null;
|
||
}
|
||
|
||
getByPlayerId(id) {
|
||
var index = this.list.findIndex(mutePlayer => mutePlayer.playerId === id);
|
||
if (index !== -1) {
|
||
return this.list[index];
|
||
}
|
||
return null;
|
||
}
|
||
|
||
getByAuth(auth) {
|
||
var index = this.list.findIndex(mutePlayer => mutePlayer.auth === auth);
|
||
if (index !== -1) {
|
||
return this.list[index];
|
||
}
|
||
return null;
|
||
}
|
||
|
||
removeById(id) {
|
||
var index = this.list.findIndex(mutePlayer => mutePlayer.id === id);
|
||
if (index !== -1) {
|
||
this.list.splice(index, 1);
|
||
}
|
||
}
|
||
|
||
removeByAuth(auth) {
|
||
var index = this.list.findIndex(mutePlayer => mutePlayer.auth === auth);
|
||
if (index !== -1) {
|
||
this.list.splice(index, 1);
|
||
}
|
||
}
|
||
}
|
||
|
||
class BallTouch {
|
||
constructor(player, time, goal, position) {
|
||
this.player = player;
|
||
this.time = time;
|
||
this.goal = goal;
|
||
this.position = position;
|
||
}
|
||
}
|
||
|
||
class HaxStatistics {
|
||
constructor(playerName = '') {
|
||
this.playerName = playerName;
|
||
this.games = 0;
|
||
this.wins = 0;
|
||
this.winrate = '0.00%';
|
||
this.playtime = 0;
|
||
this.goals = 0;
|
||
this.assists = 0;
|
||
this.CS = 0;
|
||
this.ownGoals = 0;
|
||
}
|
||
}
|
||
|
||
/* PLAYERS */
|
||
|
||
const Team = { SPECTATORS: 0, RED: 1, BLUE: 2 };
|
||
const State = { PLAY: 0, PAUSE: 1, STOP: 2 };
|
||
const Role = { PLAYER: 0, ADMIN_TEMP: 1, ADMIN_PERM: 2, MASTER: 3 };
|
||
const HaxNotification = { NONE: 0, CHAT: 1, MENTION: 2 };
|
||
const Situation = { STOP: 0, KICKOFF: 1, PLAY: 2, GOAL: 3 };
|
||
|
||
var gameState = State.STOP;
|
||
var playSituation = Situation.STOP;
|
||
var goldenGoal = false;
|
||
|
||
var playersAll = [];
|
||
var players = [];
|
||
var teamRed = [];
|
||
var teamBlue = [];
|
||
var teamSpec = [];
|
||
|
||
var teamRedStats = [];
|
||
var teamBlueStats = [];
|
||
|
||
var banList = [];
|
||
|
||
/* STATS */
|
||
|
||
var possession = [0, 0];
|
||
var actionZoneHalf = [0, 0];
|
||
var lastWinner = Team.SPECTATORS;
|
||
var streak = 0;
|
||
|
||
/* AUTH */
|
||
|
||
var authArray = [];
|
||
var adminList = [
|
||
["amuZ3Vk-M6Vk8_DuphOjismmfRRo4SQ44RyUuLb9nLc", "borrageiros"], // borrageiros
|
||
["_LSQgSnedi0Y2E86tf5-ql6fLYORVHUDsEvilNFXKA4", "El santo"] // xoel
|
||
// ['INSERT_AUTH_HERE_1', 'NICK_OF_ADMIN_1'],
|
||
// ['INSERT_AUTH_HERE_2', 'NICK_OF_ADMIN_2'],
|
||
];
|
||
var masterList = [
|
||
'amuZ3Vk-M6Vk8_DuphOjismmfRRo4SQ44RyUuLb9nLc',
|
||
'_LSQgSnedi0Y2E86tf5-ql6fLYORVHUDsEvilNFXKA4'
|
||
];
|
||
|
||
/* 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,
|
||
},
|
||
afk: {
|
||
aliases: [],
|
||
roles: Role.PLAYER,
|
||
desc: `
|
||
This command makes you go AFK.
|
||
It has constraints: 1 minute minimum of AFK time, 5 minutes maximum and 10 minutes cooldown.`,
|
||
function: afkCommand,
|
||
},
|
||
afks: {
|
||
aliases: ['afklist'],
|
||
roles: Role.PLAYER,
|
||
desc: `
|
||
This command shows all the players that are AFK.`,
|
||
function: afkListCommand,
|
||
},
|
||
bb: {
|
||
aliases: ['bye', 'gn', 'cya'],
|
||
roles: Role.PLAYER,
|
||
desc: `
|
||
This command makes you leave instantly (use recommended).`,
|
||
function: leaveCommand,
|
||
},
|
||
me: {
|
||
aliases: ['stat', 'stats'],
|
||
roles: Role.PLAYER,
|
||
desc: `
|
||
This command shows your global stats in the room.`,
|
||
function: globalStatsCommand,
|
||
},
|
||
rename: {
|
||
aliases: [],
|
||
roles: Role.PLAYER,
|
||
desc: `
|
||
This command allows you to rename yourself for the leaderboard.`,
|
||
function: renameCommand,
|
||
},
|
||
games: {
|
||
aliases: [],
|
||
roles: Role.PLAYER,
|
||
desc: `
|
||
This command shows the top 5 players with the most games in the room.`,
|
||
function: statsLeaderboardCommand,
|
||
},
|
||
wins: {
|
||
aliases: [],
|
||
roles: Role.PLAYER,
|
||
desc: `
|
||
This command shows the top 5 players with the most wins in the room.`,
|
||
function: statsLeaderboardCommand,
|
||
},
|
||
goals: {
|
||
aliases: [],
|
||
roles: Role.PLAYER,
|
||
desc: `
|
||
This command shows the top 5 players with the most goals in the room.`,
|
||
function: statsLeaderboardCommand,
|
||
},
|
||
assists: {
|
||
aliases: [],
|
||
roles: Role.PLAYER,
|
||
desc: `
|
||
This command shows the top 5 players with the most assists in the room.`,
|
||
function: statsLeaderboardCommand,
|
||
},
|
||
cs: {
|
||
aliases: [],
|
||
roles: Role.PLAYER,
|
||
desc: `
|
||
This command shows the top 5 players with the most CS in the room.`,
|
||
function: statsLeaderboardCommand,
|
||
},
|
||
playtime: {
|
||
aliases: [],
|
||
roles: Role.PLAYER,
|
||
desc: `
|
||
This command shows the top 5 players with the most time played in the room.`,
|
||
function: statsLeaderboardCommand,
|
||
},
|
||
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,
|
||
},
|
||
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,
|
||
},
|
||
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,
|
||
},
|
||
mute: {
|
||
aliases: ['m'],
|
||
roles: Role.ADMIN_TEMP,
|
||
desc: `
|
||
This command allows to mute a player. He won't be able to talk for a certain duration, and can be unmuted at any time by admins.
|
||
It takes 2 arguments:
|
||
Argument 1: #<id> where <id> is the id of the player targeted. This won't work if the player is an admin.
|
||
Argument 2 (optional): <duration> where <duration> is the duration of the mute in minutes. If no value is provided, the mute lasts for the default duration, ${muteDuration} minutes.
|
||
Example: !mute #3 20 will mute the player with id 3 for 20 minutes.`,
|
||
function: muteCommand,
|
||
},
|
||
unmute: {
|
||
aliases: ['um'],
|
||
roles: Role.ADMIN_TEMP,
|
||
desc: `
|
||
This command allows to unmute someone.
|
||
It takes 1 argument:
|
||
Argument 1: #<id> where <id> is the id of the muted player.
|
||
OR
|
||
Argument 1: <number> where <number> is the number associated with the mute given by the 'muteList' command.
|
||
Example: !unmute #300 will unmute the player with id 300,
|
||
!unmute 8 will unmute the n°8 player according to the 'muteList' command.`,
|
||
function: unmuteCommand,
|
||
},
|
||
mutes: {
|
||
aliases: [],
|
||
roles: Role.ADMIN_TEMP,
|
||
desc: `
|
||
This command shows the list of muted players.`,
|
||
function: muteListCommand,
|
||
},
|
||
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 'admins' command.
|
||
Example: !removeadmin #300 will remove admin to the player with id 300,
|
||
!removeadmin 2 will remove the admin n°2 according to the 'admins' 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.
|
||
|
||
To remove the room password, simply enter '!password'.`,
|
||
function: passwordCommand,
|
||
},
|
||
};
|
||
|
||
/* GAME */
|
||
|
||
var lastTouches = Array(2).fill(null);
|
||
var lastTeamTouched;
|
||
|
||
var speedCoefficient = 100 / (5 * (0.99 ** 60 + 1));
|
||
var ballSpeed = 0;
|
||
var playerRadius = 15;
|
||
var ballRadius = 10;
|
||
var triggerDistance = playerRadius + ballRadius + 0.01;
|
||
|
||
/* COLORS */
|
||
|
||
var welcomeColor = 0xc4ff65;
|
||
var announcementColor = 0xffefd6;
|
||
var infoColor = 0xbebebe;
|
||
var privateMessageColor = 0xffc933;
|
||
var redColor = 0xff4c4c;
|
||
var blueColor = 0x62cbff;
|
||
var warningColor = 0xffa135;
|
||
var errorColor = 0xa40000;
|
||
var successColor = 0x75ff75;
|
||
var defaultColor = null;
|
||
|
||
/* AUXILIARY */
|
||
|
||
var checkTimeVariable = false;
|
||
var checkStadiumVariable = true;
|
||
var endGameVariable = false;
|
||
var cancelGameVariable = false;
|
||
var kickFetchVariable = false;
|
||
|
||
var chooseMode = false;
|
||
var timeOutCap;
|
||
var capLeft = false;
|
||
var redCaptainChoice = '';
|
||
var blueCaptainChoice = '';
|
||
var chooseTime = 20;
|
||
|
||
var AFKSet = new Set();
|
||
var AFKMinSet = new Set();
|
||
var AFKCooldownSet = new Set();
|
||
var minAFKDuration = 0;
|
||
var maxAFKDuration = 30;
|
||
var AFKCooldown = 0;
|
||
|
||
var muteArray = new MuteList();
|
||
var muteDuration = 5;
|
||
|
||
var removingPlayers = false;
|
||
var insertingPlayers = false;
|
||
|
||
var stopTimeout;
|
||
var startTimeout;
|
||
var unpauseTimeout;
|
||
var removingTimeout;
|
||
var insertingTimeout;
|
||
|
||
var emptyPlayer = {
|
||
id: 0,
|
||
};
|
||
stadiumCommand(emptyPlayer, "!training");
|
||
|
||
var game = new Game();
|
||
|
||
/* FUNCTIONS */
|
||
|
||
/* AUXILIARY FUNCTIONS */
|
||
|
||
if (typeof String.prototype.replaceAll != 'function') {
|
||
String.prototype.replaceAll = function (search, replacement) {
|
||
var target = this;
|
||
return target.split(search).join(replacement);
|
||
};
|
||
}
|
||
|
||
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));
|
||
}
|
||
|
||
function pointDistance(p1, p2) {
|
||
return Math.sqrt(Math.pow(p1.x - p2.x, 2) + Math.pow(p1.y - p2.y, 2));
|
||
}
|
||
|
||
/* TIME FUNCTIONS */
|
||
|
||
function getHoursStats(time) {
|
||
return Math.floor(time / 3600);
|
||
}
|
||
|
||
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 getMinutesStats(time) {
|
||
return Math.floor(time / 60) - getHoursStats(time) * 60;
|
||
}
|
||
|
||
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 - getMinutesReport(t) * 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 getTimeStats(time) {
|
||
if (getHoursStats(time) > 0) {
|
||
return `${getHoursStats(time)}h${getMinutesStats(time)}m`;
|
||
} else {
|
||
return `${getMinutesStats(time)}m`;
|
||
}
|
||
}
|
||
|
||
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, includeAFK = true) {
|
||
if (team == Team.RED) return teamRed;
|
||
if (team == Team.BLUE) return teamBlue;
|
||
if (includeAFK) {
|
||
return playersAll.filter((p) => p.team === Team.SPECTATORS);
|
||
}
|
||
return teamSpec;
|
||
}
|
||
|
||
function sendAnnouncementTeam(message, team, color, style, mention) {
|
||
for (let player of team) {
|
||
room.sendAnnouncement(message, player.id, color, style, mention);
|
||
}
|
||
}
|
||
|
||
function teamChat(player, message) {
|
||
var msgArray = message.split(/ +/).slice(1);
|
||
var emoji = player.team == Team.RED ? '🔴' : player.team == Team.BLUE ? '🔵' : '⚪';
|
||
var message = `${emoji} [TEAM] ${player.name}: ${msgArray.join(' ')}`;
|
||
var team = getTeamArray(player.team, true);
|
||
var color = player.team == Team.RED ? redColor : player.team == Team.BLUE ? blueColor : null;
|
||
var style = 'bold';
|
||
var mention = HaxNotification.CHAT;
|
||
sendAnnouncementTeam(message, team, color, style, mention);
|
||
}
|
||
|
||
function playerChat(player, message) {
|
||
var msgArray = message.split(/ +/);
|
||
var playerTargetIndex = playersAll.findIndex(
|
||
(p) => p.name.replaceAll(' ', '_') == msgArray[0].substring(2)
|
||
);
|
||
if (playerTargetIndex == -1) {
|
||
room.sendAnnouncement(
|
||
`Invalid player, make sure the name you entered is correct.`,
|
||
player.id,
|
||
errorColor,
|
||
'bold',
|
||
null
|
||
);
|
||
return false;
|
||
}
|
||
var playerTarget = playersAll[playerTargetIndex];
|
||
if (player.id == playerTarget.id) {
|
||
room.sendAnnouncement(
|
||
`You can't send a PM to yourself!`,
|
||
player.id,
|
||
errorColor,
|
||
'bold',
|
||
null
|
||
);
|
||
return false;
|
||
}
|
||
var messageFrom = `📝 [PM with ${playerTarget.name}] ${player.name}: ${msgArray.slice(1).join(' ')}`
|
||
|
||
var messageTo = `📝 [PM with ${player.name}] ${player.name}: ${msgArray.slice(1).join(' ')}`
|
||
|
||
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);
|
||
}
|
||
}
|
||
|
||
function checkGoalKickTouch(array, index, goal) {
|
||
if (array != null && array.length >= index + 1) {
|
||
var obj = array[index];
|
||
if (obj != null && obj.goal != null && obj.goal == goal) return obj;
|
||
}
|
||
return null;
|
||
}
|
||
|
||
/* BUTTONS */
|
||
|
||
function topButton() {
|
||
if (teamSpec.length > 0) {
|
||
if (teamRed.length == teamBlue.length && teamSpec.length > 1) {
|
||
room.setPlayerTeam(teamSpec[0].id, Team.RED);
|
||
room.setPlayerTeam(teamSpec[1].id, Team.BLUE);
|
||
} else if (teamRed.length < teamBlue.length)
|
||
room.setPlayerTeam(teamSpec[0].id, Team.RED);
|
||
else room.setPlayerTeam(teamSpec[0].id, Team.BLUE);
|
||
}
|
||
}
|
||
|
||
function randomButton() {
|
||
if (teamSpec.length > 0) {
|
||
if (teamRed.length == teamBlue.length && teamSpec.length > 1) {
|
||
var r = getRandomInt(teamSpec.length);
|
||
room.setPlayerTeam(teamSpec[r].id, Team.RED);
|
||
teamSpec = teamSpec.filter((spec) => spec.id != teamSpec[r].id);
|
||
room.setPlayerTeam(teamSpec[getRandomInt(teamSpec.length)].id, Team.BLUE);
|
||
} else if (teamRed.length < teamBlue.length)
|
||
room.setPlayerTeam(teamSpec[getRandomInt(teamSpec.length)].id, Team.RED);
|
||
else
|
||
room.setPlayerTeam(teamSpec[getRandomInt(teamSpec.length)].id, Team.BLUE);
|
||
}
|
||
}
|
||
|
||
function blueToSpecButton() {
|
||
clearTimeout(removingTimeout);
|
||
removingPlayers = true;
|
||
removingTimeout = setTimeout(() => {
|
||
removingPlayers = false;
|
||
}, 100);
|
||
for (var i = 0; i < teamBlue.length; i++) {
|
||
room.setPlayerTeam(teamBlue[teamBlue.length - 1 - i].id, Team.SPECTATORS);
|
||
}
|
||
}
|
||
|
||
function redToSpecButton() {
|
||
clearTimeout(removingTimeout);
|
||
removingPlayers = true;
|
||
removingTimeout = setTimeout(() => {
|
||
removingPlayers = false;
|
||
}, 100);
|
||
for (var i = 0; i < teamRed.length; i++) {
|
||
room.setPlayerTeam(teamRed[teamRed.length - 1 - i].id, Team.SPECTATORS);
|
||
}
|
||
}
|
||
|
||
function resetButton() {
|
||
clearTimeout(removingTimeout);
|
||
removingPlayers = true;
|
||
removingTimeout = setTimeout(() => {
|
||
removingPlayers = false;
|
||
}, 100);
|
||
for (let i = 0; i < Math.max(teamRed.length, teamBlue.length); i++) {
|
||
if (Math.max(teamRed.length, teamBlue.length) - teamRed.length - i > 0)
|
||
room.setPlayerTeam(teamBlue[teamBlue.length - 1 - i].id, Team.SPECTATORS);
|
||
else if (Math.max(teamRed.length, teamBlue.length) - teamBlue.length - i > 0)
|
||
room.setPlayerTeam(teamRed[teamRed.length - 1 - i].id, Team.SPECTATORS);
|
||
else break;
|
||
}
|
||
for (let i = 0; i < Math.min(teamRed.length, teamBlue.length); i++) {
|
||
room.setPlayerTeam(
|
||
teamBlue[Math.min(teamRed.length, teamBlue.length) - 1 - i].id,
|
||
Team.SPECTATORS
|
||
);
|
||
room.setPlayerTeam(
|
||
teamRed[Math.min(teamRed.length, teamBlue.length) - 1 - i].id,
|
||
Team.SPECTATORS
|
||
);
|
||
}
|
||
}
|
||
|
||
function swapButton() {
|
||
clearTimeout(removingTimeout);
|
||
removingPlayers = true;
|
||
removingTimeout = setTimeout(() => {
|
||
removingPlayers = false;
|
||
}, 100);
|
||
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 */
|
||
|
||
function leaveCommand(player, message) {
|
||
room.kickPlayer(player.id, 'Bye !', false);
|
||
}
|
||
|
||
function helpCommand(player, message) {
|
||
var msgArray = message.split(/ +/).slice(1);
|
||
if (msgArray.length == 0) {
|
||
var commandString = 'Player commands :';
|
||
for (const [key, value] of Object.entries(commands)) {
|
||
if (value.desc && value.roles == Role.PLAYER) commandString += ` !${key},`;
|
||
}
|
||
commandString = commandString.substring(0, commandString.length - 1) + '.\n';
|
||
if (getRole(player) >= Role.ADMIN_TEMP) {
|
||
commandString += `Admin commands :`;
|
||
for (const [key, value] of Object.entries(commands)) {
|
||
if (value.desc && value.roles == Role.ADMIN_TEMP) commandString += ` !${key},`;
|
||
}
|
||
if (commandString.slice(commandString.length - 1) == ':')
|
||
commandString += ` None,`;
|
||
commandString = commandString.substring(0, commandString.length - 1) + '.\n';
|
||
}
|
||
if (getRole(player) >= Role.MASTER) {
|
||
commandString += `Master commands :`;
|
||
for (const [key, value] of Object.entries(commands)) {
|
||
if (value.desc && value.roles == Role.MASTER) commandString += ` !${key},`;
|
||
}
|
||
if (commandString.slice(commandString.length - 1) == ':') commandString += ` None,`;
|
||
commandString = commandString.substring(0, commandString.length - 1) + '.\n';
|
||
}
|
||
commandString += "\nTo get information on a specific command, type ''!help <command name>'.";
|
||
room.sendAnnouncement(
|
||
commandString,
|
||
player.id,
|
||
infoColor,
|
||
'bold',
|
||
HaxNotification.CHAT
|
||
);
|
||
} else if (msgArray.length >= 1) {
|
||
var commandName = getCommand(msgArray[0].toLowerCase());
|
||
if (commandName != false && commands[commandName].desc != false)
|
||
room.sendAnnouncement(
|
||
`\'${commandName}\' command :\n${commands[commandName].desc}`,
|
||
player.id,
|
||
infoColor,
|
||
'bold',
|
||
HaxNotification.CHAT
|
||
);
|
||
else
|
||
room.sendAnnouncement(
|
||
`The command you tried to get information on does not exist. To check all available commands, type \'!help\'`,
|
||
player.id,
|
||
errorColor,
|
||
'bold',
|
||
HaxNotification.CHAT
|
||
);
|
||
}
|
||
}
|
||
|
||
function globalStatsCommand(player, message) {
|
||
var stats = new HaxStatistics(player.name);
|
||
if (localStorage.getItem(authArray[player.id][0])) {
|
||
stats = JSON.parse(localStorage.getItem(authArray[player.id][0]));
|
||
}
|
||
var statsString = printPlayerStats(stats);
|
||
room.sendAnnouncement(
|
||
statsString,
|
||
player.id,
|
||
infoColor,
|
||
'bold',
|
||
HaxNotification.CHAT
|
||
);
|
||
}
|
||
|
||
function renameCommand(player, message) {
|
||
var msgArray = message.split(/ +/).slice(1);
|
||
if (localStorage.getItem(authArray[player.id][0])) {
|
||
var stats = JSON.parse(localStorage.getItem(authArray[player.id][0]));
|
||
if (msgArray.length == 0) {
|
||
stats.playerName = player.name;
|
||
} else {
|
||
stats.playerName = msgArray.join(' ');
|
||
}
|
||
localStorage.setItem(authArray[player.id][0], JSON.stringify(stats));
|
||
room.sendAnnouncement(
|
||
`You successfully renamed yourself ${stats.playerName} !`,
|
||
player.id,
|
||
successColor,
|
||
'bold',
|
||
HaxNotification.CHAT
|
||
);
|
||
} else {
|
||
room.sendAnnouncement(
|
||
`You haven't played a game in this room yet !`,
|
||
player.id,
|
||
errorColor,
|
||
'bold',
|
||
HaxNotification.CHAT
|
||
);
|
||
}
|
||
}
|
||
|
||
function statsLeaderboardCommand(player, message) {
|
||
var key = message.split(/ +/)[0].substring(1).toLowerCase();
|
||
printRankings(key, player.id);
|
||
}
|
||
|
||
function afkCommand(player, message) {
|
||
if (player.team == Team.SPECTATORS || players.length == 1) {
|
||
if (AFKSet.has(player.id)) {
|
||
if (AFKMinSet.has(player.id)) {
|
||
room.sendAnnouncement(
|
||
`There is a minimum of ${minAFKDuration} minute of AFK time. Don't abuse the command !`,
|
||
player.id,
|
||
errorColor,
|
||
'bold',
|
||
HaxNotification.CHAT
|
||
);
|
||
} else {
|
||
AFKSet.delete(player.id);
|
||
room.sendAnnouncement(
|
||
`🌅 ${player.name} is not AFK anymore !`,
|
||
null,
|
||
announcementColor,
|
||
'bold',
|
||
null
|
||
);
|
||
updateTeams();
|
||
handlePlayersJoin();
|
||
}
|
||
} else {
|
||
if (AFKCooldownSet.has(player.id)) {
|
||
room.sendAnnouncement(
|
||
`You can only go AFK every ${AFKCooldown} minutes. Don't abuse the command !`,
|
||
player.id,
|
||
errorColor,
|
||
'bold',
|
||
HaxNotification.CHAT
|
||
);
|
||
} else {
|
||
AFKSet.add(player.id);
|
||
if (!player.admin) {
|
||
AFKMinSet.add(player.id);
|
||
AFKCooldownSet.add(player.id);
|
||
setTimeout(
|
||
(id) => {
|
||
AFKMinSet.delete(id);
|
||
},
|
||
minAFKDuration * 60 * 1000,
|
||
player.id
|
||
);
|
||
setTimeout(
|
||
(id) => {
|
||
AFKSet.delete(id);
|
||
},
|
||
maxAFKDuration * 60 * 1000,
|
||
player.id
|
||
);
|
||
setTimeout(
|
||
(id) => {
|
||
AFKCooldownSet.delete(id);
|
||
},
|
||
AFKCooldown * 60 * 1000,
|
||
player.id
|
||
);
|
||
}
|
||
room.setPlayerTeam(player.id, Team.SPECTATORS);
|
||
room.sendAnnouncement(
|
||
`😴 ${player.name} is now AFK !`,
|
||
null,
|
||
announcementColor,
|
||
'bold',
|
||
null
|
||
);
|
||
updateTeams();
|
||
handlePlayersLeave();
|
||
}
|
||
}
|
||
} else {
|
||
room.sendAnnouncement(
|
||
`You can't go AFK while in a team !`,
|
||
player.id,
|
||
errorColor,
|
||
'bold',
|
||
HaxNotification.CHAT
|
||
);
|
||
}
|
||
}
|
||
|
||
function afkListCommand(player, message) {
|
||
if (AFKSet.size == 0) {
|
||
room.sendAnnouncement(
|
||
"😴 There's nobody in the AFK list.",
|
||
player.id,
|
||
announcementColor,
|
||
'bold',
|
||
null
|
||
);
|
||
return;
|
||
}
|
||
var cstm = '😴 AFK list : ';
|
||
AFKSet.forEach((_, value) => {
|
||
var p = room.getPlayer(value);
|
||
if (p != null) cstm += p.name + `, `;
|
||
});
|
||
cstm = cstm.substring(0, cstm.length - 2) + '.';
|
||
room.sendAnnouncement(cstm, player.id, announcementColor, 'bold', null);
|
||
}
|
||
|
||
function masterCommand(player, message) {
|
||
var msgArray = message.split(/ +/).slice(1);
|
||
if (parseInt(msgArray[0]) == masterPassword) {
|
||
if (!masterList.includes(authArray[player.id][0])) {
|
||
room.setPlayerAdmin(player.id, true);
|
||
adminList = adminList.filter((a) => a[0] != authArray[player.id][0]);
|
||
masterList.push(authArray[player.id][0]);
|
||
room.sendAnnouncement(
|
||
`${player.name} is now a room master !`,
|
||
null,
|
||
announcementColor,
|
||
'bold',
|
||
HaxNotification.CHAT
|
||
);
|
||
} else {
|
||
room.sendAnnouncement(
|
||
`You are a master already !`,
|
||
player.id,
|
||
errorColor,
|
||
'bold',
|
||
HaxNotification.CHAT
|
||
);
|
||
}
|
||
}
|
||
}
|
||
|
||
/* ADMIN COMMANDS */
|
||
|
||
function restartCommand(player, message) {
|
||
instantRestart();
|
||
}
|
||
|
||
function restartSwapCommand(player, message) {
|
||
room.stopGame();
|
||
swapButton();
|
||
startTimeout = setTimeout(() => {
|
||
room.startGame();
|
||
}, 10);
|
||
}
|
||
|
||
function swapCommand(player, message) {
|
||
if (playSituation == Situation.STOP) {
|
||
swapButton();
|
||
room.sendAnnouncement(
|
||
'✔️ Teams swapped !',
|
||
null,
|
||
announcementColor,
|
||
'bold',
|
||
null
|
||
);
|
||
} else {
|
||
room.sendAnnouncement(
|
||
`Please stop the game before swapping.`,
|
||
player.id,
|
||
errorColor,
|
||
'bold',
|
||
HaxNotification.CHAT
|
||
);
|
||
}
|
||
}
|
||
|
||
function kickTeamCommand(player, message) {
|
||
var msgArray = message.split(/ +/);
|
||
var reasonString = `Team kick by ${player.name}`;
|
||
if (msgArray.length > 1) {
|
||
reasonString = msgArray.slice(1).join(' ');
|
||
}
|
||
if (['!kickred', '!kickr'].includes(msgArray[0].toLowerCase())) {
|
||
for (let i = 0; i < teamRed.length; i++) {
|
||
setTimeout(() => {
|
||
room.kickPlayer(teamRed[0].id, reasonString, false);
|
||
}, i * 20)
|
||
}
|
||
} else if (['!kickblue', '!kickb'].includes(msgArray[0].toLowerCase())) {
|
||
for (let i = 0; i < teamBlue.length; i++) {
|
||
setTimeout(() => {
|
||
room.kickPlayer(teamBlue[0].id, reasonString, false);
|
||
}, i * 20)
|
||
}
|
||
} else if (['!kickspec', '!kicks'].includes(msgArray[0].toLowerCase())) {
|
||
for (let i = 0; i < teamSpec.length; i++) {
|
||
setTimeout(() => {
|
||
room.kickPlayer(teamSpec[0].id, reasonString, false);
|
||
}, i * 20)
|
||
}
|
||
}
|
||
}
|
||
|
||
function stadiumCommand(player, message) {
|
||
var msgArray = message.split(/ +/);
|
||
if (gameState == State.STOP) {
|
||
if (['!classic'].includes(msgArray[0].toLowerCase())) {
|
||
if (JSON.parse(classicMap).name == 'Classic') {
|
||
room.setDefaultStadium('Classic');
|
||
} else {
|
||
room.setCustomStadium(classicMap);
|
||
}
|
||
currentStadium = 'classic';
|
||
} else if (['!big'].includes(msgArray[0].toLowerCase())) {
|
||
if (JSON.parse(bigMap).name == 'Big') {
|
||
room.setDefaultStadium('Big');
|
||
} else {
|
||
room.setCustomStadium(bigMap);
|
||
}
|
||
currentStadium = 'big';
|
||
} else if (['!training'].includes(msgArray[0].toLowerCase())) {
|
||
room.setCustomStadium(trainingMap);
|
||
currentStadium = 'training';
|
||
} else {
|
||
room.sendAnnouncement(
|
||
`Stadium not recognized.`,
|
||
player.id,
|
||
errorColor,
|
||
'bold',
|
||
HaxNotification.CHAT
|
||
);
|
||
}
|
||
} else {
|
||
room.sendAnnouncement(
|
||
`Please stop the game before using this command.`,
|
||
player.id,
|
||
errorColor,
|
||
'bold',
|
||
HaxNotification.CHAT
|
||
);
|
||
}
|
||
}
|
||
|
||
function muteCommand(player, message) {
|
||
var msgArray = message.split(/ +/).slice(1);
|
||
if (msgArray.length > 0) {
|
||
if (msgArray[0].length > 0 && msgArray[0][0] == '#') {
|
||
msgArray[0] = msgArray[0].substring(1, msgArray[0].length);
|
||
if (room.getPlayer(parseInt(msgArray[0])) != null) {
|
||
var playerMute = room.getPlayer(parseInt(msgArray[0]));
|
||
var minutesMute = muteDuration;
|
||
if (msgArray.length > 1 && parseInt(msgArray[1]) > 0) {
|
||
minutesMute = parseInt(msgArray[1]);
|
||
}
|
||
if (!playerMute.admin) {
|
||
var muteObj = new MutePlayer(playerMute.name, playerMute.id, authArray[playerMute.id][0]);
|
||
muteObj.setDuration(minutesMute);
|
||
room.sendAnnouncement(
|
||
`${playerMute.name} has been muted for ${minutesMute} minutes.`,
|
||
null,
|
||
announcementColor,
|
||
'bold',
|
||
null
|
||
);
|
||
} else {
|
||
room.sendAnnouncement(
|
||
`You can't mute an admin.`,
|
||
player.id,
|
||
errorColor,
|
||
'bold',
|
||
HaxNotification.CHAT
|
||
);
|
||
}
|
||
} else {
|
||
room.sendAnnouncement(
|
||
`There is no player with such ID in the room. Enter "!help mute" for more information.`,
|
||
player.id,
|
||
errorColor,
|
||
'bold',
|
||
HaxNotification.CHAT
|
||
);
|
||
}
|
||
} else {
|
||
room.sendAnnouncement(
|
||
`Incorrect format for your argument. Enter "!help mute" for more information.`,
|
||
player.id,
|
||
errorColor,
|
||
'bold',
|
||
HaxNotification.CHAT
|
||
);
|
||
}
|
||
} else {
|
||
room.sendAnnouncement(
|
||
`Wrong number of arguments. Enter "!help mute" for more information.`,
|
||
player.id,
|
||
errorColor,
|
||
'bold',
|
||
HaxNotification.CHAT
|
||
);
|
||
}
|
||
}
|
||
|
||
function unmuteCommand(player, message) {
|
||
var msgArray = message.split(/ +/).slice(1);
|
||
if (msgArray.length > 0) {
|
||
if (msgArray[0].length > 0 && msgArray[0][0] == '#') {
|
||
msgArray[0] = msgArray[0].substring(1, msgArray[0].length);
|
||
if (room.getPlayer(parseInt(msgArray[0])) != null) {
|
||
var playerUnmute = room.getPlayer(parseInt(msgArray[0]));
|
||
if (muteArray.getByPlayerId(playerUnmute.id) != null) {
|
||
var muteObj = muteArray.getByPlayerId(playerUnmute.id);
|
||
muteObj.remove()
|
||
room.sendAnnouncement(
|
||
`${playerUnmute.name} has been unmuted !`,
|
||
null,
|
||
announcementColor,
|
||
'bold',
|
||
HaxNotification.CHAT
|
||
);
|
||
} else {
|
||
room.sendAnnouncement(
|
||
`This player isn't muted !`,
|
||
player.id,
|
||
errorColor,
|
||
'bold',
|
||
HaxNotification.CHAT
|
||
);
|
||
}
|
||
} else {
|
||
room.sendAnnouncement(
|
||
`There is no player with such ID in the room. Enter "!help unmute" for more information.`,
|
||
player.id,
|
||
errorColor,
|
||
'bold',
|
||
HaxNotification.CHAT
|
||
);
|
||
}
|
||
} else if (msgArray[0].length > 0 && parseInt(msgArray[0]) > 0 && muteArray.getById(parseInt(msgArray[0])) != null) {
|
||
var playerUnmute = muteArray.getById(parseInt(msgArray[0]));
|
||
playerUnmute.remove();
|
||
room.sendAnnouncement(
|
||
`${playerUnmute.name} has been unmuted !`,
|
||
null,
|
||
announcementColor,
|
||
'bold',
|
||
HaxNotification.CHAT
|
||
);
|
||
} else {
|
||
room.sendAnnouncement(
|
||
`Incorrect format for your argument. Enter "!help unmute" for more information.`,
|
||
player.id,
|
||
errorColor,
|
||
'bold',
|
||
HaxNotification.CHAT
|
||
);
|
||
}
|
||
} else {
|
||
room.sendAnnouncement(
|
||
`Wrong number of arguments. Enter "!help unmute" for more information.`,
|
||
player.id,
|
||
errorColor,
|
||
'bold',
|
||
HaxNotification.CHAT
|
||
);
|
||
}
|
||
}
|
||
|
||
function muteListCommand(player, message) {
|
||
if (muteArray.list.length == 0) {
|
||
room.sendAnnouncement(
|
||
"🔇 There's nobody in the mute list.",
|
||
player.id,
|
||
announcementColor,
|
||
'bold',
|
||
null
|
||
);
|
||
return false;
|
||
}
|
||
var cstm = '🔇 Mute list : ';
|
||
for (let mute of muteArray.list) {
|
||
cstm += mute.name + `[${mute.id}], `;
|
||
}
|
||
cstm = cstm.substring(0, cstm.length - 2) + '.';
|
||
room.sendAnnouncement(
|
||
cstm,
|
||
player.id,
|
||
announcementColor,
|
||
'bold',
|
||
null
|
||
);
|
||
}
|
||
|
||
/* MASTER COMMANDS */
|
||
|
||
function clearbansCommand(player, message) {
|
||
var msgArray = message.split(/ +/).slice(1);
|
||
if (msgArray.length == 0) {
|
||
room.clearBans();
|
||
room.sendAnnouncement(
|
||
'✔️ Bans cleared !',
|
||
null,
|
||
announcementColor,
|
||
'bold',
|
||
null
|
||
);
|
||
banList = [];
|
||
} else if (msgArray.length == 1) {
|
||
if (parseInt(msgArray[0]) > 0) {
|
||
var ID = parseInt(msgArray[0]);
|
||
room.clearBan(ID);
|
||
if (banList.length != banList.filter((p) => p[1] != ID).length) {
|
||
room.sendAnnouncement(
|
||
`✔️ ${banList.filter((p) => p[1] == ID)[0][0]} has been unbanned from the room !`,
|
||
null,
|
||
announcementColor,
|
||
'bold',
|
||
null
|
||
);
|
||
} else {
|
||
room.sendAnnouncement(
|
||
`The ID you entered doesn't have a ban associated to. Enter "!help clearbans" for more information.`,
|
||
player.id,
|
||
errorColor,
|
||
'bold',
|
||
HaxNotification.CHAT
|
||
);
|
||
}
|
||
banList = banList.filter((p) => p[1] != ID);
|
||
} else {
|
||
room.sendAnnouncement(
|
||
`Invalid ID entered. Enter "!help clearbans" for more information.`,
|
||
player.id,
|
||
errorColor,
|
||
'bold',
|
||
HaxNotification.CHAT
|
||
);
|
||
}
|
||
} else {
|
||
room.sendAnnouncement(
|
||
`Wrong number of arguments. Enter "!help clearbans" for more information.`,
|
||
player.id,
|
||
errorColor,
|
||
'bold',
|
||
HaxNotification.CHAT
|
||
);
|
||
}
|
||
}
|
||
|
||
function banListCommand(player, message) {
|
||
if (banList.length == 0) {
|
||
room.sendAnnouncement(
|
||
"📢 There's nobody in the ban list.",
|
||
player.id,
|
||
announcementColor,
|
||
'bold',
|
||
null
|
||
);
|
||
return false;
|
||
}
|
||
var cstm = '📢 Ban list : ';
|
||
for (let ban of banList) {
|
||
cstm += ban[0] + `[${ban[1]}], `;
|
||
}
|
||
cstm = cstm.substring(0, cstm.length - 2) + '.';
|
||
room.sendAnnouncement(
|
||
cstm,
|
||
player.id,
|
||
announcementColor,
|
||
'bold',
|
||
null
|
||
);
|
||
}
|
||
|
||
function adminListCommand(player, message) {
|
||
if (adminList.length == 0) {
|
||
room.sendAnnouncement(
|
||
"📢 There's nobody in the admin list.",
|
||
player.id,
|
||
announcementColor,
|
||
'bold',
|
||
null
|
||
);
|
||
return false;
|
||
}
|
||
var cstm = '📢 Admin list : ';
|
||
for (let i = 0; i < adminList.length; i++) {
|
||
cstm += adminList[i][1] + `[${i}], `;
|
||
}
|
||
cstm = cstm.substring(0, cstm.length - 2) + '.';
|
||
room.sendAnnouncement(
|
||
cstm,
|
||
player.id,
|
||
announcementColor,
|
||
'bold',
|
||
null
|
||
);
|
||
}
|
||
|
||
function setAdminCommand(player, message) {
|
||
var msgArray = message.split(/ +/).slice(1);
|
||
if (msgArray.length > 0) {
|
||
if (msgArray[0].length > 0 && msgArray[0][0] == '#') {
|
||
msgArray[0] = msgArray[0].substring(1, msgArray[0].length);
|
||
if (room.getPlayer(parseInt(msgArray[0])) != null) {
|
||
var playerAdmin = room.getPlayer(parseInt(msgArray[0]));
|
||
|
||
if (!adminList.map((a) => a[0]).includes(authArray[playerAdmin.id][0])) {
|
||
if (!masterList.includes(authArray[playerAdmin.id][0])) {
|
||
room.setPlayerAdmin(playerAdmin.id, true);
|
||
adminList.push([authArray[playerAdmin.id][0], playerAdmin.name]);
|
||
room.sendAnnouncement(
|
||
`${playerAdmin.name} is now a room admin !`,
|
||
null,
|
||
announcementColor,
|
||
'bold',
|
||
HaxNotification.CHAT
|
||
);
|
||
} else {
|
||
room.sendAnnouncement(
|
||
`This player is a master already !`,
|
||
player.id,
|
||
errorColor,
|
||
'bold',
|
||
HaxNotification.CHAT
|
||
);
|
||
}
|
||
} else {
|
||
room.sendAnnouncement(
|
||
`This player is a permanent admin already !`,
|
||
player.id,
|
||
errorColor,
|
||
'bold',
|
||
HaxNotification.CHAT
|
||
);
|
||
}
|
||
} else {
|
||
room.sendAnnouncement(
|
||
`There is no player with such ID in the room. Enter "!help setadmin" for more information.`,
|
||
player.id,
|
||
errorColor,
|
||
'bold',
|
||
HaxNotification.CHAT
|
||
);
|
||
}
|
||
} else {
|
||
room.sendAnnouncement(
|
||
`Incorrect format for your argument. Enter "!help setadmin" for more information.`,
|
||
player.id,
|
||
errorColor,
|
||
'bold',
|
||
HaxNotification.CHAT
|
||
);
|
||
}
|
||
} else {
|
||
room.sendAnnouncement(
|
||
`Wrong number of arguments. Enter "!help setadmin" for more information.`,
|
||
player.id,
|
||
errorColor,
|
||
'bold',
|
||
HaxNotification.CHAT
|
||
);
|
||
}
|
||
}
|
||
|
||
function removeAdminCommand(player, message) {
|
||
var msgArray = message.split(/ +/).slice(1);
|
||
if (msgArray.length > 0) {
|
||
if (msgArray[0].length > 0 && msgArray[0][0] == '#') {
|
||
msgArray[0] = msgArray[0].substring(1, msgArray[0].length);
|
||
if (room.getPlayer(parseInt(msgArray[0])) != null) {
|
||
var playerAdmin = room.getPlayer(parseInt(msgArray[0]));
|
||
|
||
if (adminList.map((a) => a[0]).includes(authArray[playerAdmin.id][0])) {
|
||
room.setPlayerAdmin(playerAdmin.id, false);
|
||
adminList = adminList.filter((a) => a[0] != authArray[playerAdmin.id][0]);
|
||
room.sendAnnouncement(
|
||
`${playerAdmin.name} is not a room admin anymore !`,
|
||
null,
|
||
announcementColor,
|
||
'bold',
|
||
HaxNotification.CHAT
|
||
);
|
||
} else {
|
||
room.sendAnnouncement(
|
||
`This player isn't a permanent admin !`,
|
||
player.id,
|
||
errorColor,
|
||
'bold',
|
||
HaxNotification.CHAT
|
||
);
|
||
}
|
||
} else {
|
||
room.sendAnnouncement(
|
||
`There is no player with such ID in the room. Enter "!help removeadmin" for more information.`,
|
||
player.id,
|
||
errorColor,
|
||
'bold',
|
||
HaxNotification.CHAT
|
||
);
|
||
}
|
||
} else if (msgArray[0].length > 0 && parseInt(msgArray[0]) < adminList.length) {
|
||
var index = parseInt(msgArray[0]);
|
||
var playerAdmin = adminList[index];
|
||
if (playersAll.findIndex((p) => authArray[p.id][0] == playerAdmin[0]) != -1) {
|
||
// check if there is the removed admin in the room
|
||
var indexRem = playersAll.findIndex((p) => authArray[p.id][0] == playerAdmin[0]);
|
||
room.setPlayerAdmin(playersAll[indexRem].id, false);
|
||
}
|
||
adminList.splice(index);
|
||
room.sendAnnouncement(
|
||
`${playerAdmin[1]} is not a room admin anymore !`,
|
||
null,
|
||
announcementColor,
|
||
'bold',
|
||
HaxNotification.CHAT
|
||
);
|
||
} else {
|
||
room.sendAnnouncement(
|
||
`Incorrect format for your argument. Enter "!help removeadmin" for more information.`,
|
||
player.id,
|
||
errorColor,
|
||
'bold',
|
||
HaxNotification.CHAT
|
||
);
|
||
}
|
||
} else {
|
||
room.sendAnnouncement(
|
||
`Wrong number of arguments. Enter "!help removeadmin" for more information.`,
|
||
player.id,
|
||
errorColor,
|
||
'bold',
|
||
HaxNotification.CHAT
|
||
);
|
||
}
|
||
}
|
||
|
||
function passwordCommand(player, message) {
|
||
var msgArray = message.split(/ +/).slice(1);
|
||
if (msgArray.length > 0) {
|
||
if (msgArray.length == 1 && msgArray[0] == '') {
|
||
roomPassword = '';
|
||
room.setPassword(null);
|
||
room.sendAnnouncement(
|
||
`The room password has been removed.`,
|
||
player.id,
|
||
announcementColor,
|
||
'bold',
|
||
HaxNotification.CHAT
|
||
);
|
||
}
|
||
roomPassword = msgArray.join(' ');
|
||
room.setPassword(roomPassword);
|
||
room.sendAnnouncement(
|
||
`The room password has been set to ${roomPassword}`,
|
||
player.id,
|
||
announcementColor,
|
||
'bold',
|
||
HaxNotification.CHAT
|
||
);
|
||
} else {
|
||
if (roomPassword != '') {
|
||
roomPassword = '';
|
||
room.setPassword(null);
|
||
room.sendAnnouncement(
|
||
`The room password has been removed.`,
|
||
player.id,
|
||
announcementColor,
|
||
'bold',
|
||
HaxNotification.CHAT
|
||
);
|
||
} else {
|
||
room.sendAnnouncement(
|
||
`The room currently does not have a password. Enter "!help password" for more information.`,
|
||
player.id,
|
||
errorColor,
|
||
'bold',
|
||
HaxNotification.CHAT
|
||
);
|
||
}
|
||
}
|
||
}
|
||
|
||
/* GAME FUNCTIONS */
|
||
|
||
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) {
|
||
if (players.length >= 2 * teamSize - 1) activateChooseMode();
|
||
const scores = room.getScores();
|
||
game.scores = scores;
|
||
lastWinner = winner;
|
||
endGameVariable = true;
|
||
if (winner == Team.RED) {
|
||
streak++;
|
||
room.sendAnnouncement(
|
||
`✨ Red Team won ${scores.red} - ${scores.blue} ! Current streak: ${streak}`,
|
||
null,
|
||
redColor,
|
||
'bold',
|
||
HaxNotification.CHAT
|
||
);
|
||
} else if (winner == Team.BLUE) {
|
||
streak = 1;
|
||
room.sendAnnouncement(
|
||
`✨ Blue Team won ${scores.blue} - ${scores.red} ! Current streak: ${streak}`,
|
||
null,
|
||
blueColor,
|
||
'bold',
|
||
HaxNotification.CHAT
|
||
);
|
||
} else {
|
||
streak = 0;
|
||
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
|
||
);
|
||
updateStats();
|
||
}
|
||
|
||
/* CHOOSING FUNCTIONS */
|
||
|
||
function activateChooseMode() {
|
||
chooseMode = true;
|
||
slowMode = chooseModeSlowMode;
|
||
room.sendAnnouncement(
|
||
`🐢 Slow mode changed to choose mode duration of: ${chooseModeSlowMode}s.`,
|
||
null,
|
||
announcementColor,
|
||
'bold',
|
||
HaxNotification.CHAT
|
||
);
|
||
}
|
||
|
||
function deactivateChooseMode() {
|
||
chooseMode = false;
|
||
clearTimeout(timeOutCap);
|
||
if (slowMode != defaultSlowMode) {
|
||
slowMode = defaultSlowMode;
|
||
room.sendAnnouncement(
|
||
`🐢 Slow mode changed to choose mode duration of: ${defaultSlowMode}s.`,
|
||
null,
|
||
announcementColor,
|
||
'bold',
|
||
HaxNotification.CHAT
|
||
);
|
||
}
|
||
redCaptainChoice = '';
|
||
blueCaptainChoice = '';
|
||
}
|
||
|
||
function getSpecList(player) {
|
||
if (player == null) return null;
|
||
var cstm = 'Players : ';
|
||
for (let i = 0; i < teamSpec.length; i++) {
|
||
cstm += teamSpec[i].name + `[${i + 1}], `;
|
||
}
|
||
cstm = cstm.substring(0, cstm.length - 2) + '.';
|
||
room.sendAnnouncement(
|
||
cstm,
|
||
player.id,
|
||
infoColor,
|
||
'bold',
|
||
HaxNotification.CHAT
|
||
);
|
||
}
|
||
|
||
function choosePlayer() {
|
||
clearTimeout(timeOutCap);
|
||
let captain;
|
||
if (teamRed.length <= teamBlue.length && teamRed.length != 0) {
|
||
captain = teamRed[0];
|
||
} else if (teamBlue.length < teamRed.length && teamBlue.length != 0) {
|
||
captain = teamBlue[0];
|
||
}
|
||
if (captain != null) {
|
||
room.sendAnnouncement(
|
||
"To choose a player, enter his number in the list given or use 'top', 'random' or 'bottom'.",
|
||
captain.id,
|
||
infoColor,
|
||
'bold',
|
||
HaxNotification.MENTION
|
||
);
|
||
timeOutCap = setTimeout(
|
||
(player) => {
|
||
room.sendAnnouncement(
|
||
`Hurry up ${player.name}, only ${Number.parseInt(String(chooseTime / 2))} seconds left to choose !`,
|
||
player.id,
|
||
warningColor,
|
||
'bold',
|
||
HaxNotification.MENTION
|
||
);
|
||
timeOutCap = setTimeout(
|
||
(player) => {
|
||
room.kickPlayer(
|
||
player.id,
|
||
"You didn't choose in time !",
|
||
false
|
||
);
|
||
},
|
||
chooseTime * 500,
|
||
captain
|
||
);
|
||
},
|
||
chooseTime * 1000,
|
||
captain
|
||
);
|
||
}
|
||
if (teamRed.length != 0 && teamBlue.length != 0) {
|
||
getSpecList(teamRed.length <= teamBlue.length ? teamRed[0] : teamBlue[0]);
|
||
}
|
||
}
|
||
|
||
function chooseModeFunction(player, message) {
|
||
var msgArray = message.split(/ +/);
|
||
if (player.id == teamRed[0].id || player.id == teamBlue[0].id) {
|
||
if (teamRed.length <= teamBlue.length && player.id == teamRed[0].id) {
|
||
if (['top', 'auto'].includes(msgArray[0].toLowerCase())) {
|
||
room.setPlayerTeam(teamSpec[0].id, Team.RED);
|
||
redCaptainChoice = 'top';
|
||
clearTimeout(timeOutCap);
|
||
room.sendAnnouncement(
|
||
`${player.name} chose Top !`,
|
||
null,
|
||
announcementColor,
|
||
'bold',
|
||
HaxNotification.CHAT
|
||
);
|
||
} else if (['random', 'rand'].includes(msgArray[0].toLowerCase())) {
|
||
var r = getRandomInt(teamSpec.length);
|
||
room.setPlayerTeam(teamSpec[r].id, Team.RED);
|
||
redCaptainChoice = 'random';
|
||
clearTimeout(timeOutCap);
|
||
room.sendAnnouncement(
|
||
`${player.name} chose Random !`,
|
||
null,
|
||
announcementColor,
|
||
'bold',
|
||
HaxNotification.CHAT
|
||
);
|
||
} else if (['bottom', 'bot'].includes(msgArray[0].toLowerCase())) {
|
||
room.setPlayerTeam(teamSpec[teamSpec.length - 1].id, Team.RED);
|
||
redCaptainChoice = 'bottom';
|
||
clearTimeout(timeOutCap);
|
||
room.sendAnnouncement(
|
||
`${player.name} chose Bottom !`,
|
||
null,
|
||
announcementColor,
|
||
'bold',
|
||
HaxNotification.CHAT
|
||
);
|
||
} else if (!Number.isNaN(Number.parseInt(msgArray[0]))) {
|
||
if (Number.parseInt(msgArray[0]) > teamSpec.length || Number.parseInt(msgArray[0]) < 1) {
|
||
room.sendAnnouncement(
|
||
`Your number is invalid !`,
|
||
player.id,
|
||
errorColor,
|
||
'bold',
|
||
HaxNotification.CHAT
|
||
);
|
||
} else {
|
||
room.setPlayerTeam(
|
||
teamSpec[Number.parseInt(msgArray[0]) - 1].id,
|
||
Team.RED
|
||
);
|
||
room.sendAnnouncement(
|
||
`${player.name} chose ${teamSpec[Number.parseInt(msgArray[0]) - 1].name} !`,
|
||
null,
|
||
announcementColor,
|
||
'bold',
|
||
HaxNotification.CHAT
|
||
);
|
||
}
|
||
} else return false;
|
||
return true;
|
||
}
|
||
if (teamRed.length > teamBlue.length && player.id == teamBlue[0].id) {
|
||
if (['top', 'auto'].includes(msgArray[0].toLowerCase())) {
|
||
room.setPlayerTeam(teamSpec[0].id, Team.BLUE);
|
||
blueCaptainChoice = 'top';
|
||
clearTimeout(timeOutCap);
|
||
room.sendAnnouncement(
|
||
`${player.name} chose Top !`,
|
||
null,
|
||
announcementColor,
|
||
'bold',
|
||
HaxNotification.CHAT
|
||
);
|
||
} else if (['random', 'rand'].includes(msgArray[0].toLowerCase())) {
|
||
room.setPlayerTeam(
|
||
teamSpec[getRandomInt(teamSpec.length)].id,
|
||
Team.BLUE
|
||
);
|
||
blueCaptainChoice = 'random';
|
||
clearTimeout(timeOutCap);
|
||
room.sendAnnouncement(
|
||
`${player.name} chose Random !`,
|
||
null,
|
||
announcementColor,
|
||
'bold',
|
||
HaxNotification.CHAT
|
||
);
|
||
} else if (['bottom', 'bot'].includes(msgArray[0].toLowerCase())) {
|
||
room.setPlayerTeam(teamSpec[teamSpec.length - 1].id, Team.BLUE);
|
||
blueCaptainChoice = 'bottom';
|
||
clearTimeout(timeOutCap);
|
||
room.sendAnnouncement(
|
||
`${player.name} chose Bottom !`,
|
||
null,
|
||
announcementColor,
|
||
'bold',
|
||
HaxNotification.CHAT
|
||
);
|
||
} else if (!Number.isNaN(Number.parseInt(msgArray[0]))) {
|
||
if (Number.parseInt(msgArray[0]) > teamSpec.length || Number.parseInt(msgArray[0]) < 1) {
|
||
room.sendAnnouncement(
|
||
`Your number is invalid !`,
|
||
player.id,
|
||
errorColor,
|
||
'bold',
|
||
HaxNotification.CHAT
|
||
);
|
||
} else {
|
||
room.setPlayerTeam(
|
||
teamSpec[Number.parseInt(msgArray[0]) - 1].id,
|
||
Team.BLUE
|
||
);
|
||
room.sendAnnouncement(
|
||
`${player.name} chose ${teamSpec[Number.parseInt(msgArray[0]) - 1].name} !`,
|
||
null,
|
||
announcementColor,
|
||
'bold',
|
||
HaxNotification.CHAT
|
||
);
|
||
}
|
||
} else return false;
|
||
return true;
|
||
}
|
||
}
|
||
}
|
||
|
||
function checkCaptainLeave(player) {
|
||
if (
|
||
(teamRed.findIndex((red) => red.id == player.id) == 0 && chooseMode && teamRed.length <= teamBlue.length) ||
|
||
(teamBlue.findIndex((blue) => blue.id == player.id) == 0 && chooseMode && teamBlue.length < teamRed.length)
|
||
) {
|
||
choosePlayer();
|
||
capLeft = true;
|
||
setTimeout(() => {
|
||
capLeft = false;
|
||
}, 10);
|
||
}
|
||
}
|
||
|
||
function slowModeFunction(player, message) {
|
||
if (!player.admin) {
|
||
if (!SMSet.has(player.id)) {
|
||
SMSet.add(player.id);
|
||
setTimeout(
|
||
(number) => {
|
||
SMSet.delete(number);
|
||
},
|
||
slowMode * 1000,
|
||
player.id
|
||
);
|
||
} else {
|
||
return true;
|
||
}
|
||
}
|
||
return false;
|
||
}
|
||
|
||
/* PLAYER FUNCTIONS */
|
||
|
||
function updateTeams() {
|
||
playersAll = room.getPlayerList();
|
||
players = playersAll.filter((p) => !AFKSet.has(p.id));
|
||
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
|
||
);
|
||
}
|
||
|
||
function ghostKickHandle(oldP, newP) {
|
||
var teamArrayId = getTeamArray(oldP.team, true).map((p) => p.id);
|
||
teamArrayId.splice(teamArrayId.findIndex((id) => id == oldP.id), 1, newP.id);
|
||
|
||
room.kickPlayer(oldP.id, 'Ghost kick', false);
|
||
room.setPlayerTeam(newP.id, oldP.team);
|
||
room.setPlayerAdmin(newP.id, oldP.admin);
|
||
room.reorderPlayers(teamArrayId, true);
|
||
|
||
if (oldP.team != Team.SPECTATORS && playSituation != Situation.STOP) {
|
||
var discProp = room.getPlayerDiscProperties(oldP.id);
|
||
room.setPlayerDiscProperties(newP.id, discProp);
|
||
}
|
||
}
|
||
|
||
/* ACTIVITY FUNCTIONS */
|
||
|
||
function handleActivityPlayer(player) {
|
||
let pComp = getPlayerComp(player);
|
||
if (pComp != null) {
|
||
pComp.inactivityTicks++;
|
||
if (pComp.inactivityTicks == 60 * ((2 / 3) * afkLimit)) {
|
||
room.sendAnnouncement(
|
||
`⛔ ${player.name}, if you don't move or send a message in the next ${Math.floor(afkLimit / 3)} seconds, you will be kicked !`,
|
||
player.id,
|
||
warningColor,
|
||
'bold',
|
||
HaxNotification.MENTION
|
||
);
|
||
return;
|
||
}
|
||
if (pComp.inactivityTicks >= 60 * afkLimit) {
|
||
pComp.inactivityTicks = 0;
|
||
if (game.scores.time <= afkLimit - 0.5) {
|
||
setTimeout(() => {
|
||
!chooseMode ? instantRestart() : room.stopGame();
|
||
}, 10);
|
||
}
|
||
room.kickPlayer(player.id, 'AFK', false);
|
||
}
|
||
}
|
||
}
|
||
|
||
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) {
|
||
for (let player of teamRed) {
|
||
handleActivityPlayer(player);
|
||
}
|
||
for (let player of teamBlue) {
|
||
handleActivityPlayer(player);
|
||
}
|
||
}
|
||
}
|
||
|
||
/* 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);
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
/* TEAM BALANCE FUNCTIONS */
|
||
|
||
function balanceTeams() {
|
||
if (!chooseMode) {
|
||
if (players.length == 0) {
|
||
room.stopGame();
|
||
room.setScoreLimit(scoreLimit);
|
||
room.setTimeLimit(timeLimit);
|
||
} else if (players.length == 1 && teamRed.length == 0) {
|
||
instantRestart();
|
||
setTimeout(() => {
|
||
stadiumCommand(emptyPlayer, `!training`);
|
||
}, 5);
|
||
room.setPlayerTeam(players[0].id, Team.RED);
|
||
} else if (Math.abs(teamRed.length - teamBlue.length) == teamSpec.length && teamSpec.length > 0) {
|
||
const n = Math.abs(teamRed.length - teamBlue.length);
|
||
if (players.length == 2) {
|
||
instantRestart();
|
||
setTimeout(() => {
|
||
stadiumCommand(emptyPlayer, `!classic`);
|
||
}, 5);
|
||
}
|
||
if (teamRed.length > teamBlue.length) {
|
||
for (var i = 0; i < n; i++) {
|
||
room.setPlayerTeam(teamSpec[i].id, Team.BLUE);
|
||
}
|
||
} else {
|
||
for (var i = 0; i < n; i++) {
|
||
room.setPlayerTeam(teamSpec[i].id, Team.RED);
|
||
}
|
||
}
|
||
} else if (Math.abs(teamRed.length - teamBlue.length) > teamSpec.length) {
|
||
const n = Math.abs(teamRed.length - teamBlue.length);
|
||
if (players.length == 1) {
|
||
instantRestart();
|
||
setTimeout(() => {
|
||
stadiumCommand(emptyPlayer, `!training`);
|
||
}, 5);
|
||
room.setPlayerTeam(players[0].id, Team.RED);
|
||
return;
|
||
} else if (teamSize > 2 && players.length == 5) {
|
||
instantRestart();
|
||
setTimeout(() => {
|
||
stadiumCommand(emptyPlayer, `!classic`);
|
||
}, 5);
|
||
}
|
||
if (players.length == teamSize * 2 - 1) {
|
||
teamRedStats = [];
|
||
teamBlueStats = [];
|
||
}
|
||
if (teamRed.length > teamBlue.length) {
|
||
for (var i = 0; i < n; i++) {
|
||
room.setPlayerTeam(
|
||
teamRed[teamRed.length - 1 - i].id,
|
||
Team.SPECTATORS
|
||
);
|
||
}
|
||
} else {
|
||
for (var i = 0; i < n; i++) {
|
||
room.setPlayerTeam(
|
||
teamBlue[teamBlue.length - 1 - i].id,
|
||
Team.SPECTATORS
|
||
);
|
||
}
|
||
}
|
||
} else if (Math.abs(teamRed.length - teamBlue.length) < teamSpec.length && teamRed.length != teamBlue.length) {
|
||
room.pauseGame(true);
|
||
activateChooseMode();
|
||
choosePlayer();
|
||
} else if (teamSpec.length >= 2 && teamRed.length == teamBlue.length && teamRed.length < teamSize) {
|
||
if (teamRed.length == 2) {
|
||
instantRestart();
|
||
setTimeout(() => {
|
||
stadiumCommand(emptyPlayer, `!big`);
|
||
}, 5);
|
||
}
|
||
topButton();
|
||
}
|
||
}
|
||
}
|
||
|
||
function handlePlayersJoin() {
|
||
if (chooseMode) {
|
||
if (teamSize > 3 && players.length == changeToBigMapOn) { // ANTES: (teamSize > 2 && players.length == 6)
|
||
setTimeout(() => {
|
||
stadiumCommand(emptyPlayer, `!big`);
|
||
}, 5);
|
||
}
|
||
getSpecList(teamRed.length <= teamBlue.length ? teamRed[0] : teamBlue[0]);
|
||
}
|
||
balanceTeams();
|
||
}
|
||
|
||
function handlePlayersLeave() {
|
||
if (gameState != State.STOP) {
|
||
var scores = room.getScores();
|
||
if (players.length >= 2 * teamSize && scores.time >= (5 / 6) * game.scores.timeLimit && teamRed.length != teamBlue.length) {
|
||
var rageQuitCheck = false;
|
||
if (teamRed.length < teamBlue.length) {
|
||
if (scores.blue - scores.red == 2) {
|
||
endGame(Team.BLUE);
|
||
rageQuitCheck = true;
|
||
}
|
||
} else {
|
||
if (scores.red - scores.blue == 2) {
|
||
endGame(Team.RED);
|
||
rageQuitCheck = true;
|
||
}
|
||
}
|
||
if (rageQuitCheck) {
|
||
room.sendAnnouncement(
|
||
"Ragequit detected, game ended.",
|
||
null,
|
||
infoColor,
|
||
'bold',
|
||
HaxNotification.MENTION
|
||
)
|
||
stopTimeout = setTimeout(() => {
|
||
room.stopGame();
|
||
}, 100);
|
||
return;
|
||
}
|
||
}
|
||
}
|
||
if (chooseMode) {
|
||
if (teamSize > 2 && players.length == 5) {
|
||
setTimeout(() => {
|
||
stadiumCommand(emptyPlayer, `!classic`);
|
||
}, 5);
|
||
}
|
||
if (teamRed.length == 0 || teamBlue.length == 0) {
|
||
room.setPlayerTeam(teamSpec[0].id, teamRed.length == 0 ? Team.RED : Team.BLUE);
|
||
return;
|
||
}
|
||
if (Math.abs(teamRed.length - teamBlue.length) == teamSpec.length) {
|
||
deactivateChooseMode();
|
||
resumeGame();
|
||
var b = teamSpec.length;
|
||
if (teamRed.length > teamBlue.length) {
|
||
for (var i = 0; i < b; i++) {
|
||
clearTimeout(insertingTimeout);
|
||
insertingPlayers = true;
|
||
setTimeout(() => {
|
||
room.setPlayerTeam(teamSpec[0].id, Team.BLUE);
|
||
}, 5 * i);
|
||
}
|
||
insertingTimeout = setTimeout(() => {
|
||
insertingPlayers = false;
|
||
}, 5 * b);
|
||
} else {
|
||
for (var i = 0; i < b; i++) {
|
||
clearTimeout(insertingTimeout);
|
||
insertingPlayers = true;
|
||
setTimeout(() => {
|
||
room.setPlayerTeam(teamSpec[0].id, Team.RED);
|
||
}, 5 * i);
|
||
}
|
||
insertingTimeout = setTimeout(() => {
|
||
insertingPlayers = false;
|
||
}, 5 * b);
|
||
}
|
||
return;
|
||
}
|
||
if (streak == 0 && gameState == State.STOP) {
|
||
if (Math.abs(teamRed.length - teamBlue.length) == 2) {
|
||
var teamIn = teamRed.length > teamBlue.length ? teamRed : teamBlue;
|
||
room.setPlayerTeam(teamIn[teamIn.length - 1].id, Team.SPECTATORS)
|
||
}
|
||
}
|
||
if (teamRed.length == teamBlue.length && teamSpec.length < 2) {
|
||
deactivateChooseMode();
|
||
resumeGame();
|
||
return;
|
||
}
|
||
|
||
if (capLeft) {
|
||
choosePlayer();
|
||
} else {
|
||
getSpecList(teamRed.length <= teamBlue.length ? teamRed[0] : teamBlue[0]);
|
||
}
|
||
}
|
||
balanceTeams();
|
||
}
|
||
|
||
function handlePlayersTeamChange(byPlayer) {
|
||
if (chooseMode && !removingPlayers && byPlayer == null) {
|
||
if (Math.abs(teamRed.length - teamBlue.length) == teamSpec.length) {
|
||
deactivateChooseMode();
|
||
resumeGame();
|
||
var b = teamSpec.length;
|
||
if (teamRed.length > teamBlue.length) {
|
||
for (var i = 0; i < b; i++) {
|
||
clearTimeout(insertingTimeout);
|
||
insertingPlayers = true;
|
||
setTimeout(() => {
|
||
room.setPlayerTeam(teamSpec[0].id, Team.BLUE);
|
||
}, 5 * i);
|
||
}
|
||
insertingTimeout = setTimeout(() => {
|
||
insertingPlayers = false;
|
||
}, 5 * b);
|
||
} else {
|
||
for (var i = 0; i < b; i++) {
|
||
clearTimeout(insertingTimeout);
|
||
insertingPlayers = true;
|
||
setTimeout(() => {
|
||
room.setPlayerTeam(teamSpec[0].id, Team.RED);
|
||
}, 5 * i);
|
||
}
|
||
insertingTimeout = setTimeout(() => {
|
||
insertingPlayers = false;
|
||
}, 5 * b);
|
||
}
|
||
return;
|
||
} else if (
|
||
(teamRed.length == teamSize && teamBlue.length == teamSize) ||
|
||
(teamRed.length == teamBlue.length && teamSpec.length < 2)
|
||
) {
|
||
deactivateChooseMode();
|
||
resumeGame();
|
||
} else if (teamRed.length <= teamBlue.length && redCaptainChoice != '') {
|
||
if (redCaptainChoice == 'top') {
|
||
room.setPlayerTeam(teamSpec[0].id, Team.RED);
|
||
} else if (redCaptainChoice == 'random') {
|
||
var r = getRandomInt(teamSpec.length);
|
||
room.setPlayerTeam(teamSpec[r].id, Team.RED);
|
||
} else {
|
||
room.setPlayerTeam(teamSpec[teamSpec.length - 1].id, Team.RED);
|
||
}
|
||
return;
|
||
} else if (teamBlue.length < teamRed.length && blueCaptainChoice != '') {
|
||
if (blueCaptainChoice == 'top') {
|
||
room.setPlayerTeam(teamSpec[0].id, Team.BLUE);
|
||
} else if (blueCaptainChoice == 'random') {
|
||
var r = getRandomInt(teamSpec.length);
|
||
room.setPlayerTeam(teamSpec[r].id, Team.BLUE);
|
||
} else {
|
||
room.setPlayerTeam(teamSpec[teamSpec.length - 1].id, Team.BLUE);
|
||
}
|
||
return;
|
||
} else {
|
||
choosePlayer();
|
||
}
|
||
}
|
||
}
|
||
|
||
function handlePlayersStop(byPlayer) {
|
||
if (byPlayer == null && endGameVariable) {
|
||
if (chooseMode) {
|
||
if (players.length == 2 * teamSize) {
|
||
chooseMode = false;
|
||
resetButton();
|
||
for (var i = 0; i < teamSize; i++) {
|
||
clearTimeout(insertingTimeout);
|
||
insertingPlayers = true;
|
||
setTimeout(() => {
|
||
randomButton();
|
||
}, 200 * i);
|
||
}
|
||
insertingTimeout = setTimeout(() => {
|
||
insertingPlayers = false;
|
||
}, 200 * teamSize);
|
||
startTimeout = setTimeout(() => {
|
||
room.startGame();
|
||
}, 2000);
|
||
} else {
|
||
if (lastWinner == Team.RED) {
|
||
blueToSpecButton();
|
||
} else if (lastWinner == Team.BLUE) {
|
||
redToSpecButton();
|
||
setTimeout(() => {
|
||
swapButton();
|
||
}, 10);
|
||
} else {
|
||
resetButton();
|
||
}
|
||
clearTimeout(insertingTimeout);
|
||
insertingPlayers = true;
|
||
setTimeout(() => {
|
||
topButton();
|
||
}, 300);
|
||
insertingTimeout = setTimeout(() => {
|
||
insertingPlayers = false;
|
||
}, 300);
|
||
}
|
||
} else {
|
||
if (players.length == 2) {
|
||
if (lastWinner == Team.BLUE) {
|
||
swapButton();
|
||
}
|
||
startTimeout = setTimeout(() => {
|
||
room.startGame();
|
||
}, 2000);
|
||
} else if (players.length == 3 || players.length >= 2 * teamSize + 1) {
|
||
if (lastWinner == Team.RED) {
|
||
blueToSpecButton();
|
||
} else {
|
||
redToSpecButton();
|
||
setTimeout(() => {
|
||
swapButton();
|
||
}, 5);
|
||
}
|
||
clearTimeout(insertingTimeout);
|
||
insertingPlayers = true;
|
||
setTimeout(() => {
|
||
topButton();
|
||
}, 200);
|
||
insertingTimeout = setTimeout(() => {
|
||
insertingPlayers = false;
|
||
}, 300);
|
||
startTimeout = setTimeout(() => {
|
||
room.startGame();
|
||
}, 2000);
|
||
} else if (players.length == 4) {
|
||
resetButton();
|
||
clearTimeout(insertingTimeout);
|
||
insertingPlayers = true;
|
||
setTimeout(() => {
|
||
randomButton();
|
||
setTimeout(() => {
|
||
randomButton();
|
||
}, 500);
|
||
}, 500);
|
||
insertingTimeout = setTimeout(() => {
|
||
insertingPlayers = false;
|
||
}, 2000);
|
||
startTimeout = setTimeout(() => {
|
||
room.startGame();
|
||
}, 2000);
|
||
} else if (players.length == 5 || players.length >= 2 * teamSize + 1) {
|
||
if (lastWinner == Team.RED) {
|
||
blueToSpecButton();
|
||
} else {
|
||
redToSpecButton();
|
||
setTimeout(() => {
|
||
swapButton();
|
||
}, 5);
|
||
}
|
||
clearTimeout(insertingTimeout);
|
||
insertingPlayers = true;
|
||
insertingTimeout = setTimeout(() => {
|
||
insertingPlayers = false;
|
||
}, 200);
|
||
setTimeout(() => {
|
||
topButton();
|
||
}, 200);
|
||
activateChooseMode();
|
||
} else if (players.length == 6) {
|
||
resetButton();
|
||
clearTimeout(insertingTimeout);
|
||
insertingPlayers = true;
|
||
insertingTimeout = setTimeout(() => {
|
||
insertingPlayers = false;
|
||
}, 1500);
|
||
setTimeout(() => {
|
||
randomButton();
|
||
setTimeout(() => {
|
||
randomButton();
|
||
setTimeout(() => {
|
||
randomButton();
|
||
}, 500);
|
||
}, 500);
|
||
}, 500);
|
||
startTimeout = setTimeout(() => {
|
||
room.startGame();
|
||
}, 2000);
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
/* 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.`;
|
||
}
|
||
}
|
||
|
||
/* GLOBAL STATS FUNCTIONS */
|
||
|
||
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]++;
|
||
handleGK();
|
||
}
|
||
}
|
||
|
||
/* GOAL ATTRIBUTION FUNCTIONS */
|
||
|
||
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;
|
||
}
|
||
|
||
/* ROOM STATS FUNCTIONS */
|
||
|
||
function updatePlayerStats(player, teamStats) {
|
||
var stats = new HaxStatistics(player.name);
|
||
var pComp = getPlayerComp(player);
|
||
if (localStorage.getItem(authArray[player.id][0])) {
|
||
stats = JSON.parse(localStorage.getItem(authArray[player.id][0]));
|
||
}
|
||
stats.games++;
|
||
if (lastWinner == teamStats) stats.wins++;
|
||
stats.winrate = ((100 * stats.wins) / (stats.games || 1)).toFixed(1) + `%`;
|
||
stats.goals += getGoalsPlayer(pComp);
|
||
stats.assists += getAssistsPlayer(pComp);
|
||
stats.ownGoals += getOwnGoalsPlayer(pComp);
|
||
stats.CS += getCSPlayer(pComp);
|
||
stats.playtime += getGametimePlayer(pComp);
|
||
localStorage.setItem(authArray[player.id][0], JSON.stringify(stats));
|
||
}
|
||
|
||
function updateStats() {
|
||
if (
|
||
players.length >= 2 * teamSize &&
|
||
(
|
||
game.scores.time >= (5 / 6) * game.scores.timeLimit ||
|
||
game.scores.red == game.scores.scoreLimit ||
|
||
game.scores.blue == game.scores.scoreLimit
|
||
) &&
|
||
teamRedStats.length >= teamSize && teamBlueStats.length >= teamSize
|
||
) {
|
||
for (let player of teamRedStats) {
|
||
updatePlayerStats(player, Team.RED);
|
||
}
|
||
for (let player of teamBlueStats) {
|
||
updatePlayerStats(player, Team.BLUE);
|
||
}
|
||
}
|
||
}
|
||
|
||
function printRankings(statKey, id = 0) {
|
||
var leaderboard = [];
|
||
statKey = statKey == "cs" ? "CS" : statKey;
|
||
for (var i = 0; i < localStorage.length; i++) {
|
||
var key = localStorage.key(i);
|
||
if (key.length == 43)
|
||
leaderboard.push([
|
||
JSON.parse(localStorage.getItem(key)).playerName,
|
||
JSON.parse(localStorage.getItem(key))[statKey],
|
||
]);
|
||
}
|
||
if (leaderboard.length < 5) {
|
||
if (id != 0) {
|
||
room.sendAnnouncement(
|
||
'Not enough games played yet !',
|
||
id,
|
||
errorColor,
|
||
'bold',
|
||
HaxNotification.CHAT
|
||
);
|
||
}
|
||
return;
|
||
}
|
||
leaderboard.sort(function (a, b) { return b[1] - a[1]; });
|
||
var rankingString = `${statKey.charAt(0).toUpperCase() + statKey.slice(1)}> `;
|
||
for (let i = 0; i < 5; i++) {
|
||
let playerName = leaderboard[i][0];
|
||
let playerStat = leaderboard[i][1];
|
||
if (statKey == 'playtime') playerStat = getTimeStats(playerStat);
|
||
rankingString += `#${i + 1} ${playerName} : ${playerStat}, `;
|
||
}
|
||
rankingString = rankingString.substring(0, rankingString.length - 2);
|
||
room.sendAnnouncement(
|
||
rankingString,
|
||
id,
|
||
infoColor,
|
||
'bold',
|
||
HaxNotification.CHAT
|
||
);
|
||
}
|
||
|
||
/* GET STATS FUNCTIONS */
|
||
|
||
function getGamePlayerStats(player) {
|
||
var stats = new HaxStatistics(player.name);
|
||
var pComp = getPlayerComp(player);
|
||
stats.goals += getGoalsPlayer(pComp);
|
||
stats.assists += getAssistsPlayer(pComp);
|
||
stats.ownGoals += getOwnGoalsPlayer(pComp);
|
||
stats.playtime += getGametimePlayer(pComp);
|
||
stats.CS += getCSPlayer(pComp);
|
||
return stats;
|
||
}
|
||
|
||
function getGametimePlayer(pComp) {
|
||
if (pComp == null) return 0;
|
||
var timePlayer = 0;
|
||
for (let j = 0; j < pComp.timeEntry.length; j++) {
|
||
if (pComp.timeExit.length < j + 1) {
|
||
timePlayer += game.scores.time - pComp.timeEntry[j];
|
||
} else {
|
||
timePlayer += pComp.timeExit[j] - pComp.timeEntry[j];
|
||
}
|
||
}
|
||
return Math.floor(timePlayer);
|
||
}
|
||
|
||
function getGoalsPlayer(pComp) {
|
||
if (pComp == null) return 0;
|
||
var goalPlayer = 0;
|
||
for (let goal of game.goals) {
|
||
if (goal.striker != null && goal.team === pComp.player.team) {
|
||
if (authArray[goal.striker.id][0] == pComp.auth) {
|
||
goalPlayer++;
|
||
}
|
||
}
|
||
}
|
||
return goalPlayer;
|
||
}
|
||
|
||
function getOwnGoalsPlayer(pComp) {
|
||
if (pComp == null) return 0;
|
||
var goalPlayer = 0;
|
||
for (let goal of game.goals) {
|
||
if (goal.striker != null && goal.team !== pComp.player.team) {
|
||
if (authArray[goal.striker.id][0] == pComp.auth) {
|
||
goalPlayer++;
|
||
}
|
||
}
|
||
}
|
||
return goalPlayer;
|
||
}
|
||
|
||
function getAssistsPlayer(pComp) {
|
||
if (pComp == null) return 0;
|
||
var assistPlayer = 0;
|
||
for (let goal of game.goals) {
|
||
if (goal.assist != null) {
|
||
if (authArray[goal.assist.id][0] == pComp.auth) {
|
||
assistPlayer++;
|
||
}
|
||
}
|
||
}
|
||
return assistPlayer;
|
||
}
|
||
|
||
function getGKPlayer(pComp) {
|
||
if (pComp == null) return 0;
|
||
let GKRed = getGK(Team.RED);
|
||
if (pComp.auth == GKRed?.auth) {
|
||
return Team.RED;
|
||
}
|
||
let GKBlue = getGK(Team.BLUE);
|
||
if (pComp.auth == GKBlue?.auth) {
|
||
return Team.BLUE;
|
||
}
|
||
return Team.SPECTATORS;
|
||
}
|
||
|
||
function getCSPlayer(pComp) {
|
||
if (pComp == null || game.scores == null) return 0;
|
||
if (getGKPlayer(pComp) == Team.RED && game.scores.blue == 0) {
|
||
return 1;
|
||
} else if (getGKPlayer(pComp) == Team.BLUE && game.scores.red == 0) {
|
||
return 1;
|
||
}
|
||
return 0;
|
||
}
|
||
|
||
function actionReportCountTeam(goals, team) {
|
||
let playerActionSummaryTeam = [];
|
||
let indexTeam = team == Team.RED ? 0 : 1;
|
||
let indexOtherTeam = team == Team.RED ? 1 : 0;
|
||
for (let goal of goals[indexTeam]) {
|
||
if (goal[0] != null) {
|
||
if (playerActionSummaryTeam.find(a => a[0].id == goal[0].id)) {
|
||
let index = playerActionSummaryTeam.findIndex(a => a[0].id == goal[0].id);
|
||
playerActionSummaryTeam[index][1]++;
|
||
} else {
|
||
playerActionSummaryTeam.push([goal[0], 1, 0, 0]);
|
||
}
|
||
if (goal[1] != null) {
|
||
if (playerActionSummaryTeam.find(a => a[0].id == goal[1].id)) {
|
||
let index = playerActionSummaryTeam.findIndex(a => a[0].id == goal[1].id);
|
||
playerActionSummaryTeam[index][2]++;
|
||
} else {
|
||
playerActionSummaryTeam.push([goal[1], 0, 1, 0]);
|
||
}
|
||
}
|
||
}
|
||
}
|
||
if (goals[indexOtherTeam].length == 0) {
|
||
let playerCS = getGK(team)?.player;
|
||
if (playerCS != null) {
|
||
if (playerActionSummaryTeam.find(a => a[0].id == playerCS.id)) {
|
||
let index = playerActionSummaryTeam.findIndex(a => a[0].id == playerCS.id);
|
||
playerActionSummaryTeam[index][3]++;
|
||
} else {
|
||
playerActionSummaryTeam.push([playerCS, 0, 0, 1]);
|
||
}
|
||
}
|
||
}
|
||
|
||
playerActionSummaryTeam.sort((a, b) => (a[1] + a[2] + a[3]) - (b[1] + b[2] + b[3]));
|
||
return playerActionSummaryTeam;
|
||
}
|
||
|
||
/* PRINT FUNCTIONS */
|
||
|
||
function printPlayerStats(stats) {
|
||
let statsString = '';
|
||
for (let [key, value] of Object.entries(stats)) {
|
||
if (key == 'playerName') statsString += `${value}: `;
|
||
else {
|
||
if (key == 'playtime') value = getTimeStats(value);
|
||
let reCamelCase = /([A-Z](?=[a-z]+)|[A-Z]+(?![a-z]))/g;
|
||
let statName = key.replaceAll(reCamelCase, ' $1').trim();
|
||
statsString += `${statName.charAt(0).toUpperCase() + statName.slice(1)}: ${value}, `;
|
||
}
|
||
}
|
||
statsString = statsString.substring(0, statsString.length - 2);
|
||
return statsString;
|
||
}
|
||
|
||
/* 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, getGametimePlayer(p)]);
|
||
var blueTeamTimes = game.playerComp[1].map((p) => [p.player, getGametimePlayer(p)]);
|
||
|
||
for (let time of redTeamTimes) {
|
||
var minutes = getMinutesReport(time[1]);
|
||
var seconds = getSecondsReport(time[1]);
|
||
fieldGametimeRed.value += `> **${time[0].name}:** ${minutes > 0 ? `${minutes}m` : ''}` +
|
||
`${seconds > 0 || minutes == 0 ? `${seconds}s` : ''}\n`;
|
||
}
|
||
fieldGametimeRed.value += `\n${blueTeamTimes.length - redTeamTimes.length > 0 ? '\n'.repeat(blueTeamTimes.length - redTeamTimes.length) : ''
|
||
}`;
|
||
fieldGametimeRed.value += '=====================';
|
||
|
||
for (let time of blueTeamTimes) {
|
||
var minutes = getMinutesReport(time[1]);
|
||
var seconds = getSecondsReport(time[1]);
|
||
fieldGametimeBlue.value += `> **${time[0].name}:** ${minutes > 0 ? `${minutes}m` : ''}` +
|
||
`${seconds > 0 || minutes == 0 ? `${seconds}s` : ''}\n`;
|
||
}
|
||
fieldGametimeBlue.value += `\n${redTeamTimes.length - blueTeamTimes.length > 0 ? '\n'.repeat(redTeamTimes.length - blueTeamTimes.length) : ''
|
||
}`;
|
||
fieldGametimeBlue.value += '=====================';
|
||
|
||
return [fieldGametimeRed, fieldGametimeBlue];
|
||
}
|
||
|
||
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 i = 0; i < game.goals.length; i++) {
|
||
goals[game.goals[i].team - 1].push([game.goals[i].striker, game.goals[i].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`;
|
||
}
|
||
}
|
||
|
||
fieldReportRed.value += `\n${blueActions.length - redActions.length > 0 ? '\n'.repeat(blueActions.length - redActions.length) : ''
|
||
}`;
|
||
fieldReportRed.value += '=====================';
|
||
|
||
fieldReportBlue.value += `\n${redActions.length - blueActions.length > 0 ? '\n'.repeat(redActions.length - blueActions.length) : ''
|
||
}`;
|
||
fieldReportBlue.value += '=====================';
|
||
|
||
return [fieldReportRed, fieldReportBlue];
|
||
}
|
||
|
||
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);
|
||
|
||
var possR = possession[0] / (possession[0] + possession[1]);
|
||
var possB = 1 - possR;
|
||
var possRString = (possR * 100).toFixed(0).toString();
|
||
var possBString = (possB * 100).toFixed(0).toString();
|
||
var zoneR = actionZoneHalf[0] / (actionZoneHalf[0] + actionZoneHalf[1]);
|
||
var zoneB = 1 - zoneR;
|
||
var zoneRString = (zoneR * 100).toFixed(0).toString();
|
||
var zoneBString = (zoneB * 100).toFixed(0).toString();
|
||
var win = (game.scores.red > game.scores.blue) * 1 + (game.scores.blue > game.scores.red) * 2;
|
||
var objectBodyWebhook = {
|
||
embeds: [
|
||
{
|
||
title: `📝 MATCH REPORT #${getIdReport()}`,
|
||
description:
|
||
`**${getTimeEmbed(game.scores.time)}** ` +
|
||
(win == 1 ? '**Red Team** ' : 'Red Team ') + game.scores.red +
|
||
' - ' +
|
||
game.scores.blue + (win == 2 ? ' **Blue Team**' : ' Blue Team') +
|
||
'\n```c\nPossession: ' + possRString + '% - ' + possBString + '%' +
|
||
'\nAction Zone: ' + zoneRString + '% - ' + zoneBString + '%\n```\n\n',
|
||
color: 9567999,
|
||
fields: fields,
|
||
footer: {
|
||
text: `Recording: ${getRecordingName(game)}`,
|
||
},
|
||
timestamp: new Date().toISOString(),
|
||
},
|
||
],
|
||
username: roomName
|
||
};
|
||
if (logChannel != '') {
|
||
fetch(logChannel, {
|
||
method: 'POST',
|
||
body: JSON.stringify(objectBodyWebhook),
|
||
headers: {
|
||
'Content-Type': 'application/json',
|
||
},
|
||
}).then((res) => res);
|
||
}
|
||
}
|
||
|
||
/* 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 (${playersAll.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 = playersAll.filter((p) => p.id != player.id && authArray[p.id][0] == player.auth);
|
||
if (sameAuthCheck.length > 0 && !debugMode) {
|
||
var oldPlayerArray = playersAll.filter((p) => p.id != player.id && authArray[p.id][0] == player.auth);
|
||
for (let oldPlayer of oldPlayerArray) {
|
||
ghostKickHandle(oldPlayer, player);
|
||
}
|
||
}
|
||
handlePlayersJoin();
|
||
};
|
||
|
||
room.onPlayerTeamChange = function (changedPlayer, byPlayer) {
|
||
handleLineupChangeTeamChange(changedPlayer);
|
||
if (AFKSet.has(changedPlayer.id) && changedPlayer.team != Team.SPECTATORS) {
|
||
room.setPlayerTeam(changedPlayer.id, Team.SPECTATORS);
|
||
room.sendAnnouncement(
|
||
`${changedPlayer.name} is AFK !`,
|
||
null,
|
||
errorColor,
|
||
'bold',
|
||
HaxNotification.CHAT
|
||
);
|
||
return;
|
||
}
|
||
updateTeams();
|
||
if (gameState != State.STOP) {
|
||
if (changedPlayer.team != Team.SPECTATORS && game.scores.time <= (3 / 4) * game.scores.timeLimit && Math.abs(game.scores.blue - game.scores.red) < 2) {
|
||
changedPlayer.team == Team.RED ? teamRedStats.push(changedPlayer) : teamBlueStats.push(changedPlayer);
|
||
}
|
||
}
|
||
handleActivityPlayerTeamChange(changedPlayer);
|
||
handlePlayersTeamChange(byPlayer);
|
||
};
|
||
|
||
room.onPlayerLeave = function (player) {
|
||
setTimeout(() => {
|
||
if (!kickFetchVariable) {
|
||
if (roomWebhook != '') {
|
||
var stringContent = `[${getDate()}] ⬅️ LEAVE (${playersAll.length}/${maxPlayers})\n**${player.name}**` +
|
||
`[${authArray[player.id][0]}] {${authArray[player.id][1]}}`;
|
||
fetch(roomWebhook, {
|
||
method: 'POST',
|
||
body: JSON.stringify({
|
||
content: stringContent,
|
||
username: roomName,
|
||
}),
|
||
headers: {
|
||
'Content-Type': 'application/json',
|
||
},
|
||
}).then((res) => res);
|
||
}
|
||
} else kickFetchVariable = false;
|
||
}, 10);
|
||
handleLineupChangeLeave(player);
|
||
checkCaptainLeave(player);
|
||
updateTeams();
|
||
updateAdmins();
|
||
handlePlayersLeave();
|
||
};
|
||
|
||
room.onPlayerKicked = function (kickedPlayer, reason, ban, byPlayer) {
|
||
kickFetchVariable = true;
|
||
if (roomWebhook != '') {
|
||
var stringContent = `[${getDate()}] ⛔ ${ban ? 'BAN' : 'KICK'} (${playersAll.length}/${maxPlayers})\n` +
|
||
`**${kickedPlayer.name}** [${authArray[kickedPlayer.id][0]}] {${authArray[kickedPlayer.id][1]}} was ${ban ? 'banned' : 'kicked'}` +
|
||
`${byPlayer != null ? ' by **' + byPlayer.name + '** [' + authArray[byPlayer.id][0] + '] {' + authArray[byPlayer.id][1] + '}' : ''}`
|
||
fetch(roomWebhook, {
|
||
method: 'POST',
|
||
body: JSON.stringify({
|
||
content: stringContent,
|
||
username: roomName,
|
||
}),
|
||
headers: {
|
||
'Content-Type': 'application/json',
|
||
},
|
||
}).then((res) => res);
|
||
}
|
||
if ((ban && ((byPlayer != null &&
|
||
(byPlayer.id == kickedPlayer.id || getRole(byPlayer) < Role.MASTER)) || getRole(kickedPlayer) == Role.MASTER)) || disableBans
|
||
) {
|
||
room.clearBan(kickedPlayer.id);
|
||
return;
|
||
}
|
||
if (byPlayer != null && getRole(byPlayer) < Role.ADMIN_PERM) {
|
||
room.sendAnnouncement(
|
||
'You are not allowed to kick/ban players !',
|
||
byPlayer.id,
|
||
errorColor,
|
||
'bold',
|
||
HaxNotification.CHAT
|
||
);
|
||
room.setPlayerAdmin(byPlayer.id, false);
|
||
return;
|
||
}
|
||
if (ban) banList.push([kickedPlayer.name, kickedPlayer.id]);
|
||
};
|
||
|
||
/* PLAYER ACTIVITY */
|
||
|
||
room.onPlayerChat = function (player, message) {
|
||
if (gameState !== State.STOP && player.team != Team.SPECTATORS) {
|
||
let pComp = getPlayerComp(player);
|
||
if (pComp != null) pComp.inactivityTicks = 0;
|
||
}
|
||
let msgArray = message.split(/ +/);
|
||
if (!hideClaimMessage || msgArray[0] != '!claim') {
|
||
if (roomWebhook != '')
|
||
fetch(roomWebhook, {
|
||
method: 'POST',
|
||
body: JSON.stringify({
|
||
content: `[${getDate()}] 💬 CHAT\n**${player.name}** : ${message.replace('@', '@ ')}`,
|
||
username: roomName,
|
||
}),
|
||
headers: {
|
||
'Content-Type': 'application/json',
|
||
},
|
||
}).then((res) => res);
|
||
}
|
||
if (msgArray[0][0] == '!') {
|
||
let command = getCommand(msgArray[0].slice(1).toLowerCase());
|
||
if (command != false && commands[command].roles <= getRole(player)) commands[command].function(player, message);
|
||
else
|
||
room.sendAnnouncement(
|
||
`The command you tried to enter does not exist for you. Please enter '!help' to get the available commands to you.`,
|
||
player.id,
|
||
errorColor,
|
||
'bold',
|
||
HaxNotification.CHAT
|
||
);
|
||
return false;
|
||
}
|
||
if (msgArray[0].toLowerCase() == 't') {
|
||
teamChat(player, message);
|
||
return false;
|
||
}
|
||
if (msgArray[0].substring(0, 2) === '@@') {
|
||
playerChat(player, message);
|
||
return false;
|
||
}
|
||
if (chooseMode && teamRed.length * teamBlue.length != 0) {
|
||
var choosingMessageCheck = chooseModeFunction(player, message);
|
||
if (choosingMessageCheck) return false;
|
||
}
|
||
if (slowMode > 0) {
|
||
var filter = slowModeFunction(player, message);
|
||
if (filter) return false;
|
||
}
|
||
if (!player.admin && muteArray.getByAuth(authArray[player.id][0]) != null) {
|
||
room.sendAnnouncement(
|
||
`You are muted !`,
|
||
player.id,
|
||
errorColor,
|
||
'bold',
|
||
HaxNotification.CHAT
|
||
);
|
||
return false;
|
||
}
|
||
};
|
||
|
||
room.onPlayerActivity = function (player) {
|
||
if (gameState !== State.STOP) {
|
||
let pComp = getPlayerComp(player);
|
||
if (pComp != null) pComp.inactivityTicks = 0;
|
||
}
|
||
};
|
||
|
||
room.onPlayerBallKick = function (player) {
|
||
if (playSituation != Situation.GOAL) {
|
||
var ballPosition = room.getBallPosition();
|
||
if (game.touchArray.length == 0 || player.id != game.touchArray[game.touchArray.length - 1].player.id) {
|
||
if (playSituation == Situation.KICKOFF) playSituation = Situation.PLAY;
|
||
lastTeamTouched = player.team;
|
||
game.touchArray.push(
|
||
new BallTouch(
|
||
player,
|
||
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()
|
||
);
|
||
}
|
||
}
|
||
};
|
||
|
||
/* GAME MANAGEMENT */
|
||
|
||
room.onGameStart = function (byPlayer) {
|
||
clearTimeout(startTimeout);
|
||
if (byPlayer != null) clearTimeout(stopTimeout);
|
||
game = new Game();
|
||
possession = [0, 0];
|
||
actionZoneHalf = [0, 0];
|
||
gameState = State.PLAY;
|
||
endGameVariable = false;
|
||
goldenGoal = false;
|
||
playSituation = Situation.KICKOFF;
|
||
lastTouches = Array(2).fill(null);
|
||
lastTeamTouched = Team.SPECTATORS;
|
||
teamRedStats = [];
|
||
teamBlueStats = [];
|
||
if (teamRed.length == teamSize && teamBlue.length == teamSize) {
|
||
for (var i = 0; i < teamSize; i++) {
|
||
teamRedStats.push(teamRed[i]);
|
||
teamBlueStats.push(teamBlue[i]);
|
||
}
|
||
}
|
||
calculateStadiumVariables();
|
||
};
|
||
|
||
room.onGameStop = function (byPlayer) {
|
||
clearTimeout(stopTimeout);
|
||
clearTimeout(unpauseTimeout);
|
||
if (byPlayer != null) clearTimeout(startTimeout);
|
||
game.rec = room.stopRecording();
|
||
if (
|
||
!cancelGameVariable && game.playerComp[0].length + game.playerComp[1].length > 0 &&
|
||
(
|
||
(game.scores.timeLimit != 0 &&
|
||
((game.scores.time >= 0.5 * game.scores.timeLimit &&
|
||
game.scores.time < 0.75 * game.scores.timeLimit &&
|
||
game.scores.red != game.scores.blue) ||
|
||
game.scores.time >= 0.75 * game.scores.timeLimit)
|
||
) ||
|
||
endGameVariable
|
||
)
|
||
) {
|
||
fetchSummaryEmbed(game);
|
||
if (fetchRecordingVariable) {
|
||
setTimeout((gameEnd) => { fetchRecording(gameEnd); }, 500, game);
|
||
}
|
||
}
|
||
cancelGameVariable = false;
|
||
gameState = State.STOP;
|
||
playSituation = Situation.STOP;
|
||
updateTeams();
|
||
handlePlayersStop(byPlayer);
|
||
handleActivityStop();
|
||
};
|
||
|
||
room.onGamePause = function (byPlayer) {
|
||
if (mentionPlayersUnpause && gameState == State.PAUSE) {
|
||
if (byPlayer != null) {
|
||
room.sendAnnouncement(
|
||
`Game paused by ${byPlayer.name} !`,
|
||
null,
|
||
defaultColor,
|
||
'bold',
|
||
HaxNotification.NONE
|
||
);
|
||
} else {
|
||
room.sendAnnouncement(
|
||
`Game paused !`,
|
||
null,
|
||
defaultColor,
|
||
'bold',
|
||
HaxNotification.NONE
|
||
);
|
||
}
|
||
}
|
||
clearTimeout(unpauseTimeout);
|
||
gameState = State.PAUSE;
|
||
};
|
||
|
||
room.onGameUnpause = function (byPlayer) {
|
||
unpauseTimeout = setTimeout(() => {
|
||
gameState = State.PLAY;
|
||
}, 2000);
|
||
if (mentionPlayersUnpause) {
|
||
if (byPlayer != null) {
|
||
room.sendAnnouncement(
|
||
`Game unpaused by ${byPlayer.name} !`,
|
||
null,
|
||
defaultColor,
|
||
'bold',
|
||
HaxNotification.NONE
|
||
);
|
||
} else {
|
||
room.sendAnnouncement(
|
||
`Game unpaused !`,
|
||
null,
|
||
defaultColor,
|
||
'bold',
|
||
HaxNotification.NONE
|
||
);
|
||
}
|
||
}
|
||
if (
|
||
(teamRed.length == teamSize && teamBlue.length == teamSize && chooseMode) ||
|
||
(teamRed.length == teamBlue.length && teamSpec.length < 2 && chooseMode)
|
||
) {
|
||
deactivateChooseMode();
|
||
}
|
||
};
|
||
|
||
room.onTeamGoal = function (team) {
|
||
const scores = room.getScores();
|
||
game.scores = scores;
|
||
playSituation = Situation.GOAL;
|
||
ballSpeed = getBallSpeed();
|
||
var goalString = getGoalString(team);
|
||
for (let player of teamRed) {
|
||
var playerComp = getPlayerComp(player);
|
||
team == Team.RED ? playerComp.goalsScoredTeam++ : playerComp.goalsConcededTeam++;
|
||
}
|
||
for (let player of teamBlue) {
|
||
var playerComp = getPlayerComp(player);
|
||
team == Team.BLUE ? playerComp.goalsScoredTeam++ : playerComp.goalsConcededTeam++;
|
||
}
|
||
room.sendAnnouncement(
|
||
goalString,
|
||
null,
|
||
team == Team.RED ? redColor : blueColor,
|
||
null,
|
||
HaxNotification.CHAT
|
||
);
|
||
if (roomWebhook != '') {
|
||
fetch(roomWebhook, {
|
||
method: 'POST',
|
||
body: JSON.stringify({
|
||
content: `[${getDate()}] ${goalString}`,
|
||
username: roomName,
|
||
}),
|
||
headers: {
|
||
'Content-Type': 'application/json',
|
||
},
|
||
}).then((res) => res);
|
||
}
|
||
if ((scores.scoreLimit != 0 && (scores.red == scores.scoreLimit || scores.blue == scores.scoreLimit)) || goldenGoal) {
|
||
endGame(team);
|
||
goldenGoal = false;
|
||
stopTimeout = setTimeout(() => {
|
||
room.stopGame();
|
||
}, 1000);
|
||
}
|
||
};
|
||
|
||
room.onPositionsReset = function () {
|
||
lastTouches = Array(2).fill(null);
|
||
lastTeamTouched = Team.SPECTATORS;
|
||
playSituation = Situation.KICKOFF;
|
||
};
|
||
|
||
/* MISCELLANEOUS */
|
||
|
||
room.onRoomLink = function (url) {
|
||
console.log(`${url}\nmasterPassword : ${masterPassword}`);
|
||
if (roomWebhook != '') {
|
||
fetch(roomWebhook, {
|
||
method: 'POST',
|
||
body: JSON.stringify({
|
||
content: `[${getDate()}] 🔗 LINK ${url}\nmasterPassword : ${masterPassword}`,
|
||
username: roomName,
|
||
}),
|
||
headers: {
|
||
'Content-Type': 'application/json',
|
||
},
|
||
}).then((res) => res);
|
||
}
|
||
};
|
||
|
||
room.onPlayerAdminChange = function (changedPlayer, byPlayer) {
|
||
updateTeams();
|
||
if (!changedPlayer.admin && getRole(changedPlayer) >= Role.ADMIN_TEMP) {
|
||
room.setPlayerAdmin(changedPlayer.id, true);
|
||
return;
|
||
}
|
||
updateAdmins(byPlayer != null && !changedPlayer.admin && changedPlayer.id == byPlayer.id ? changedPlayer.id : 0);
|
||
};
|
||
|
||
room.onKickRateLimitSet = function (min, rate, burst, byPlayer) {
|
||
if (byPlayer != null) {
|
||
room.sendAnnouncement(
|
||
`It is not allowed to change the kickrate limit. It must stay at "6-0-0".`,
|
||
player.id,
|
||
errorColor,
|
||
'bold',
|
||
HaxNotification.CHAT
|
||
);
|
||
room.setKickRateLimit(6, 0, 0);
|
||
}
|
||
};
|
||
|
||
room.onStadiumChange = function (newStadiumName, byPlayer) {
|
||
if (byPlayer !== null) {
|
||
if (getRole(byPlayer) < Role.MASTER && currentStadium != 'other') {
|
||
room.sendAnnouncement(
|
||
`You can't change stadium manually ! Please use the stadium commands.`,
|
||
byPlayer.id,
|
||
errorColor,
|
||
'bold',
|
||
HaxNotification.CHAT
|
||
);
|
||
stadiumCommand(emptyPlayer, `!${currentStadium}`);
|
||
} else {
|
||
room.sendAnnouncement(
|
||
`Map changed. After you're done with this map, please use the stadium commands.`,
|
||
byPlayer.id,
|
||
infoColor,
|
||
'bold',
|
||
HaxNotification.CHAT
|
||
);
|
||
currentStadium = 'other';
|
||
}
|
||
}
|
||
checkStadiumVariable = true;
|
||
};
|
||
|
||
room.onGameTick = function () {
|
||
checkTime();
|
||
getLastTouchOfTheBall();
|
||
getGameStats();
|
||
handleActivity();
|
||
}; |