Page MenuHomePhabricator

No OneTemporary

diff --git a/scripts/functions-body.js b/scripts/functions-body.js
index 04a3220..8b2daec 100644
--- a/scripts/functions-body.js
+++ b/scripts/functions-body.js
@@ -1,447 +1,447 @@
/*
* 3DCycles - A lightcycle game.
* Copyright (C) 2019 Glen Harpring
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
function getPlayer(name)
{
name = removeColors(name).filter();
var matches = [];
for(var i=engine.players.length;i--;)
{
if(engine.players[i].getBoringName().filter() == name)
{
return engine.players[i];
}
else if(engine.players[i].getBoringName().filter().indexOf(name) > -1)
{
matches.push(i);
}
}
if(matches.length > 1)
{
engine.console.print("Too many matches for "+name+". Try something more exact to narrow down the search.\n");
}
else if(matches.length < 1)
{
engine.console.print("No matches for "+name+". Try a different name.\n");
}
else
{
return engine.players[matches[0]];
}
}
function retToLastSafe(cycle,w1x,w1y,w2x,w2y)
{
var dist = distanceoflines(cycle.position.x,cycle.position.y,cycle.position.x,cycle.position.y,w1x,w1y,w2x,w2y);
console.warn(cycle.name+" phased through a wall "+dist+"m.\n");
//if(dist == 0) return;
dist -= settings.CYCLE_RUBBER_MINDISTANCE;
cycle.position.x -= cycle.lastdir.front[0]*dist; cycle.position.y -= cycle.lastdir.front[1]*dist;
if(lineIntersect(cycle.position.x,cycle.position.y,cycle.lastpos.x,cycle.lastpos.y,w1x,w1y,w2x,w2y))
{
//cycle.position.x += cycle.lastdir.front[0]*(dist*2); cycle.position.y += cycle.lastdir.front[1]*(dist*2);
//if(lineIntersect(cycle.position.x,cycle.position.y,cycle.lastpos.x,cycle.lastpos.y,w1x,w1y,w2x,w2y))
{
var dist = distanceoflines(cycle.lastpos.x,cycle.lastpos.y,cycle.lastpos.x,cycle.lastpos.y,w1x,w1y,w2x,w2y);
dist -= settings.CYCLE_RUBBER_MINDISTANCE;
cycle.position.x = cycle.lastpos.x+
(cycle.lastdir.front[0]*dist)/*+
(cycle.lastsensor.left*cycle.lastdir.left[0])+
(cycle.lastsensor.right*cycle.lastdir.right[0])*/;
cycle.position.y = cycle.lastpos.y+
(cycle.lastdir.front[1]*dist)/*+
(cycle.lastsensor.left*cycle.lastdir.left[1])+
(cycle.lastsensor.right*cycle.lastdir.right[1])*/;
/*while(lineIntersect(cycle.position.x,cycle.position.y,cycle.lastpos.x,cycle.lastpos.y,w1x,w1y,w2x,w2y))
{
cycle.position.x -= (1/1000)*cycle.lastdir.front[0];
cycle.position.y -= (1/1000)*cycle.lastdir.front[1];
}
cycle.collidetime = 0; cycle.lastspeed = 0;*/
if(lineIntersect(cycle.position.x,cycle.position.y,cycle.lastpos.x,cycle.lastpos.y,w1x,w1y,w2x,w2y))
{
if(engine.network)
{
//request new cycle trails
}
else
{
doDeath(cycle);
engine.console.print(cycle.name+" phased through a wall and has been terminated.\n");
}
}
else
{
cycle.rubber += cycle.speed;
cycle.sensor.front = settings.CYCLE_RUBBER_MINDISTANCE;
}
}
}
else
{
cycle.rubber += cycle.speed;
cycle.sensor.front = settings.CYCLE_RUBBER_MINDISTANCE;
}
if(engine.haswall) recalcCurrWall(cycle);
}
function getCycleSensors(full=false)
{
var oneline = "";
var range = settings.CYCLE_SENSORS_RANGE;
for(var x=engine.players.length-1;x>=0;--x) if(engine.players[x] !== undefined)
{
//if(full)
{
engine.players[x].sensor.left = engine.players[x].sensor.right =
engine.players[x].sensor.leftTurn = engine.players[x].sensor.rightTurn =
engine.players[x].sensor.front =
engine.players[x].sensor.rear = Infinity;
engine.players[x].sensor.nearestobj =
engine.players[x].sensor.lnearestobj = false;
engine.players[x].sensor.rnearestobj = false;
}
engine.players[x].sensor.bottom = 0;
engine.players[x].sensor.frontWallHeight = Infinity;
engine.players[x].sensor.objleft =
engine.players[x].sensor.objright =
engine.players[x].sensor.objfront =
engine.players[x].sensor.objrear = false;
engine.players[x].sensor.nearcycle = false;
engine.players[x].dir.front = cdir(engine.players[x].rotation.z);
engine.players[x].dir.left = cdir(engine.players[x].rotation.z+(Math.PI/2));
engine.players[x].dir.right = cdir(engine.players[x].rotation.z-(Math.PI/2));
engine.players[x].dir.leftTurn = cdir(engine.players[x].rotation.z+(Math.PI/(settings.ARENA_AXES*0.5)));
engine.players[x].dir.rightTurn = cdir(engine.players[x].rotation.z-(Math.PI/(settings.ARENA_AXES*0.5)));
}
- for(var x=engine.map.zones.length-1;x>=0;--x)
+ for(var x=engine.zones.children.length-1;x>=0;--x)
{
engine.zones.children[x].walldist = Infinity;
}
if(!engine.dedicated) var campos = engine.camera.position, ppos = engine.players[engine.viewTarget].position;
for(var y=engine.map.walls.length-1;y>=0;--y)
{
//console.log("ohi");
var lookThroughWall = false;
for(var i=engine.map.walls[y].length-1;i>=0;--i)
{
- var w1x = engine.map.walls[y][i][0], w1y = engine.map.walls[y][i][1];
+ var w1x = engine.map.walls[y][i][0], w1y = engine.map.walls[y][i][1], p=engine.map.walls[y][i+1];
- if(engine.map.walls[y][i+1] !== undefined)
+ if(p !== undefined)
{
- var w2x = engine.map.walls[y][i+1][0], w2y = engine.map.walls[y][i+1][1];
+ var w2x = p[0], w2y = p[1]/*,w2z = p[2]*/;
for(var x=engine.players.length-1;x>=0;--x) if(engine.players[x] !== undefined && engine.players[x].alive)
{
var cycle = engine.players[x];
var posx = cycle.position.x, posy = cycle.position.y, posz = cycle.position.z;
if(lineIntersect(posx,posy,cycle.lastpos.x,cycle.lastpos.y,w1x,w1y,w2x,w2y))
{
retToLastSafe(cycle,w1x,w1y,w2x,w2y);
}
else
{
var dir = engine.players[x].dir.front,
ldir = engine.players[x].dir.left,
rdir = engine.players[x].dir.right
ltdir = engine.players[x].dir.leftTurn,
rtdir = engine.players[x].dir.rightTurn;
var rg = /*cycle.sensor.front==Infinity?*/(cycle.speed*range);//:cycle.sensor.front;
//var output = pointLineDistance(w1x,w1y,w2x,w2y,posx,posy);
//var testx = (w2x-w1x)*dir[0], testy = (w2y-w1y)*dir[1], tpx = posx*(-dir[0]), tpy = posy*(-dir[1]);
//if(cycle == engine.players[engine.viewTarget]) oneline += ""+(w2x-w1x)+"\t\t\t\t\t\t\t"+posx+"\t\t\t\t\t\t\t"+(w2x-w1x)+"\t\t\t\t\t\t\t"+posy+";\n";
//if(((w2x+w1x)/2) >= posy*dir[0] && ((w2y+w1y)/2) >= posx*dir[1])
//if(isinfront(w1x,w1y,w2x,w2y,posx,posy,dir))
coord = [w1x,w1y,w2x,w2y];
if(lineIntersect(posx,posy,posx+(dir[0]*rg),posy+(dir[1]*rg),w1x,w1y,w2x,w2y))
{
//var ff = distanceoflines(posx,posy,posx+(dir[0]/6),posy+(dir[1]/6),w1x,w1y,w2x,w2y);
var ff = distanceoflines(posx,posy,posx,posy,w1x,w1y,w2x,w2y);
/*forward = Math.min(forward,ff);
if(ff == forward) type = "rim";//*/
if(ff < cycle.sensor.front) { cycle.sensor.front=ff; cycle.sensor.nearestobj = "rim";}
}
else if(lineIntersect(posx,posy,posx+(ldir[0]*rg),posy+(ldir[1]*rg),w1x,w1y,w2x,w2y))
{
var ll = distanceoflines(posx,posy,posx,posy,w1x,w1y,w2x,w2y);
if(ll < cycle.sensor.left) { cycle.sensor.left=ll; cycle.sensor.lnearestobj = "rim";}
}
else if(lineIntersect(posx,posy,posx+(rdir[0]*rg),posy+(rdir[1]*rg),w1x,w1y,w2x,w2y))
{
var rr = distanceoflines(posx,posy,posx,posy,w1x,w1y,w2x,w2y);
if(rr < cycle.sensor.right) { cycle.sensor.right=rr; cycle.sensor.rnearestobj = "rim";}
}
if(lineIntersect(posx,posy,posx+(ltdir[0]*rg),posy+(ltdir[1]*rg),w1x,w1y,w2x,w2y))
{
var ll = distanceoflines(posx,posy,posx,posy,w1x,w1y,w2x,w2y);
if(ll < cycle.sensor.leftTurn) { cycle.sensor.leftTurn=ll; }
}
else if(lineIntersect(posx,posy,posx+(rtdir[0]*rg),posy+(rtdir[1]*rg),w1x,w1y,w2x,w2y))
{
var rr = distanceoflines(posx,posy,posx,posy,w1x,w1y,w2x,w2y);
if(rr < cycle.sensor.rightTurn) { cycle.sensor.rightTurn=rr;}
}
/*
if(((w2x+w1x)/2) >= posy*ldir[0] && ((w2y+w1y)/2) >= posx*ldir[1])
{
var ll = distanceoflines(posx,posy,posx+(ldir[0]),posy+(ldir[1]),w1x,w1y,w2x,w2y);
left = Math.min(left,ll);
}
if(((w2x+w1x)/2) >= posy*rdir[0] && ((w2y+w1y)/2) >= posx*rdir[1])
{
var rr = distanceoflines(posx,posy,posx+(rdir[0]),posy+(rdir[1]),w1x,w1y,w2x,w2y);
right = Math.min(right,rr);
}
*/
}
}
- for(var x=engine.map.zones.length-1;x>=0;--x)
+ for(var x=engine.zones.children.length-1;x>=0;--x)
{
- var zone = engine.map.zones[x];
- var posx = zone[1], posy = zone[2],w2z = p[2]*1;
- var walldist = distanceoflines(posx,posy,posx,posy,w1x,w1y,w2x,w2y)-zone[3];
- if(walldist < engine.zones.children[x].walldist)
+ var zone = engine.zones.children[x];
+ var posx = zone.position.x, posy = zone.position.y;
+ var walldist = distanceoflines(posx,posy,posx,posy,w1x,w1y,w2x,w2y)-zone.cfg.radius;
+ if(walldist < zone.walldist)
{
- engine.zones.children[x].walldist = walldist;
+ zone.walldist = walldist;
}
}
if(!engine.dedicated && !lookThroughWall) lookThroughWall = (engine.walls.children[y]&&engine.walls.children[y].geometry.vertices[engine.walls.children[y].geometry.vertices.length-1].z) > campos.z && lineIntersect(campos.x,campos.y,ppos.x,ppos.y,w1x,w1y,w2x,w2y);
}
}
if(!engine.dedicated && engine.walls.children[y]) engine.walls.children[y].visible = !lookThroughWall;
}
for(var a=engine.players.length-1;a>=0;--a) if(engine.players[a] !== undefined)
{
var walls = engine.players[a].walls.map;
var len = walls.length;
for(var i=len-1;i>=0;--i)
{
var p1 = walls[i];
//var w1x = p1[0],w1y = p1[1],w1z = p1[2];
if(walls[i+1] !== undefined)
{
var p2 = walls[i+1];
//var w2x = p2[0],w2y = p2[1],w2z = p2[2];
for(var x=engine.players.length-1;x>=0;--x) if(engine.players[x] !== undefined && engine.players[x].alive)
{
//var cycle = engine.players[x];
//var isplayer = (engine.players[a] == engine.players[x]);
if(engine.players[a] != engine.players[x] || i <= len-(settings.ARENA_AXES))
{
//var posx = engine.players[x].position.x, posy = engine.players[x].position.y, posz = engine.players[x].position.z;
if(p1[2]||0 <= engine.players[x].position.z && (p1[2]||0)+1 >= engine.players[x].position.z)
{
if(lineIntersect(engine.players[x].position.x,engine.players[x].position.y,engine.players[x].lastpos.x,engine.players[x].lastpos.y,p1[0],p1[1],p2[0],p2[1]))
{
retToLastSafe(engine.players[x],p1[0],p1[1],p2[0],p2[1]);
}
else
{
var dir = engine.players[x].dir.front,
ldir = engine.players[x].dir.left,
rdir = engine.players[x].dir.right,
ltdir = engine.players[x].dir.leftTurn,
rtdir = engine.players[x].dir.rightTurn;
//var rg = engine.players[x].sensor.front==Infinity?(engine.players[x].speed*range):engine.players[x].sensor.front;
//if(engine.players[x].sensor.front==Infinity)
var rg=engine.players[x].speed*range;//else var rg=engine.players[x].sensor.front;
//if(!(engine.players[x].position.x == p2[0] && engine.players[x].position.y == p2[1]))
{
if(lineIntersect(engine.players[x].position.x,engine.players[x].position.y,engine.players[x].position.x+(dir[0]*rg),engine.players[x].position.y+(dir[1]*rg),p1[0],p1[1],p2[0],p2[1]))
{
var ff=distanceoflines(engine.players[x].position.x,engine.players[x].position.y,engine.players[x].position.x,engine.players[x].position.y,p1[0],p1[1],p2[0],p2[1]);
/*forward = Math.min(forward,ff);
if(ff == forward) type = engine.players[x];//*/
if(ff < engine.players[x].sensor.front)
{
engine.players[x].sensor.front=ff;
engine.players[x].sensor.nearestobj = engine.players[a];
if(engine.players[a] != engine.players[x])
{
engine.players[x].sensor.lastnonselfobj = engine.players[a];
}
}
}
else if(lineIntersect(engine.players[x].position.x,engine.players[x].position.y,engine.players[x].position.x+(ldir[0]*rg),engine.players[x].position.y+(ldir[1]*rg),p1[0],p1[1],p2[0],p2[1]))
{
var ll = distanceoflines(engine.players[x].position.x,engine.players[x].position.y,engine.players[x].position.x,engine.players[x].position.y,p1[0],p1[1],p2[0],p2[1]);
if(ll < engine.players[x].sensor.left)
{
engine.players[x].sensor.left=ll;
engine.players[x].sensor.lnearestobj = engine.players[a];
engine.players[x].sensor.objleft = engine.players[a];
}
}
else if(lineIntersect(engine.players[x].position.x,engine.players[x].position.y,engine.players[x].position.x+(rdir[0]*rg),engine.players[x].position.y+(rdir[1]*rg),p1[0],p1[1],p2[0],p2[1]))
{
var rr = distanceoflines(engine.players[x].position.x,engine.players[x].position.y,engine.players[x].position.x,engine.players[x].position.y,p1[0],p1[1],p2[0],p2[1]);
if(rr < engine.players[x].sensor.right)
{
engine.players[x].sensor.right=rr;
engine.players[x].sensor.rnearestobj =
engine.players[x].sensor.objright = engine.players[a];
}
}
else if(lineIntersect(engine.players[x].position.x,engine.players[x].position.y,engine.players[x].position.x+(-dir[0]*rg),engine.players[x].position.y+(-dir[1]*rg),p1[0],p1[1],p2[0],p2[1]))
{
var bb=distanceoflines(engine.players[x].position.x,engine.players[x].position.y,engine.players[x].position.x,engine.players[x].position.y,p1[0],p1[1],p2[0],p2[1]);
if(bb < engine.players[x].sensor.rear)
{
engine.players[x].sensor.rear=bb;
engine.players[x].sensor.objrear = engine.players[a];
}
}
if(lineIntersect(engine.players[x].position.x,engine.players[x].position.y,engine.players[x].position.x+(ltdir[0]*rg),engine.players[x].position.y+(ltdir[1]*rg),p1[0],p1[1],p2[0],p2[1]))
{
var ll = distanceoflines(engine.players[x].position.x,engine.players[x].position.y,engine.players[x].position.x,engine.players[x].position.y,p1[0],p1[1],p2[0],p2[1]);
if(ll < engine.players[x].sensor.leftTurn) { engine.players[x].sensor.leftTurn=ll;}
}
else if(lineIntersect(engine.players[x].position.x,engine.players[x].position.y,engine.players[x].position.x+(rtdir[0]*rg),engine.players[x].position.y+(rtdir[1]*rg),p1[0],p1[1],p2[0],p2[1]))
{
var rr = distanceoflines(engine.players[x].position.x,engine.players[x].position.y,engine.players[x].position.x,engine.players[x].position.y,p1[0],p1[1],p2[0],p2[1]);
if(rr < engine.players[x].sensor.rightTurn) { engine.players[x].sensor.rightTurn=rr;}
}
}
}
}
}
}
}
}
}//*/
/*for(var x=engine.map.zones.length-1;x>=0;--x)
{
var zone = engine.map.zones[x];
for(var y=engine.players.length-1;y>=0;--y) if(engine.players[y] !== undefined)
{
var ff = Math.sqrt(((zone[1]-p2x)**2)+((zone[2]-p2y)**2))-zone[3];
if(ff < cycle.sensor.front) { cycle.sensor.front=ff; cycle.sensor.nearestobj = "zone"; }
}
}*/
//console.log(forward);
if(oneline != "") console.log(oneline);
for(var x=engine.players.length-1;x>=0;--x) if((cycle=engine.players[x]) !== undefined && cycle.lastpos)
{
cycle.lastpos.x = cycle.position.x;
cycle.lastpos.y = cycle.position.y;
cycle.lastpos.z = cycle.position.z;
engine.players[x].lastdir = {
front:engine.players[x].dir.front,
left:engine.players[x].dir.left,
right:engine.players[x].dir.right
};
engine.players[x].lastsensor = {
front:engine.players[x].sensor.front,
left:engine.players[x].sensor.left,
right:engine.players[x].sensor.right
};
cycle.intersectTest = [];
}
}
function maxSpeed()
{
if(settings.CYCLE_SPEED_DECAY_ABOVE > 0 )
var max_cs = settings.CYCLE_SPEED / settings.CYCLE_SPEED_DECAY_ABOVE;
else
var max_cs = settings.CYCLE_SPEED * 100;
var max_fastest = engine.fastestSpeed; //
return Math.max(max_cs,max_fastest);
}
function handleChat(cycle,output)
{
var split = output.split(" ");
/*if(split[0][0] == "/")
{
switch(split[0])
{
case "/console": case "/admin":
if(!engine.dedicated || split[0] != "/console")
{
split.shift();
loadcfg(split.join(" "));
break;
}
default:
if(engine.network)
{
}
else
{
engine.console.print('Unknown chat command "'+split[0]+'".\n');
}
break;
}
}*/
if(split[0] == "/console" && !engine.dedicated)
{
split.shift();
loadcfg(split.join(" "));
}
else if(split[0] == "/admin" && !engine.network)
{
split.shift();
var ln = split.join(" ");
loadcfg(ln);
engine.console.print('Remote admin command0x7f7fff: '+ln+'\n');
}
else
{
cycle.doChat(output);
}
}
if(typeof(document) == "undefined")
{
function centerMessage(msg,time=5000)
{
console.log(msg);
if(window.svr)
{
if(time == Infinity) time = Number.MAX_VALUE;
var data = JSON.stringify({type:"cen",data:{msg:msg,time:time}});
window.svr.clients.forEach(function(ws){ws.send(data);});
}
}
}
else
{
function centerMessage(msg,time=5000)
{
var cm = document.getElementById("centerMessage");
cm.innerHTML = replaceColors(htmlEntities(msg));
cm.style.opacity = 1;
cm.style.display = "block";
engine.cMFadeOutAfter = performance.now()+time;
}
}
function toLadderLog(event,params)
{
if(settings["LADDERLOG_WRITE_"+event])
{
}
}
diff --git a/scripts/game.js b/scripts/game.js
index af60710..951b9c6 100644
--- a/scripts/game.js
+++ b/scripts/game.js
@@ -1,1083 +1,1083 @@
/*
* 3DCycles - A lightcycle game.
* Copyright (C) 2019 Glen Harpring
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
function doNewRound()
{
if(engine.uRound !== false) { clearTimeout(engine.uRound); engine.uRound = false; }
endRound();
setTimeout(newRound,engine.dedicated?300:0); //give clients an opportunity to sync their data
}
function endRound()
{
if(window.svr)
{
window.svr.clients.forEach(function(ws){ws.send('{"type":"endRound"}')});
window.svr.clients.forEach(function(ws){ws.send('{"type":"syncdata","gtime":-4000}')});
}
if(ctx)
{
audioStop();
if(settings.SOUNDS_EXTRO) playSound(bufferLoader.bufferList[bufferLoader.other+2],0.5,1,false,ctx.destination);
}
engine.roundCommencing = true;
//engine.hud.hide();
if(engine.hud) engine.hud.game.style.opacity = 0;
engine.console.print("Deleting objects...\n",false);
if(!engine.network)
{
if(settings.ROUND_CENTER_MESSAGE != "")
{
centerMessage(settings.ROUND_CENTER_MESSAGE);
}
}
engine.gtime = -4000;
for(var x=engine.players.length-1;x>=0;--x) if(typeof(engine.players[x]) != "undefined")
{
engine.players[x].alive = false;
}
while(engine.scene.children.length > 0)
{
engine.scene.remove(engine.scene.children[0]);
}
//if(!engine.network) engine.players.splice(0);
}
function endGame()
{
endRound();
engine.players.splice(0);
engine.round = 0;
}
function playGame()
{
engine.playGame = true;
if(!engine.scene)
{
init();
}
else
{
engine.paused = false;
if(engine.hud) engine.hud.show();
}
hideMenu(); newRound();
engine.inputState = 'game'; //change input state to accept game controls
if(engine.network)
{
document.getElementById("progtitle").innerHTML = tStringify("@progtitleshort@ &bull; Playing online");
}
else
{
document.getElementById("progtitle").innerHTML = tStringify("@progtitleshort@ &bull; Playing locally");
}
}
function revertMap()
{
var mapfile = settings.RESOURCE_REPOSITORY_CACHE+(settings.MAP_FILE.replace(/\(.+\)/,""));
engine.console.print("Downloading map from "+mapfile+"...\n",false);
httpGetAsync(mapfile,loadRound,function()
{
engine.console.print("Unable to load map file. Ignoring for now...",false);
loadRound();
});
}
function newRound()
{
engine.roundCommencing = true;
/////////////LIGHTS
var light1 = new THREE.AmbientLight( 0x666666 ); // soft white light
engine.scene.add( light1 );
var light = new THREE.DirectionalLight( 0xffffff, 1 );
light.castShadow = true;
light.position.set( 4, 1, 0 );
engine.scene.add( light );
var light2 = new THREE.DirectionalLight( 0xffffff, 1 );
light2.castShadow = true;
light2.position.set( -4, -1, 0 );
engine.scene.add( light2 );
//////////end of lights
var aspectRatio = (window.innerWidth / window.innerHeight);
engine.camera = new THREE.PerspectiveCamera( settings.CAMERA_FOV, aspectRatio, settings.CAMERA_NEAR_RENDER, settings.CAMERA_FAR_RENDER );
engine.camera.userViewDir = false;
engine.camera.up = new THREE.Vector3(0,0,1); //Z is up, X and Y is l+r and b+f
//engine.camera.position.set(247, 247, 3);
engine.viewTarget = engine.activePlayer;
//engine.cameraOrbit = new THREE.OrbitControls(engine.camera);
//engine.cameraOrbit.maxDistance = 400;
//BELOW THIS LINE DEPENDS ON GAME TYPE
//MAP
var maps = settings.MAP_ROTATION.split(";");
if(settings.ROTATION_TYPE > 0)
{
switch(settings.ROTATION_TYPE)
{
case 1:
engine.currrot += 1;
break;
case 2: // when matches are implemented
if(engine.rounds == 0) engine.currrot += 1;
break;
}
if(engine.currrot > maps.length) engine.currrot = 0;
settings.MAP_FILE = maps[engine.currrot];
}
if(settings.MAP_FILE != "" && settings.MAP_FILE != engine.loadedMap)
{
var mapfile = settings.RESOURCE_REPOSITORY_SERVER+(settings.MAP_FILE.replace(/\(.+\)/,""));
engine.console.print("Downloading map from "+mapfile+"...\n",false);
httpGetAsync(mapfile,loadRound,revertMap);
//loadRound(httpGet(mapfile));
}
else
{
loadRound();
}
}
function teamColor(id)
{
id += 1;
if(settings["TEAM_NAME_"+id])
{
return new THREE.Color(settings["TEAM_RED_"+id]/15,settings["TEAM_GREEN_"+id]/15,settings["TEAM_BLUE_"+id]/15);
}
return new THREE.Color();
}
function createAIsettings()
{
var AI_NUM = 1;
for(var z=engine.players.length-1;z>=0;--z) if(engine.players[z] && engine.players[z].AI) {AI_NUM++;}
var cycleColor = [0x000000,0xff0000,0x00ff00,0x0000ff][Math.round(Math.random()*3)];
var tailColor = [0x0000ff,0xff0000,0xffff00,0x00ff00][Math.round(Math.random()*3)];
if(!settings.ALLOW_TEAM_NAME_COLOR) { cycleColor = tailColor = teamColor(1); }
var colorcode = cycleColor.toString(16);
colorcode = ("0".repeat(6-colorcode.length))+colorcode;
var cycleinfo = { ai:true,
cycleColor:cycleColor, tailColor:tailColor,
/*engineType: 5,*/ engineType:(settings.players[0])?settings.players[0].engineType:5, spectating:false,
name: settings.AI_DUAL_COLOR_NAME?'AI0x'+colorcode+'#'+AI_NUM:'AI#'+AI_NUM
};
return cycleinfo;
}
function calculateSpawn(x)
{
var spawnslength = engine.map.spawns.length;
if(!engine.map.spawns[x])
{
var mult = Math.floor((x/spawnslength));
var currspawn = x-(spawnslength*mult);
var alt = (mult/2 != Math.floor(mult/2));
console.log(mult);
if(alt) mult = -Math.ceil(mult/2)
else mult = mult/2
console.log(mult,currspawn);
var spawns = JSON.parse(JSON.stringify(engine.map.spawns[Math.min(currspawn,(spawnslength-1))]||[]));
spawns[0] -= mult*settings.SPAWN_WINGMEN_SIDE;
spawns[1] -= Math.abs(mult)*settings.SPAWN_WINGMEN_BACK;
}
else
{
var spawns = engine.map.spawns[x];
}
return spawns;
}
function processPlayer(x,cfg)
{
var spawns = calculateSpawn(x);
if(engine.players[x])
{
var cycle = engine.players[x];
cycle.engineType = (typeof(cfg)=="undefined")?5:cfg.engineType;
if(x == engine.activePlayer && !engine.dedicated)
{
var cycleColor = cfg.cycleColor,tailColor = cfg.tailColor;
if(!settings.ALLOW_TEAM_NAME_COLOR) { cycleColor = tailColor = teamColor(0); }
if(cycle.name != cfg.name)
{
var out = cycle.getColoredName()+"0x7fff7f renamed to ";
cycle.cycleColor = cycleColor;
cycle.tailColor = tailColor;
cycle.name = cfg.name;
engine.console.print(out+cycle.getColoredName()+"\n");
}
else
{
cycle.cycleColor = cycleColor;
cycle.tailColor = tailColor;
}
if(cycle.spectating != cfg.spectating)
{
cycle.spectating = cfg.spectating;
if(cycle.spectating)
{
engine.console.print(cycle.getColoredName()+"0xff7f7f left to spectator mode.\n");
}
else
{
engine.console.print(cycle.getColoredName()+"0x7fff7f entered from spectator mode.\n");
}
}
}
else
{
if(!settings.ALLOW_TEAM_NAME_COLOR) { cycleColor = tailColor = teamColor(1); }
}
}
else
{
cfg.x = spawns[0]; cfg.y = spawns[1]; cfg.z = spawns[2];
engine.players[x] = (new Player(cfg));
var cycle = engine.players[x];
if(cycle.spectating)
{
engine.console.print(cycle.getColoredName()+"0xff7f7f entered as spectator.\n");
}
else
{
engine.console.print(cycle.getColoredName()+"0x7fff7f entered the game.\n");
}
}
if(cycle.spectating)
{
cycle.team = null;
}
else if(!cycle.team)
{
if(engine.teams.length < settings.TEAMS_MAX)
{
engine.teams.push(cycle.team = new Team({name:cfg.name,x:spawns[0], y:spawns[1], z:spawns[2], dir:deg2rad(spawns[3])}));
}
else
{
var minPCount = 0, minPlayers = Infinity, minTeam;
for(var x=engine.teams.length-1;x>=0;--x)
{
if(engine.teams[x].members.length == minPlayers)
{
minPCount++;
if(minTeam.push)
{
minTeam.push(x);
}
else
{
minTeam = [minTeam,x];
}
}
else if(engine.teams[x].members.length < minPlayers)
{
minPlayers = engine.teams[x].members.length;
minTeam = x; minPCount = 1;
}
}
if(minPCount != 1)
{
minTeam = Math.floor(Math.random()*minTeam.length);
}
cycle.team = engine.teams[minTeam];
}
cycle.team.members.push(cycle);
}
}
function ensurePlayersSane(removeAIs=true)
{
var numAIs = 0, numPlay = 0, numSpec = 0, numWantPlay = 0;
for(var x=engine.players.length-1;x>=0;--x) if(engine.players[x])
{
if(engine.players[x].AI) numAIs++;
if(engine.players[x].spectating) numSpec++; else numPlay++;
//if(engine.players[x].spectating && !settings.players[x].spectating) numWantPlay++;
}
var numHuman = numPlay-numAIs;
if(removeAIs)
{
for(var x=settings.TEAMS_MAX;x<engine.teams.length;++x) if(engine.teams[x])
{
for(var i=engine.teams[x].members.length-1;i>=0;--i)
{
engine.console.print(engine.teams[x].members[i].getColoredName()+"0xff7f7f left to spectator mode.\n");
engine.teams[x].members[i].spectating = true;
}
}
engine.teams.splice(settings.TEAMS_MAX);
}
for(var x=settings.players.length-1;x>=0;--x) if(settings.players[x])
{
if(engine.players[x] && engine.players[x].AI)
{
engine.players[engine.players.length-1] = engine.players[x];
engine.players[x] = undefined;
}
if(!engine.players[x])
{
numPlay++; numHuman++;
}
processPlayer(x,settings.players[x]);
}
if(removeAIs)
{
console.log(numHuman);
var shouldAIs = Math.max(0,(settings.MIN_PLAYERS-numHuman));
if(!settings.AI_TEAM)
{
shouldAIs += (numHuman <= settings.SP_HUMANS_COUNT)?settings.SP_NUM_AIS:settings.NUM_AIS;
}
if(shouldAIs > numAIs)
{
var AIsToAdd = (shouldAIs-numAIs);
console.log(numAIs+" AIs in the game, adding "+AIsToAdd+".");
for(var x=AIsToAdd;x>0;--x)
{
var cycleinfo = createAIsettings();
processPlayer(engine.players.length,cycleinfo);
}
numAIs += AIsToAdd;
}
else if(numAIs != 0)
{
var AIsToDealWith = (numAIs-shouldAIs);
console.log(numAIs+" AIs in the game, removing "+AIsToDealWith+".");
if(AIsToDealWith != 0)
{
for(var x=engine.players.length-1;x>=0;--x) if(engine.players[x])
{
if(engine.players[x].AI)
{
engine.console.print(engine.players[x].getColoredName()+"0xff7f7f left the game.\n");
engine.players.splice(x,1);
AIsToDealWith--;
if(window.svr)
{
var data = JSON.stringify({type:"leave",data:x});
window.svr.clients.forEach(function(ws){ws.send(data)});
}
}
if(AIsToDealWith == 0) break;
}
}
}
//clean up teams / remove ghost teams
for(var x=engine.teams.length-1;x>=0;--x) if(engine.teams[x])
{
for(var i=engine.teams[x].members.length-1;i>=0;--i)
{
if(engine.players.indexOf(engine.teams[x].members[i]) == -1)
{
engine.teams[x].members.splice(i,1);
}
}
if(engine.teams[x].members.length == 0)
{
engine.teams.splice(x,1);
}
else
{
engine.teams[x].spawn(false,false); //and finally spawn everyone
}
}
if(!engine.dedicated && !engine.players[engine.activePlayer].alive) changeViewTarget(1);
}
if(window.svr) window.svr.clients.forEach(function(ws){ws.senddata(0)});
}//*/
function loadRound(dlmap)
{
if(typeof(dlmap) != "undefined")
{
engine.mapString = dlmap;
engine.loadedMap = settings.MAP_FILE;
}
engine.mapXML = xmlify(engine.mapString);
engine.console.print("Creating objects...\n",false);
if(window.svr) window.svr.clients.forEach(function(ws){ws.send('{"type":"newRound"}')});
//virtual map data (used for positions, lines and stuff to calculate)
engine.map = {zones:[],spawns:[],walls:[]};
engine.expl = []; engine.deaths = 0;
engine.winzone = false;
//GRID
buildGrid();//buildObjects.js
engine.scene.add(engine.grid);
//WALLS
buildWalls();//buildObjects
engine.scene.add(engine.walls);
//ZONES
buildZones();
engine.scene.add(engine.zones);
if(settings.SOUNDS_INTRO)
playSound(bufferLoader.bufferList[bufferLoader.other+1],0.5,1,false,ctx.destination);
if(settings.ROUND_CONSOLE_MESSAGE != "")
{
engine.console.print(settings.ROUND_CONSOLE_MESSAGE+"\n");
}
loadcfg(settings.ROUND_COMMAND.replace(/\\n/g,"\n"));
//GAME
engine.gtime = -4000;
//PLAYERS
//CYCLE
if(!engine.network)
{
ensurePlayersSane();
if(engine.round == 0)
{
engine.console.print("Resetting scores...\n");
for(var x=engine.players.length-1;x>=0;--x) if(engine.players[x])
{
engine.players[x].score = 0;
}
}
engine.round++;
engine.console.print("Go (round "+engine.round+" of "+settings.LIMIT_ROUNDS+")!\n");
}
if(!engine.camera)
{
var aspectRatio = (window.innerWidth / window.innerHeight);
engine.camera = new THREE.PerspectiveCamera( settings.CAMERA_FOV, aspectRatio, settings.CAMERA_NEAR_RENDER, settings.CAMERA_FAR_RENDER );
engine.camera.up = new THREE.Vector3(0,0,1); //Z is up, X and Y is l+r and b+f
}
engine.camera.position.set(engine.logicalBox.center.x*engine.REAL_ARENA_SIZE_FACTOR,engine.logicalBox.center.y*engine.REAL_ARENA_SIZE_FACTOR,3);
try{engine.camera.lookAt( new THREE.Vector3(engine.players[engine.viewTarget].position.x,engine.players[engine.viewTarget].position.y,engine.player[engine.viewTarget].position.z) );}
catch(e){engine.camera.lookAt( new THREE.Vector3(engine.logicalBox.center.x*engine.REAL_ARENA_SIZE_FACTOR,engine.logicalBox.center.y*engine.REAL_ARENA_SIZE_FACTOR,0) );}
updateScoreBoard();
engine.lastGameTime = engine.lastRenderTime = engine.fpsTime = engine.timeStart = performance.now();
engine.totalPauseTime = 0;
engine.fastestPlayer = engine.fastestSpeed = 0;
engine.timemult = 1;
engine.asendtm = 0;
engine.winner = undefined;
engine.roundCommencing = false;
getGoing();
}//end of init main
function game(oneoff=false)
{
if(!engine.roundCommencing && !engine.paused)
{
if(engine.network)
{
var cycle = engine.players[engine.activePlayer],data={},len=0;
if(cycle.braking != cycle.brakingPrev) {data.braking=cycle.braking; cycle.brakingPrev=cycle.braking; ++len;}
if(cycle.boosting != cycle.boostingPrev) {data.boosting=cycle.boosting; cycle.boostingPrev=cycle.boosting; ++len;}
if(len > 0)
{
engine.connection.send(JSON.stringify({type:"playdata",data:data}));
}
}
if(!oneoff && settings.GAME_LOOP != 1) {setTimeout(game,1000/settings.DEDICATED_FPS); engine.gameRunning = true;}
//time handlers and delta
var timenow = performance.now()/settings.TIME_FACTOR;
var rDelta = (timenow-engine.lastGameTime);
if(rDelta > settings.TIMESTEP_MAX*1000 && engine.gtime > 0)
{
var more = true;
rDelta = settings.TIMESTEP_MAX*1000;
//engine.timeStart += rDelta;
} else var more = false;
var delta = rDelta*engine.timemult;
var timestep = delta/1000;
engine.totalPauseTime += (timenow-engine.lastGameTime)-delta;
engine.lastGameTime += rDelta;
engine.avgTimeStep += rDelta/1000; engine.avgTimeStep /= 2;
if(!engine.network && !engine.dedicated) engine.players[0].ping = parseInt(engine.avgTimeStep*1000)
//if(!engine.network && timestep > engine.avgTimeStep*10 && rDelta == delta) {engine.totalPauseTime += timestep; console.log("Compensated skip of "+delta+"ms."); timestep = engine.avgTimeStep;}
engine.timemult += (engine.asendtm*timestep);
if(engine.timemult > 100) engine.timemult = 100;
//var timeElapsed = timenow-engine.timeStart-engine.totalPauseTime-4000;
//skipping ahead at the beginning of the round is silly
//engine.gtime = timeElapsed;
var timeElapsed = (engine.gtime += delta);
if(!engine.thread_collisiondetect && (settings.GAME_LOOP != 0.5 || !oneoff)) getCycleSensors();
var pldata = {};
for(var x=engine.players.length-1;x>=0;--x) if(engine.players[x])
{
var cycle = engine.players[x];
if(cycle.alive)
{
if(cycle.newPos) doNetSlide(cycle,timestep);
if(timeElapsed > 0)
{
if(x == engine.activePlayer)
{
if(settings.HACK_TURN_LEFT_WHEN_POSSIBLE > 0)
{
if(cycle.sensor.left > settings.HACK_TURN_SENSOR_DIST)
{
cycle.turn(-1);
settings.HACK_TURN_LEFT_WHEN_POSSIBLE--;
}
}
if(settings.HACK_TURN_RIGHT_WHEN_POSSIBLE > 0)
{
if(cycle.sensor.right > settings.HACK_TURN_SENSOR_DIST)
{
cycle.turn(1);
settings.HACK_TURN_RIGHT_WHEN_POSSIBLE--;
}
}
}
//bot turning
if(cycle.AI)
{
cycle.AI.think(timestep);
}
else if(x==engine.activePlayer && (cycle.chatting || settings.CHATBOT_ALWAYS_ACTIVE))
{
if(timenow > cycle.lastTurnTime+(settings.CYCLE_DELAY*1000) && cycle.sensor.front < Math.min(5,cycle.sensor.left,cycle.sensor.right))
{
if(cycle.sensor.right < cycle.sensor.left) cycle.turn(-1);
else if(cycle.sensor.right > cycle.sensor.left) cycle.turn(1);
else cycle.turn([-1,1][Math.round(Math.random()*1)]);
}
}
//do turning
//if(cycle.turnQueue.length > 0)
{
//if(cycle.turnQueue.length > 0 && x == 0)console.log(JSON.parse(JSON.stringify(cycle.turnQueue)));
if(cycle.turnQueue.length > settings.CYCLE_TURN_MEMORY) cycle.turnQueue.splice(0,cycle.turnQueue.length-settings.CYCLE_TURN_MEMORY);
var shouldTime = cycle.lastTurnTime+(settings.CYCLE_DELAY*1000);
if(cycle.turnQueue.length > 0 && timeElapsed >= shouldTime/*-delta*/)
{
//allow the cycle to turn when it should (???)
//var diff = (shouldTime-timeElapsed)/1000;
//cycle.update(diff);
if(settings.CYCLE_MIDAIR_TURN || cycle.position.z-cycle.sensor.bottom == cycle.model.rotation.y)
{
var dir = cycle.turnQueue[0],dirmult;
var olddir = cdir(cycle.rotation.z);
cycle.dir.front = (dirmult = cdir(cycle.rotation.z -= (pi(2)/settings.ARENA_AXES)*dir));
//cycle.rotation.z = cycle.rotation.z%(Math.PI*2);
//if(cycle.rotation.z < 0) cycle.rotation.z += Math.PI*2;
cycle.rotation.z = normalizeRad(cycle.rotation.z);
cycle.speed *= settings.CYCLE_TURN_SPEED_FACTOR;
cycle.rotation.x = Math.cos(cycle.rotation.z)*0.4*dir; //tilts the cycle
cycle.rotation.y = Math.sin(cycle.rotation.z)*0.4*dir;
//if(settings.GRAB_SENSORS_ON_TURN)
{
getCycleSensors(true);
}
cycle.collidetime = timeElapsed+(((cycle.sensor.front)/cycle.speed)*1000);
var mult = (1-settings.CYCLE_RUBBER_MINADJUST);
cycle.minDistance.front = Math.max(0,Math.min(cycle.sensor.front*mult,settings.CYCLE_RUBBER_MINDISTANCE));
cycle.lastpos = cycle.position.clone(); //redundant, should be handled by getCycleSensors
if(cycle.haswall) cycle.newWallSegment();
if(engine.network)
{
engine.connection.send(JSON.stringify({
type:"turn",data:rad2deg(cycle.rotation.z),gtime:cycle.gameTime,
position:[cycle.position.x,cycle.position.y,cycle.position.z],
speed:cycle.speed, rubber:cycle.rubber, brakes:cycle.brakes
}));
}
if(window.svr) //force a player sync
{
var data = JSON.stringify({type:"griddata",data:[{
position:[cycle.position.x,cycle.position.y,cycle.position.z],
direction:rad2deg(cycle.rotation.z),
speed:cycle.speed, rubber:cycle.rubber,
alive:cycle.alive,
netid:x, wall:cycle.walls.map,
}],gtime:engine.gtime});
window.svr.clients.forEach(function(ws){ws.send(data)});
}
}
cycle.turnQueue.splice(0,1);
cycle.lastTurnTime = timeElapsed;
}
}
cycle.update();
}
if(cycle.rubber > settings.CYCLE_RUBBER+0.0001)
cycle.rubber = settings.CYCLE_RUBBER+0.0001;
else if(cycle.rubber > 0)
cycle.rubber -= (timestep/settings.CYCLE_RUBBER_TIME)*cycle.rubber;
else
cycle.rubber = 0;
//if(timeElapsed/1000 > -3 && cycle.alive)
}
else if(cycle.walls.map.length != 0 && timenow-cycle.dedtime >= settings.WALLS_STAY_UP_DELAY*1000)
{
cycle.walls.map = [];
console.log("DELETE WALLS id "+x);
}
else if(settings.RESPAWN_TIME >= 0 && !cycle.alive && timenow-cycle.dedtime > settings.RESPAWN_TIME*1000)
{
cycle.spawn({x:cycle.position.x||0,y:cycle.position.y||0,z:cycle.position.z||0,dir:cycle.rotation.z||0});
}
}
if(timeElapsed > -3000 && timeElapsed < 1000)
{
//timer
var time=-timeElapsed/1000,gTime = Math.ceil(time);
if(gTime < 0) gTime = 0;
if(typeof(engine.timer)=="undefined" || engine.timer != gTime)
{
engine.timer = gTime;
if(engine.hud) engine.hud.fadein = true;
if(engine.dedicated) console.log(gTime);
else centerMessage(gTime,(gTime-time));
//engine.console.print(gTime+"\n");
}
}
else if(!engine.network && typeof(engine.winner) == "undefined")
{
checkForWinner();
}
if(!engine.network)
{
if(!engine.winzone && settings.WIN_ZONE_MIN_ROUND_TIME+engine.deaths*(settings.WIN_ZONE_MIN_LAST_DEATH) < timeElapsed/1000)
{
var zone = {expansion:settings.WIN_ZONE_EXPANSION};
if(settings.WIN_ZONE_DEATHS)
{
engine.console.print("Death zone activated. Avoid it!\n");
zone.type = "death";
}
else
{
engine.console.print("Win zone activated. Enter it to win the round.\n");
zone.type = "win";
}
zone.radius = Math.min(SMALL_NUM,settings.WIN_ZONE_INITIAL_SIZE)*engine.REAL_ARENA_SIZE_FACTOR;
zone.x = engine.REAL_ARENA_SIZE_FACTOR*(engine.logicalBox.center.x+(settings.WIN_ZONE_RANDOMNESS*(Math.random()-0.5)*2)*engine.logicalBox.center.x);
zone.y = engine.REAL_ARENA_SIZE_FACTOR*(engine.logicalBox.center.y+(settings.WIN_ZONE_RANDOMNESS*(Math.random()-0.5)*2)*engine.logicalBox.center.y);
new Zone(zone).spawn();
console.log("ZONE SPAWNED: "+zone.type);
engine.winzone = true;
}
}
for(var x=engine.zones.children.length-1;x>=0;--x)
{
var zone = engine.zones.children[x].cfg;
//zones expand
if(zone.radius > 0)
{
engine.zones.children[x].scale.x = engine.zones.children[x].scale.y = (zone.radius += zone.expansion*timestep*engine.REAL_ARENA_SIZE_FACTOR);
}
else if(zone.radius < 0) engine.zones.children[x].scale.x = engine.zones.children[x].scale.y = zone.radius = 0;
//zone effect
var inzone = false;
for(var y=engine.players.length-1;y>=0;--y) if(engine.players[y] && engine.players[y].alive)
{
var cycle = engine.players[y];
if(zone.type == "ball" || zone.type == "soccerball")
{
for(var z=engine.zones.children.length-1;z>=0;--z)
{
- var z2n = engine.map.zones[z];
+ var z2n = engine.zones.children[z].cfg;
if(
(
- (zone.type == "ball" && z2n[0] == "fortress") ||
- (zone.type == "soccerball" && z2n[0] == "soccergoal")
+ (zone.type == "ball" && z2n.type == "fortress") ||
+ (zone.type == "soccerball" && z2n.type == "soccergoal")
) &&
- is_in_circle(z2n[1],z2n[2],z2n[3],zone.x,zone.y,zone.radius))
+ is_in_circle(z2n.x,z2n.y,z2n.radius,zone.x,zone.y,zone.radius))
{
if(!engine.network && engine.winner == undefined)
{
centerMessage("0x00ff00Goal!");
startNewRound();
}
else
{
zone.xdir *= 1-timestep; zone.ydir *= 1-timestep;
}
}
}
}
//dont handle zones we don't need to
if(!zone.netObject || zone.type.indexOf("ball") >= 0)
{
//var lastdist = zone.distance(cycle.lastpos);
//var dist = zone.distance(cycle.position);
var lastdist = pointDistance(zone.mesh.position.x,zone.mesh.position.y,cycle.lastpos.x,cycle.lastpos.y)-zone.radius;
var dist = pointDistance(zone.mesh.position.x,zone.mesh.position.y,cycle.position.x,cycle.position.y)-zone.radius;
var inZone = (dist <= 0), wasInZone = (lastdist <= 0);
if(inZone)
{
var timediff = cycle.speed*dist;
var hitTime = timeElapsed-timediff;
if(!wasInZone) zone.onEnter(cycle,hitTime,timestep);
if(cycle.alive) zone.onInside(cycle,engine.gtime,timestep);
}
else if(wasInZone) //left zone
{
zone.onLeave(cycle,engine.gtime,timestep); //TODO: figure out "precise" left time
}
else
{
zone.onOutside(cycle,engine.gtime,timestep);
}
}
if(zone.type == "fortress") //fortress recover rate
{
zone.rotationSpeed += (settings.ZONE_SPIN_SPEED-zone.rotationSpeed)*timestep*settings.FORTRESS_CONQUEST_DECAY_RATE;
}
}
if(typeof(zone.xdir)+typeof(zone.ydir) !== "undefinedundefined")
{
- if(zone.bounce && zone.walldist <= timestep)
+ if(zone.bounce && zone.mesh.walldist <= timestep)
{
var mindirx,mindiry,mindist=Infinity,apc=0;
- var px = zone.x+(zone.walldist*zone.xdir), py = zone.y+(zone.walldist*zone.ydir);
+ var px = zone.mesh.position.x+(zone.mesh.walldist*zone.xdir), py = zone.mesh.position.y+(zone.mesh.walldist*zone.ydir);
for(var i=359;i>0;i--)
{
var xdir = Math.sin(Math.PI*2*(i/360)), ydir=Math.cos(Math.PI*2*(i/360));
- var xpos = xdir*zone.radius+zone.x, ypos=ydir*zone.radius+zone.y;
+ var xpos = xdir*zone.radius+zone.mesh.position.x, ypos=ydir*zone.radius+zone.mesh.position.y;
var dist = pointDistance(xpos,ypos,px,py);
if(dist < mindist)
{
//mindist += dist; mindirx += xdir; mindiry += ydir;
//apc++;
mindist=dist;mindirx=xdir;mindiry=ydir;apc=1;
}
}
//mindist /= apc; mindirx /= apc; mindiry /= apc;
var speed = Math.sqrt((zone.xdir*zone.xdir)+(zone.ydir*zone.ydir));
if(mindist != Infinity)
{
var angle = Math.atan2(mindiry,mindirx);
//var angle = Math.atan2(mindiry,mindirx)*2;
//var angle = Math.atan2(mindiry,mindirx)+(Math.PI/2);
//var angle = Math.PI-Math.atan2(mindiry,mindirx);
var dir = cdir(angle);
zone.xdir = dir[0]*speed; zone.ydir = dir[1]*speed;
- zone.x -= dir[0]*realzone.walldist; zone.y -= dir[1]*realzone.walldist;
- zone.x += dir[0]*speed*timestep; zone.y += dir[1]*speed*timestep;
+ zone.mesh.position.x -= dir[0]*zone.mesh.walldist; zone.mesh.position.y -= dir[1]*zone.mesh.walldist;
+ zone.mesh.position.x += dir[0]*speed*timestep; zone.mesh.position.y += dir[1]*speed*timestep;
console.log(zone);
}
else
{
zone.xdir *= -1; zone.ydir *= -1;
}
}
else
{
zone.mesh.position.x += zone.xdir*timestep; zone.mesh.position.y += zone.ydir*timestep;
}
}
}
var dc = Object.keys(engine.delayedcommands);
for(var x=dc.length-1;x>=0;x--)
{
var cmd = engine.delayedcommands[dc[x]];
loadcfg(cmd[0]);
if(dc[x] >= engine.gtime)
{
if(cmd[1] > 0)
{
engine.delayedcommands[dc[x]+cmd[1]] = cmd;
}
delete engine.delayedcommands[dc[x]];
}
}
//if(more) game();
}
else
{
engine.gameRunning = false;
}
}
function doDeath(cycle,escape=false)
{
if(escape || (cycle.sensor.nearestobj == "rim" && !cycle.sensor.lastnonselfobj))
{
if(escape || (
cycle.position.x-cycle.minDistance.front > engine.logicalBox.max.x ||
cycle.position.y-cycle.minDistance.front > engine.logicalBox.max.y ||
cycle.position.x+cycle.minDistance.front < engine.logicalBox.min.x ||
cycle.position.y+cycle.minDistance.front < engine.logicalBox.min.y
))
{
engine.console.print(cycle.getColoredName()+"0xRESETT tried to escape the game grid.\n");
}
else
{
engine.console.print(cycle.getColoredName()+"0xRESETT committed suicide.\n");
}
}
else
{
var objtoaccuse = typeof(cycle.sensor.lastnonselfobj)=="undefined"?cycle.sensor.nearestobj:cycle.sensor.lastnonselfobj;
if(objtoaccuse == cycle)
{
engine.console.print(cycle.getColoredName()+"0xRESETT committed suicide.\n");
}
else if(typeof(objtoaccuse) == "object")
{
engine.console.print(objtoaccuse.getColoredName()+"0xRESETT core dumped "+cycle.getColoredName()+"0xRESETT for 1 point.\n");
objtoaccuse.addScore(1);
}
else
{
engine.console.print(cycle.getColoredName()+"0xRESETT died.\n");
}
}
cycle.kill();
}
function simulatePlayer(cycle,timestep)
{
console.warn("Deprecated call to simulatePlayer");
cycle.update(timestep);
}
function getGoing()
{
if(!engine.gameRunning) game();
if(!engine.renderRunning) render();
}
function pauseRender()
{
engine.paused = true;//cuts off the loop
engine.startOfPause = performance.now();
audioStop();
}
function unpauseRender()
{
for(var ctrl in engine.controls)
{
engine.controls[ctrl] = [];
}
//renderLoop = true;//replaces cutoff
if(engine.paused)
{
engine.paused = false;
audioStart();
engine.lastGameTime = engine.lastRenderTime = engine.fpsTime = performance.now();//resets delta so we don't pretend the game should have been playing the entire time we were paused
var endOfPause = performance.now();
engine.totalPauseTime += (endOfPause - engine.startOfPause);
getGoing();//starts the loop again
}
}
function changeViewTarget(a=1,forcechange=false)
{
if(engine.dedicated) return;
if(a != 0)
{
if(!forcechange && engine.players[engine.activePlayer].alive) return;
var first = true; //force the loop to get started
var itcount = 0;
/*if(alive > 0) */while(first || !engine.players[engine.viewTarget] || !engine.players[engine.viewTarget].alive)
{
first = false;
engine.viewTarget+=a;
if(engine.viewTarget >= engine.players.length) engine.viewTarget = 0;
if(engine.viewTarget < 0) engine.viewTarget = engine.players.length+engine.viewTarget;
itcount++;
if(itcount > engine.players.length) break;
//console.log(engine.viewTarget);
}
}
if(engine.view == 'cockpit')
{
for(var x=0;x>engine.players.length;x++)
{
if(x == engine.viewTarget)
engine.players[x].audio.gain.setTargetAtTime(0.2, ctx.currentTime, 0.02);
else
engine.players[x].audio.gain.setTargetAtTime(6, ctx.currentTime, 1);
}
}
if(!engine.network && !engine.players[engine.activePlayer].spectating && typeof(engine.winner) == "undefined")
{
switch(settings.FINISH_TYPE)
{
case 2:
engine.asendtm = 0.2;
centerMessage("Time Warp!",Infinity);
if(engine.hud) engine.hud.fadein = false;
break;
case 3:
centerMessage("Please wait...",Infinity);
setTimeout(function()
{
engine.timemult = 100;
while(typeof(engine.winner) == "undefined") { game(true) }
engine.timemult = 1;
},100);
break;
}
}
engine.console.print("Watching "+engine.players[engine.viewTarget].name+"...\n");
}
function checkForWinner()
{
var alivecount = aliveaicount = 0;
var numPlay = 0;
var alive = [], theplayer = false;
var declareRoundWinner = typeof(engine.declareRoundWinner) != "undefined";
for(var x=engine.players.length-1;x>=0;--x) if(typeof(engine.players[x]) != "undefined")
{
if(!engine.players[x].spectating) numPlay++;
if(engine.players[x].alive)
{
alivecount++;
if(engine.players[x].AI)
aliveaicount++;
alive.push(engine.players[x]);
}
if(declareRoundWinner && engine.players[x].name == engine.declareRoundWinner)
{
engine.winner = engine.players[x];
engine.declareRoundWinner = undefined;
}
}
if(
(declareRoundWinner) ||
(settings.GAME_TYPE == 1 && numPlay > 1 && (alivecount <= 1 || (settings.FINISH_TYPE == 1 && aliveaicount == alivecount))) ||
(/*settings.GAME_TYPE == 0 && */(alivecount <= 0))
)
{
if(!declareRoundWinner)
{
engine.winner = (typeof(alive[0]) == "undefined")?{name:undefined}:alive[0];
}
if(settings.RIM_WALL_COLOR_MODE == 2)
{
if(engine.winner && settings.RIM_WALL_COLOR_MODE == 2)
{
var color = new THREE.Color(engine.winner.cycleColor);
settings.RIM_WALL_RED = color.r;
settings.RIM_WALL_GREEN = color.g;
settings.RIM_WALL_BLUE = color.b;
}
}
if(engine.asendtm > 0) {engine.asendtm = 0; engine.timemult = 1; centerMessage("Time Warp!",0);}
setTimeout(function(){centerMessage("Winner: "+engine.winner.name)},1000);
if(!window.svr || window.svr.clients.size != 0) startNewRound();
}//*/
/*if(aliveaicount == alivecount)
{
engine.console.print("Vroom!");
engine.timemult = 2;
engine.asendtm = 1.1;
}//*/
}
function startNewRound()
{
if(typeof(engine.winner) == "undefined") engine.winner = null;
var endin = 4000;
if(engine.round >= settings.LIMIT_ROUNDS)
{
var highscore = -Infinity, highplayer;
for(var x=engine.players.length-1;x>=0;--x) if(typeof(engine.players[x]) != "undefined")
{
var cycle = engine.players[x];
if(cycle.score > highscore)
{
highplayer = cycle;
highscore = cycle.score;
}
else if(cycle.score == highscore)
{
highplayer = null;
}
}
if(highplayer != null)
{
setTimeout(function(){centerMessage("Match Winner: "+highplayer.name);engine.console.print("Match Winner: "+highplayer.name+" with "+highscore+" points.\n")},4000);
}
engine.round = 0;
endin += 4000;
}
if(!settings.ROUND_WAIT) engine.uRound = setTimeout(doNewRound,endin);
}
function updateScoreBoard()
{
if(window.svr)
{
var tmp = [];
for(var x=engine.players.length-1;x>=0;--x) if(engine.players[x])
{
tmp.push({netid:x,score:engine.players[x].score,ping:engine.players[x].ping,chatting:engine.players[x].chatting});
}
var data = JSON.stringify({type:"scoredata",data:tmp});
window.svr.clients.forEach(function(ws){ws.send(data);});
}
if(engine.network)
{
engine.connection.send(JSON.stringify({type:"playdata",data:{chatting:engine.players[engine.activePlayer].chatting}}));
}
if(engine.dedicated || scoreboard.style.display == "none") return;
var scoreBoard = document.getElementById("scoreboard").children[0];
var playersSB = scoreBoard.children[1];
var tmp = "";
for(var x=0;x<engine.playersByScore.length;++x) if(typeof(engine.playersByScore[x]) != "undefined")
{
var cycle = engine.playersByScore[x];
tmp += "<tr class=\"player\"><td>"+(cycle.chatting?"*":"&nbsp;")+replaceColors(cycle.getColoredName())+"</td><td>"+replaceColors(cycle.alive?"0x00ff00Yes":"0xff0000No")+"</td><td>"+cycle.score+"</td><td>"+cycle.ping+"</td><td>"+(cycle.team?cycle.team.name:"")+"</td><tr>";
}
playersSB.innerHTML = tmp;
}
/*function updateScoreBoard()
{
var scoreboard = "";
for(var x=engine.players.length-1;x>=0;--x) if(typeof(engine.players[x]) != "undefined")
{
var cycle = engine.players[x];
scoreboard += (cycle.chatting?"*":" ")+removeColors(cycle.name)+" "+cycle.alive?"Yes":"No"+" "+cycle.score+" "+cycle.ping+" ";
}
}*/
diff --git a/scripts/zone.js b/scripts/zone.js
index 1412cdd..3a4f403 100644
--- a/scripts/zone.js
+++ b/scripts/zone.js
@@ -1,321 +1,321 @@
/*
* 3DCycles - A lightcycle game.
* Copyright (C) 2019 Glen Harpring
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
if(typeof(THREE) == "undefined") var THREE = require('./lib/Three.js');
var flagColors = [ 0x55AAFF, 0xFFFF55, 0xFF5555, 0x55FF55, 0xFF55FF, 0x55FFFF, 0xFFFFFF, 0x888888];
class Zone
{
spawn()
{
engine.zones.add(this.mesh);
return this;
}
destroy()
{
engine.zones.remove(this.mesh);
return this;
}
constructor(prop)
{
this.timesEntered = 0; this.netObject = false;
this.type = prop.type||"null";
this.rotationSpeed = isNaN(prop.rot)?settings.ZONE_SPIN_SPEED:prop.rot;
this.value = prop.value||0;
this.expansion = prop.expansion||0;
this.radius = prop.radius||0;
this.xdir = prop.xdir||0; this.ydir = prop.ydir||0;
this.bounce = !!prop.bounce;
this.team = false;
var zoneHeight = prop.height||settings.ZONE_HEIGHT;
if (settings.ZONE_SEGMENTS < 1) { settings.ZONE_SEGMENTS = 11; }
var zoneSegments = (Math.floor(this.radius/10)*10)+1;
if (zoneSegments < 11) { zoneSegments = 11; }
var zoneColor = 0xFFFFFF;
if(prop.color || prop.color === 0)
{
zoneColor = prop.color;
}
else
{
switch(this.type)
{
case "death": zoneColor = 0xFF0000; break;
case "soccerball": zoneColor = 0xFF8888; break;
case "soccergoal": zoneColor = 0xBB6666; break;
case "rubber": zoneColor = 0xFFB033; break;
case "rubberadjust": zoneColor = 0xFF8800; break;
case "oneway": zoneColor = 0xFFFF00; break;
case "win": zoneColor = 0x00FF00; break;
case "target": zoneColor = 0x00DD00; break;
case "teleport": zoneColor = 0x00AA00; break;
case "speed": zoneColor = 0x00FF88; break;
case "acceleration": zoneColor = 0x00BB66; break;
case "blast": zoneColor = 0x0088FF; break;
case "fortress": case "flag":
var lastDist = Infinity;
var closestSpawn = 0;
for(var w=0;w<engine.map.spawns.length;w++)
{
var checkx = engine.map.spawns[w][0];
var checky = engine.map.spawns[w][1];
var disValue = pointDistance( checkx, checky, prop.x, prop.y );
if (disValue < 0) { disValue = -disValue; }
if (disValue < lastDist) { lastDist = disValue; closestSpawn = w; }
}
if (closestSpawn > 7) { zoneColor = 0x4488FF; }
else { zoneColor = (this.type=="fortress"?teamColor:teamColor)(closestSpawn); }
this.team = closestSpawn;
break;
case "object": zoneColor = 0xBB0066; break;
case "checkpoint": zoneColor = 0xFF0088; break;
case "koh": zoneColor = 0xDDDDDD; break;
case "wall": case "ball": zoneColor = 0xFFFFFF; break;
case "switch": zoneColor = 0x999999; break;
}
}
var color = typeof(zoneColor)=="object"?zoneColor:new THREE.Color(zoneColor), geo = new THREE.Geometry();
switch(prop.shape)
{
case "polygon":
var min = [Infinity,Infinity],
max = [-Infinity,-Infinity];
for(var i=0;i<prop.points.length;i++)
{
var point = prop.points[i];
//point[0] += (1*prop.x)||0; point[1] += (1*prop.y)||0;
geo.vertices[i] = new THREE.Vector3(point[0],point[1],0);
geo.vertices[prop.points.length+i] = new THREE.Vector3(point[0],point[1],zoneHeight);
for(var z=1;z>=0;z--)
{
if(point[z] < min[z]) min[z] = point[z];
if(point[z] > max[z]) max[z] = point[z];
console.log(point[z]);
}
}
for(var i=0,halfvert=(geo.vertices.length/2)-1;i<halfvert;i++)
{
var p1x = geo.vertices[i].x, p1y = geo.vertices[i].y;
var p2x = geo.vertices[i+1].x, p2y = geo.vertices[i+1].y;
var dist = Math.sqrt( (p2x-=p1x)*p2x + (p2y-=p1y)*p2y );
var normal = new THREE.Vector3( (p2y - p1y), -(p2x - p1x), 0 );
geo.faces.push(
new THREE.Face3( (i), (i+1), (i+(geo.vertices.length/2)), normal ), //a,b,c
new THREE.Face3( (i+(geo.vertices.length/2)+1), (i+(geo.vertices.length/2)), (i+1), normal ) //d,c,b
);
}
//prop.x = (max[0]-min[0])/2; prop.y = (max[1]-min[1])/2;
//this.radius = (max[0]<max[1]?max[0]:max[1])-(min[0]>min[1]?min[0]:min[1]);
this.shape = "polygon";
break;
default: //circle
var zoneSegCoords = [];//get the coordinates for each segment vertex
var zoneSegMidpoints = [];//get midpoints for each segment
var trueSegments = [];
for (var i = 0; i < settings.ZONE_SEGMENTS; i++)
{
var zpx = Math.cos(2 * Math.PI * i / settings.ZONE_SEGMENTS);
var zpy = Math.sin(2 * Math.PI * i / settings.ZONE_SEGMENTS);
zoneSegCoords.push({x:zpx, y:zpy});
if (i > 0 && i != settings.ZONE_SEGMENTS-1) {//all segments starting from the second
zoneSegMidpoints[i] = { x:((zoneSegCoords[i-1].x+zoneSegCoords[i].x)/2), y:((zoneSegCoords[i-1].y+zoneSegCoords[i].y)/2) };
}
else if (i == settings.ZONE_SEGMENTS-1) {//last segment + first
zoneSegMidpoints[i] = { x:((zoneSegCoords[i-1].x+zoneSegCoords[i].x)/2), y:((zoneSegCoords[i-1].y+zoneSegCoords[i].y)/2) };
zoneSegMidpoints[0] = { x:((zoneSegCoords[0].x+zoneSegCoords[i].x)/2), y:((zoneSegCoords[0].y+zoneSegCoords[i].y)/2) };
}
}
//with midpoints, determine segments
for (var s = 0; s < settings.ZONE_SEGMENTS; s++)
{
//var segmentFullLength = pointDistance( zoneSegCoords[s].x, zoneSegCoords[s].y, zoneSegCoords[s+1].x, zoneSegCoords[s+1].y );
//var adjustedSegLength = segmentFullLength * settings.ZONE_SEG_LENGTH;
if (s == 0) {
var np1x = (zoneSegMidpoints[0].x + (settings.ZONE_SEG_LENGTH * ( zoneSegCoords[zoneSegCoords.length-1].x - zoneSegMidpoints[0].x) ) );
var np1y = (zoneSegMidpoints[0].y + (settings.ZONE_SEG_LENGTH * ( zoneSegCoords[zoneSegCoords.length-1].y - zoneSegMidpoints[0].y) ) );
var np2x = (zoneSegMidpoints[0].x + (settings.ZONE_SEG_LENGTH * ( zoneSegCoords[s].x - zoneSegMidpoints[0].x) ) );
var np2y = (zoneSegMidpoints[0].y + (settings.ZONE_SEG_LENGTH * ( zoneSegCoords[s].y - zoneSegMidpoints[0].y) ) );
}
else {
var np1x = (zoneSegMidpoints[s].x + (settings.ZONE_SEG_LENGTH * ( zoneSegCoords[s-1].x - zoneSegMidpoints[s].x) ) );
var np1y = (zoneSegMidpoints[s].y + (settings.ZONE_SEG_LENGTH * ( zoneSegCoords[s-1].y - zoneSegMidpoints[s].y) ) );
var np2x = (zoneSegMidpoints[s].x + (settings.ZONE_SEG_LENGTH * ( zoneSegCoords[s].x - zoneSegMidpoints[s].x) ) );
var np2y = (zoneSegMidpoints[s].y + (settings.ZONE_SEG_LENGTH * ( zoneSegCoords[s].y - zoneSegMidpoints[s].y) ) );
}
trueSegments[s] = { x1:np1x, y1:np1y, x2:np2x, y2:np2y };
}
//have segment coordinates, now build it
for (var n = 0; n < trueSegments.length; n++) {
geo.vertices.push( new THREE.Vector3( (trueSegments[n].x1), (trueSegments[n].y1), 0) );
geo.vertices.push( new THREE.Vector3( (trueSegments[n].x2), (trueSegments[n].y2), 0) );
}
for (var n = 0; n < trueSegments.length; n++) {
geo.vertices.push( new THREE.Vector3( (trueSegments[n].x1), (trueSegments[n].y1), settings.ZONE_HEIGHT) );
geo.vertices.push( new THREE.Vector3( (trueSegments[n].x2), (trueSegments[n].y2), settings.ZONE_HEIGHT) );
}
for (var i = 0; i < (geo.vertices.length/2)-1; i+=2) {
geo.faces.push(
new THREE.Face3( (i), (i+1), (i+(geo.vertices.length/2)) ), //a,b,c
new THREE.Face3( (i+(geo.vertices.length/2)+1), (i+(geo.vertices.length/2)), (i+1) ) //d,c,b
);
}
this.shape = "circle";
break;
}
//var alpha = Math.max(color.r,color.g,color.b);
//color.r /= alpha; color.g /= alpha; color.b /= alpha;
if(!this.mat)
this.mat = new THREE.MeshBasicMaterial( { color: color, transparent: settings.ALPHA_BLEND, opacity: settings.ZONE_ALPHA/**alpha*/, side: THREE.DoubleSide } );
if(!this.mesh)
{
this.mesh = new THREE.Mesh(geo,this.mat);
this.mesh.position.set(prop.x||0,prop.y||0,prop.z||0);
this.mesh.scale.set(this.radius||1,this.radius||1,1);
this.mesh.cfg = this;
}
}
distance(position)
{
switch(this.shape)
{
case "circle":
return pointDistance(this.mesh.position.x,this.mesh.position.y,position.x,position.y);
break;
case "polygon":
var min = Infinity, x, tmp, coords = this.mesh.geometry.vertices;
for(var i=(coords.length/2)-1;i>=0;x=(--i)-1)
{
if(coords[x] !== undefined)
{
tmp = distanceoflines(
coords[i].x,coords[i].y, coords[x].x,coords[x].y,
position.x,position.y, position.x,position.y
);
if(min > tmp) { min = tmp; }
}
}
return min;
break;
}
return Infinity;
}
onEnter(cycle,time)
{
switch(this.type)
{
case "wall":
cycle.position.x -= cycle.dir.front[0]*(engine.gtime-time);
cycle.position.y -= cycle.dir.front[1]*(engine.gtime-time);
break;
case "death":
cycle.kill();
engine.console.print(cycle.getColoredName()+"0xRESETT exploded on a deathzone.\n");
break;
case "win":
if(engine.winner == undefined && engine.declareRoundWinner == undefined)
{
//engine.console.print(cycle.getColoredName()+"0xRESETT ");
this.expansion = -1;
engine.declareRoundWinner = cycle.name;
}
break;
case "target":
loadcfg(settings.DEFAULT_TARGET_COMMAND.replace(/\\n/g,"\n"));
cycle.addScore(settings.TARGET_INITIAL_SCORE);
break;
}
}
onInside(cycle,time,timestep)
{
switch(this.type)
{
case "rubber":
cycle.rubber += timestep*this.value;
if(cycle.rubber >= settings.CYCLE_RUBBER)
{
cycle.kill();
engine.console.print(cycle.getColoredName()+"0xRESETT exploded on a rubberzone.\n");
}
break;
case "fortress":
if(engine.gtime > 0)
{
- this.rotationSpeed += timestep*0.5;
+ this.rotationSpeed += timestep*settings.FORTRESS_CONQUEST_RATE;
if(this.rotationSpeed > settings.ZONE_SPIN_SPEED*16)
{
engine.console.print(cycle.getColoredName()+"0xRESETT conquered a fortress zone.\n");
this.type = "null"; this.expansion = -10;
engine.declareRoundWinner = cycle.name;
}
}
break;
case "ball": case "soccerball":
var mindirx=0,mindiry=0,mindist=Infinity,apc=0;
for(var i=359;i>0;i--)
{
var xdir = Math.cos(Math.PI*2*(i/360)), ydir=Math.sin(Math.PI*2*(i/360));
- var xpos = xdir*this.radius+this.x, ypos=ydir*this.radius+this.y;
+ var xpos = xdir*this.radius+this.mesh.position.x, ypos=ydir*this.radius+this.mesh.position.y;
var dist = pointDistance(xpos,ypos,cycle.position.x,cycle.position.y);
if(dist < mindist)
{
/*if(mindist == Infinity)mindist = dist; else mindist += dist;
mindirx -= xdir; mindiry -= ydir;
apc++;*/
mindist=dist;mindirx=xdir;mindiry=ydir;apc=1;
}
}
//mindist /= apc; mindirx /= apc; mindiry /= apc;
if(mindist != Infinity)
{
this.xdir = -mindirx*cycle.speed; this.ydir = -mindiry*cycle.speed;
if(!this.bounce) this.bounce = true;
}
break;
case "speed":
cycle.speed = this.value||0;
break;
case "acceleration":
accel = (this.value||0); cycle.accel += accel;
cycle.speed += cycle.speed*accel;
break;
}
}
onLeave(cycle,time)
{
}
onOutside(cycle,time)
{
}
}
if(typeof(module) != "undefined") module.exports = Zone;

File Metadata

Mime Type
text/x-diff
Expires
Mon, Jun 23, 9:30 PM (4 d, 1 h ago)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
10852

Event Timeline