wind = {strength:30,size:1000},
player = {score:0,s:round(Date.now()/1000)%shipData.length,pos:createVector(0,0),dir:0,c:{c:0,d:0,dC:false},ID:false,name:`player${round(random(99,1000))}`}
socket = io($OP.getEchoServerURL(1236812))
socket.on('connect',()=>{
socket.on('globalqalert',(e,i)=>{if(i==socket.id)return;qalert(e,5)})
socket.on('data',(data,i)=>{if(i==socket.id)return;t=ships.filter(x=>x.ID==data.ID);if(t.length==0){ships.push(data)}else{
t[0].a=data.a;t[0].dir=data.dir;t[0].pos.x=data.pos.x;t[0].pos.y=data.pos.y;t[0].s=data.s;t[0].dC=data.dC;t[0].name=data.name;t[0].score=data.score}})
socket.on('radar',(x,i)=>{if(i==socket.id)return;radars.push(x)})
socket.on('deleteRadar',(x,i)=>{if(i==socket.id)return;radars=radars.filter(e=>(e.i==x.i&&e.ID==x.ID)==false);if(x.oID==player.ID){located = 255;player.score/=3}player.score=max(0,player.score-10)})
socket.on('chat',(x,i)=>{if(i==socket.id)return;if(x.to=='[ALL]'||x.to.split(',').includes(player.name.split(':')[0])||(player.name.includes(':')&&x.to.split(',').includes(':'+player.name.split('::')[1]))){qalert(x.n+' said: '+x.m.replaceAll('\n',''),10)}})
socket.on('kick',(n1,n2,i)=>{if(i==socket.id)return;if(n1==team(player.name,true)){if(team(n2)==team(player.name)&&player.name.split(':').length>1){qalert('You were kicked out of team '+team(n2))
player.name=team(player.name,true)}}})
socket.emit('globalqalert',player.name+' entered')
socket.on("connect_error",()=>{
console.log('connection error')
socket.on('disconnect',()=>{socket.emit('globalqalert',player.name+' left')})
createCanvas(windowWidth-20,windowHeight-20)
canvas = createGraphics(width,height)
w = floor(min(width-20,height-20)/100)*100
noiseseedvalue=round(Date.now()/100/60/60/24)
noiseSeed(noiseseedvalue)
for(let element of document.getElementsByClassName("p5Canvas")){element.addEventListener("contextmenu",(e)=>e.preventDefault())}
fill(150);stroke(0,0,0,0);rect(0,0,width,height)
push();textAlign(CENTER,CENTER);fill(0);stroke(0,0,0,0);text('Connecting...',width/2,height/2);pop()
fill(255);stroke(0,0,0,0);rect(0,0,(width-w)/2,height);rect(0,0,width,(height-w)/2);rect(width,height,-(width-w)/2,-height);rect(width,height,-width,-(height-w)/2)
if(round(DATE/100/60/60/24)!=noiseseedvalue){noiseseedvalue=round(DATE/100/60/60/24);noiseSeed(noiseseedvalue)}
fill(150);stroke(0,0,0,0);rect(0,0,width,height)
player.dir = createVector(mouseX-width/2,mouseY-height/2).heading()
if(lastSensed>0)lastSensed-=1
if(player.c.c<shipData[player.s].b.n){player.c.c+=1/(50*shipData[player.s].b.r)}
if(player.c.c>shipData[player.s].b.n){player.c.c=shipData[player.s].b.n}
if(player.c.c>=1&&abs(mouseX-width/2)<w/2&&abs(mouseY-height/2)<w/2&&((mouseIsPressed&&mouseButton==RIGHT)||keyIsDown(82))&&lastSensed<1){
player.c.c-=1;d=Date.now();lastSensed=25
radars.push({ID:player.ID,i:d,x:player.pos.x,y:player.pos.y,a1:player.dir,a:shipData[player.s].r.a,rr:0,r:shipData[player.s].r.r,s:shipData[player.s].r.s,d:true,n:player.name})
socket.emit('radar',{ID:player.ID,i:d,x:player.pos.x,y:player.pos.y,a1:player.dir,a:shipData[player.s].r.a,rr:0,r:shipData[player.s].r.r,s:shipData[player.s].r.s,d:true,
n:player.name})}q=shipData[player.s].s;if(player.c.dC){player.c.d+=1/50;q+=shipData[player.s].b.s;if(player.c.d>shipData[player.s].b.b){player.c.dC=false;player.c.d=0}}
if(player.c.c>=1&&player.c.dC==false){if(((mouseIsPressed&&mouseButton==LEFT)||(keyIsDown(70)))&&abs(mouseX-width/2)<w/2&&abs(mouseY-height/2)<w/2){player.c.dC=true;player.c.c-=1}}
n=(createVector(mouseX-width/2,mouseY-height/2).mag()>140?1:(createVector(mouseX-width/2,mouseY-height/2).mag()<70?0:(createVector(mouseX-width/2,mouseY-height/2).mag()-70)/70))
if(mouseX>(width-w)/2&&mouseX<(width+w)/2&&mouseY>(height-w)/2&&mouseY<(height+w)/2)player.pos.add(createVector(q,0).rotate(player.dir).mult(n))
z = Noise(player.pos.x/800,player.pos.y/800,DATE/10000)
player.pos.add(createVector(wind.strength*0.4*z,0).rotate(noise(player.pos.x/wind.strength/wind.size,player.pos.y/wind.strength/wind.size,DATE/40)*TWO_PI*wind.size))
translate(createVector(wind.strength*0.4*z,0).rotate(noise(player.pos.x/wind.strength/wind.size,player.pos.y/wind.strength/wind.size,DATE/40)*TWO_PI*wind.size).div(4))
push();translate((width-w)/2,(height-w)/2);stroke(0,0,0,0);for(i=-ceil(w/100);i<1;i++){for(j=-ceil(w/100);j<1;j++){
z = min(1,Noise((player.pos.x-100*i-w/2-(player.pos.x%100))/800,(player.pos.y-100*j-w/2-(player.pos.y%100))/800,DATE/10000));fill(125*(1-z)*(1-z))
if(dist(0,0,player.pos.x-100*i-w/2-(player.pos.x%100),player.pos.y-100*j-w/2-(player.pos.y%100))<bRadius-8)
circle(-1*(player.pos.x%100)-100*i,-1*(player.pos.y%100)-100*j,5+10*z*z)}}pop()
for(let r of radars){collided=true;if(team(player.name)==team(r.n))collided=false;if(player.name.split(':').length==1)collided=true;if(r.n==player.name)collided=true
fill(0,0,0,0);stroke(collided?0:color(0,0,0,50))
arc(r.x-player.pos.x+width/2,r.y-player.pos.y+height/2,r.rr,r.rr,r.a1-r.a/2,r.a1+r.a/2)
if(minimapShowRadar&&r.ID==player.ID){
stroke(collided?0:color(0,0,0,50))
let pq=[createVector((width+w)/2-25-bRadius/50+r.x/50,(height+w)/2-25-bRadius/50+r.y/50).add(createVector(r.rr/50,0).rotate(r.a1-r.a/2))]
pq.push(createVector((width+w)/2-25-bRadius/50+r.x/50,(height+w)/2-25-bRadius/50+r.y/50).add(createVector(r.rr/50,0).rotate(r.a1-r.a/2+r.a/30*i)))
if(pq[i].dist(createVector((width+w)/2-25-bRadius/50,(height+w)/2-25-bRadius/50))<bRadius/50&&
pq[i+1].dist(createVector((width+w)/2-25-bRadius/50,(height+w)/2-25-bRadius/50))<bRadius/50)
line(pq[i].x,pq[i].y,pq[i+1].x,pq[i+1].y)
if(r.rr>r.r){r.d=false}if(r.ID==player.ID)for(let s of ships){collided=true;if(team(s.name)==team(r.n))collided=false;if(s.name.split(':').length==1)collided=true
if(collided)if(circleArcIntersect({c:{x:s.pos.x,y:s.pos.y,
r:2*shipData[s.s].rsz},a:{x:r.x,y:r.y,r:r.rr,a1:r.a1,a:r.a+2*atan2(shipData[s.s].rsz,dist(r.x,r.y,s.pos.x,s.pos.y))}})){player.score+=s.score/4;trackers.push({a:250,s:s.s,
x:s.pos.x,y:s.pos.y});r.d=false;socket.emit('deleteRadar',{ID:r.ID,i:r.i,oID:s.ID})}}}radars = radars.filter(x=>x.d)
for(let t of trackers){t.a-=1;q=createVector(t.x-player.pos.x,t.y-player.pos.y).limit(max(150,min(250,w/2-150)));push();fill(0);stroke(0,shipData[t.s].f);textAlign(CENTER,CENTER)
textSize(shipData[t.s].qsz||20);text(shipData[t.s].c,width/2+q.x,height/2+q.y);textSize(10);stroke(0,0,0,0);text(floor(dist(player.pos.x,player.pos.y,t.x,t.y)/100).toString()+
' m away',width/2+q.x,height/2+q.y+20);pop()}trackers=trackers.filter(x=>x.a>0)
player.pos.limit(bRadius-shipData[player.s].rsz/2)
push();translate(width/2,height/2);q=shipData[player.s].o;rotate(player.dir+q);textSize(30*shipData[player.s].sz);textAlign(CENTER,CENTER);fill(0)
stroke(0,shipData[player.s].f);text(shipData[player.s].c,0,0);fill(0,0,0,0);stroke(0,0,0,50);circle(0,0,shipData[player.s].rsz);rotate(-player.dir-q)
translate(0,-shipData[player.s].rsz/2-10);fill(0);stroke(0,0,0,0);textSize(10);text(player.name+'\nScore: '+floor(player.score).toString(),0,-10)
translate(0,shipData[player.s].rsz-5);fill(100);stroke(100);for(i=0;i<player.c.c;i++){rect(-15,30+8*i,(i<player.c.c-1?30:(player.c.c-i)*30),2)}pop()
for(let s of ships){s.a-=1;push();translate(width/2+s.pos.x-player.pos.x,height/2+s.pos.y-player.pos.y);q=shipData[s.s].o;rotate(s.dir+q);textSize(30*shipData[s.s].sz)
textAlign(CENTER,CENTER);fill(shipData[s.s].t+(s.dC?shipData[s.s].b.t:0));stroke(shipData[s.s].t+(s.dC?shipData[s.s].b.t:0),shipData[s.s].f);text(shipData[s.s].c,0,0)
rotate(-s.dir-q);translate(0,-shipData[s.s].rsz/2-10);fill(shipData[s.s].t+(s.dC?shipData[s.s].b.t:0));stroke(0,0,0,0);textSize(10)
text(s.name+'\nScore: '+floor(s.score).toString(),0,-10);pop()}
push();fill(0,0,0,0);stroke(0);strokeWeight(3);circle(width/2-player.pos.x,height/2-player.pos.y,bRadius*2);pop()
ships = ships.filter(x=>x.a>0)
if(located<215){player.score+=1/50}if(player.score>highscore){highscore=player.score}
fill(0,0,0,0);stroke(0);circle((width+w)/2-25-bRadius/50,(height+w)/2-25-bRadius/50,bRadius/25)
circle((width+w)/2-25-bRadius/50+player.pos.x/50,(height+w)/2-25-bRadius/50+player.pos.y/50,2.5)
socket.emit('data',{a:100,ID:player.ID,dir:player.dir,pos:{x:player.pos.x,y:player.pos.y},s:player.s,dC:player.c.dC,name:player.name,score:floor(player.score)})
alerts.forEach((x,i)=>{if(i<alerts.length-5)x.a=0});alerts=alerts.filter(x=>x.a>0);q='';for(let a of alerts){a.a-=1/50;q+=a.m+'\n'}alerts=alerts.filter(x=>x.a>0);push()
textAlign(CENTER,BOTTOM);fill(0);stroke(0,0,0,0);textSize(15);text(q,width/2,(height+w)/2);pop()
if(located > 0){located-=1}
push();textAlign(CENTER,CENTER);fill(0,0,0,located);stroke(0,0,0,0);textSize(20);text('Someone located you!',width/2,(height-w)/2+20);pop()
if(located > 215){background(0,0,0,(located-215)*(255/40))}
fill(255);stroke(0,0,0,0);rect(0,0,(width-w)/2,height);rect(0,0,width,(height-w)/2);rect(width,height,-(width-w)/2,-height);rect(width,height,-width,-(height-w)/2)
q=player;a=player.score;ships.forEach((s,i)=>{if(s.score>a){a=s.score;q=s}});push();textAlign(LEFT,TOP);fill(0);stroke(0,0,0,0)
q1='---';a1='---';[...ships,player].filter(x=>x.ID!=q.ID).forEach((s,i)=>{if(s.score>a1||a1=='---'){a1=s.score;q1=s}});if(a1!='---')a1=floor(a1).toString()
if(q1=='---')q1={name:'---',ID:0};q2='---';a2='---';[...ships,player].filter(x=>x.ID!=q.ID).filter(x=>x.ID!=q1.ID).forEach((s,i)=>{if(s.score>a2||a2=='---'){a2=s.score;q2=s}})
if(q2=='---')q2={name:'---'};if(a2!='---')a2=floor(a2).toString();text('Your highscore: '+floor(highscore).toString()+'\n\nLeaderboard:\n #1: "'+q.name+'" at '+
floor(a).toString()+' points'+'\n\n #2: "'+q1.name+'" at '+a1+' points'+'\n\n #3: "'+q2.name+'" at '+a2+' points',10+(width-w)/2,10+(height-w)/2);pop()
let t='Players in your team:\n';for(let s of ships){if(team(s.name)==team(player.name)&&player.name.split(':').length>1){t+=(team(s.name,true)+'\n')}}push();textAlign(RIGHT,TOP)
fill(0);stroke(0,0,0,0);text(t,(width+w)/2-10,(height-w)/2+10);pop()
if(keyCode==32&&abs(mouseX-width/2)<w/2&&abs(mouseY-height/2)<w/2&&player.c.c>=1){z=[];shipData.forEach((s,i)=>{if(i!=player.s){z.push(i)}});player.s=z[floor(random(0,z.length))]
if(key=='a'){x={n:player.name,m:prompt('Message...','Hi')||'Hi',to:prompt('To...','[ALL]')||'[ALL]'}
socket.emit('chat',{n:player.name,m:x.m,to:x.to})
qalert('You said: '+x.m.replaceAll('\n',''),5)}
if(key=='c'){q=player.name;player.name=prompt('New username...').replaceAll(',','');while(player.name==''){
player.name=prompt('New username...').replaceAll(',','').replaceAll('\n','')}socket.emit('globalqalert',q+' changed their name to '+player.name)
qalert('You changed your name to '+player.name,5)}
if(key=='d')socket.emit('kick',prompt('Player to kick'),player.name)
function mouseReleased(){
if(player.c.c>=1&&mouseButton==CENTER&&abs(mouseX-width/2)<w/2&&abs(mouseY-height/2)<w/2){z=[];shipData.forEach((s,i)=>{if(i!=player.s){z.push(i)}})
player.s=z[floor(random(0,z.length))];player.c.c-=1}
function windowResized(){resizeCanvas(windowWidth-20,windowHeight-20);w=floor(min(width-20,height-20)/100)*100}
function qalert(m,s){alerts.push({m:m,a:s})}
function Noise(x,y,z){return 15*(max(noise(x+bRadius*2,y+bRadius*2,z),0.5)-0.5)}
function team(x,b=false){try{if(x.split(':').length==1&&x.split(':').length>1){return 'default'}if(b){if(x.split(':').length>1){t=x.split(':');t.pop();t.join(':');return t.toString()}else{return x}}else{t=x.split(':');return t[t.length-1].toString()}}catch(e){console.log(x)}}
function circleArcIntersect(e){q=createVector(e.c.x-e.a.x,e.c.y-e.a.y).mult(2);if(q.mag()>e.c.r+e.a.r||q.mag()<e.a.r-e.c.r){return false}m=e.a.a1-q.heading();if(m<0)m+=Math.PI*2;if(m<e.a.a/2||m>Math.PI*2-e.a.a/2){return true}else{return false}}