diff --git a/scripts/buildObjects.js b/scripts/buildObjects.js index 14f266f..a0f27cd 100644 --- a/scripts/buildObjects.js +++ b/scripts/buildObjects.js @@ -1,1787 +1,1787 @@ /* * 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. */ //TODO: neaten up this file, make it so the map isn't parsed a bunch of times //TODO: use an object for the cycles? //lots of Durf code around these parts... //NOTE: these functions depend on the presence of mapSTRING and/or mapXML //RETURNS: scene mesh/object to add into global object function loadTextures() { - engine.textures.floor = new new THREE.TextureLoader().load(settings.FLOOR_TEXTURE); - engine.textures.rim_wall = new new THREE.TextureLoader().load(settings.RIM_WALL_TEXTURE); - engine.textures.cycle_wall = new new THREE.TextureLoader().load('images/textures/dir_wall.png'); - engine.textures.cycle_body = new THREE.TextureLoader().load('images/textures/cycle_body.png'); - engine.textures.cycle_wheel = new THREE.TextureLoader().load('images/textures/cycle_wheel.png') + engine.textures.floor = new new THREE.TextureLoader().load("images/"+settings.FLOOR_TEXTURE); + engine.textures.rim_wall = new new THREE.TextureLoader().load("images/"+settings.RIM_WALL_TEXTURE); + //engine.textures.cycle_wall = new new THREE.TextureLoader().load('images/textures/dir_wall.png'); + engine.textures.cycle_body = new THREE.TextureLoader().load("images/"+settings.CYCLE_TEXTURES[0]); + engine.textures.cycle_wheel = new THREE.TextureLoader().load("images/"+settings.CYCLE_TEXTURES[1]) engine.textures.cycle_shadow = new THREE.TextureLoader().load('images/textures/shadow.png') } //GRID function buildGrid() { //floor texture stuff engine.grid = new THREE.Object3D();//initialize global object var sizeFactorHandle = settings.SIZE_FACTOR / 2; engine.REAL_ARENA_SIZE_FACTOR = Math.pow(2, sizeFactorHandle); var logicalBox = getLogicalBox(engine.mapString);// x, y, minx, miny, maxx, maxy engine.logicalBox = { center: { x:logicalBox[0], y: logicalBox[1]}, min: { x:logicalBox[2], y: logicalBox[3]}, max: { x:logicalBox[4], y: logicalBox[5]} }; var logicalHeight = ((logicalBox[5]-logicalBox[3]) * engine.REAL_ARENA_SIZE_FACTOR)/* + 10*/;//+10 for outer edge var logicalWidth = ((logicalBox[4]-logicalBox[2]) * engine.REAL_ARENA_SIZE_FACTOR)/* + 10*/; if(!engine.dedicated) { var floorTexture = engine.textures.floor; floorTexture.wrapS = floorTexture.wrapT = THREE.RepeatWrapping; floorTexture.repeat.set(logicalWidth,logicalHeight); //floorTexture.repeat.set( 500, 500 ); var centerOffset_x = (logicalBox[2] * engine.REAL_ARENA_SIZE_FACTOR);//offset from bottom left corner var centerOffset_x2 = Math.round((centerOffset_x % 1)*100000000)/100000000; floorTexture.offset.x = centerOffset_x2; var centerOffset_y = (logicalBox[3] * engine.REAL_ARENA_SIZE_FACTOR);//-5;//not needed since we only take %1 offset var centerOffset_y2 = Math.round((centerOffset_y % 1)*100000000)/100000000; floorTexture.offset.y = centerOffset_y2; if(engine.usingWebgl) { var maxAnisotropy = engine.renderer.capabilities.getMaxAnisotropy(); floorTexture.anisotropy = maxAnisotropy; } var color = new THREE.Color(settings.FLOOR_RED,settings.FLOOR_GREEN,settings.FLOOR_BLUE); var floorMaterial = new THREE.MeshBasicMaterial( { color:color, map: floorTexture,/* transparent: settings.ALPHA_BLEND /*, side: THREE.DoubleSide*/} ); floorMaterial.needsUpdate = true;//is this needed? var floorGeometry = new THREE.PlaneBufferGeometry(logicalWidth*settings.GRID_SIZE,logicalHeight*settings.GRID_SIZE,1,1); floorGeometry.dynamic = true;//is this needed? var grid_object = new THREE.Mesh(floorGeometry, floorMaterial); grid_object.position.x = logicalBox[0] * engine.REAL_ARENA_SIZE_FACTOR; grid_object.position.y = logicalBox[1] * engine.REAL_ARENA_SIZE_FACTOR; grid_object.position.z = -2/100;//move down 2/100 units for render glitch //grid_object.scale.set(settings.GRID_SIZE,settings.GRID_SIZE,1); //console.log("gridx: "+grid_object.position.x+" gridy: "+grid_object.position.y); grid_object.geometry.dynamic = true;//is this needed? if(settings.FLOOR_MIRROR) { engine.grid.mirror = grid_object.clone(); engine.grid.mirror.position.z -= 1/100; engine.grid.reflection = new THREE.CubeCamera(0.01,100000,128); engine.scene.add(engine.grid.reflection); floorMaterial.envMap = engine.grid.reflection.renderTarget; engine.grid.reflection.position.copy(grid_object.position); //engine.grid.reflection.position.z = -250; } } // return grid_object; engine.grid.add(grid_object);//add to global object //SPAWNS add to map data var allSpawns = engine.mapXML.getElementsByTagName("Spawn"); for (s = 0; s < allSpawns.length; s++) { var sXpos = (allSpawns[s].getAttribute("x") * engine.REAL_ARENA_SIZE_FACTOR); var sYpos = (allSpawns[s].getAttribute("y") * engine.REAL_ARENA_SIZE_FACTOR); var sZpos = (allSpawns[s].getAttribute("z") * 1); if(isNaN(sZpos)) sZpos = 0; if ( allSpawns[s].hasAttribute("angle") ) { var sAng = allSpawns[s].getAttribute("angle"); } else { var sAng = gafd( parseFloat(allSpawns[s].getAttribute("xdir")), parseFloat(allSpawns[s].getAttribute("ydir")) ); } var spawn_data = [sXpos, sYpos, sZpos, sAng]; engine.map.spawns.push( spawn_data ); } }//end of grid /////////////////////////////// //WALLS function buildWalls() {//builds all walls in map and returns object to add to scene engine.walls = new THREE.Object3D(); var allWalls = engine.mapXML.getElementsByTagName("Wall"); for (var r = 0; r < allWalls.length; r++) { var wall_points = new Array(); if(settings.HIGH_RIM) var wall_height = Math.pow(2,16); else var wall_height = settings.LOW_RIM_HEIGHT; //4 if (allWalls[r].hasAttribute("height")) { wall_height = allWalls[r].getAttribute("height")*1; } var allWallPoints = allWalls[r].getElementsByTagName("Point"); for (var q = 0; q < allWallPoints.length; q++) { wall_points.push( [ allWallPoints[q].getAttribute("x") * engine.REAL_ARENA_SIZE_FACTOR, allWallPoints[q].getAttribute("y") * engine.REAL_ARENA_SIZE_FACTOR, 0, //wall_bottom wall_height ] ); } wall_object = buildWall(wall_points, wall_height); //wall_object.receiveShadow = true; //wall_object.castShadow = true; engine.walls.add(wall_object);//add complete object to global walls engine.map.walls.push(wall_points);//add to map data } } //this is for buildWalls - builds a single wall out of many var totalWallsLength = 0;//used to line textures like arma does function buildWall(pointArray, height) {//builds a single tag if(!settings.RIM_WALL_REPEAT_TOP && height > settings.RIM_WALL_STRETCH_Y) height = settings.RIM_WALL_STRETCH_Y; var geo = new THREE.Geometry(); for (var n = 0; n < pointArray.length; n++) { var thisPoint = pointArray[n]; geo.vertices.push( new THREE.Vector3( (thisPoint[0]), (thisPoint[1]), 0) ); } for (var m = 0; m < pointArray.length; m++) { var thisPoint = pointArray[m]; geo.vertices.push( new THREE.Vector3( (thisPoint[0]), (thisPoint[1]), height) ); } var totalLength = 0; for (var i = 0; i < (geo.vertices.length/2)-1; i++) { var p1x = geo.vertices[i].x; var p1y = geo.vertices[i].y; var p2x = geo.vertices[i+1].x; var p2y = geo.vertices[i+1].y; var dist = Math.sqrt( (p2x-=p1x)*p2x + (p2y-=p1y)*p2y ); totalLength += dist; totalWallsLength += dist; // console.log(totalLength); // var slope = ( (py2 - py1) / (px2 - px1) ); // var invslope = -( (px2 - px1) / (py2 - py1) ); var normal = new THREE.Vector3( (p2y - p1y), -(p2x - p1x), 0 ); // c d // a b 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 ); geo.faceVertexUvs[0].push( [new THREE.Vector2((totalWallsLength-dist),0),new THREE.Vector2((totalWallsLength),0),new THREE.Vector2((totalWallsLength-dist),1)], //a,b,c [new THREE.Vector2((totalWallsLength),1),new THREE.Vector2((totalWallsLength-dist),1),new THREE.Vector2((totalWallsLength),0)] //d,c,b ); } if(!engine.dedicated) { geo.uvsNeedUpdate = true; geo.buffersNeedUpdate = true; //apparently isn't needed for desired effect geo.computeFaceNormals();//for lighting geo.computeVertexNormals();//for lighting? if(settings.RIM_WALL_TEXTURE != "") { var wallTexture = engine.textures.rim_wall; wallTexture.wrapS = THREE.RepeatWrapping; if(settings.RIM_WALL_WRAP_Y) wallTexture.wrapT = THREE.RepeatWrapping; wallTexture.repeat.set(1/settings.RIM_WALL_STRETCH_X,height/settings.RIM_WALL_STRETCH_Y); //totalLength, height } if(engine.usingWebgl) { var maxAnisotropy = engine.renderer.getMaxAnisotropy(); wallTexture.anisotropy = maxAnisotropy; } var wallIsTooLow = height"); engine.console.print("If no additional arguments, toggles boolean commands between true and false.") return false; } var cmd = split[0].toUpperCase(); if(split.length > 1) { var curr = chsetting(cmd,undefined,true), s = 0; for(var i=0;i 2) { cfg.x = s[1]*engine.REAL_ARENA_SIZE_FACTOR; cfg.y = s[2]*engine.REAL_ARENA_SIZE_FACTOR; if(s.length > 4) { cfg.dir = Math.atan2(s[4],s[3]); if(settings.STRICT_AXES_SPAWN) { var deg = (pi(2)/settings.ARENA_AXES); cfg.dir = Math.round(cfg.dir/deg)*deg; } } } p.spawn(cfg); } }, KILL: function(params) { var p = getPlayer(params); if(p) { p.kill(); if(settings.ADMIN_KILL_MESSAGE) engine.console.print(p.getColoredName()+"0xRESETT has been smitten by an administrator.\n"); } }, KILL_ALL: function() { for(var x=engine.players.length-1;x>=0;--x) if(typeof(engine.players[x]) != "undefined") { engine.players[x].kill(); } }, INCLUDE: function(params,silent=false,callback=undefined) { var file = params.replace(/\(.+\)/g,""); var s = localStorage.getItem(file); if(s == null && !engine.dedicated) { var incfile = settings.RESOURCE_REPOSITORY_CACHE+"../config/"+params; engine.console.print("Loading CFG from "+incfile+"...\n"); httpGetAsync(incfile,function(txt){loadcfg(txt,silent);if(callback != undefined)callback();}); } else { loadcfg(s,silent); if(callback != undefined)callback(); } }, SINCLUDE: function(params) { commands.INCLUDE(params,true) }, RINCLUDE: function(params,callback=undefined) { var file = params.replace(/\(.+\)/g,""); var incfile = settings.RESOURCE_REPOSITORY_SERVER+params; engine.console.print("Downloading CFG from "+incfile+"...\n"); httpGetAsync(incfile,function(txt){loadcfg(txt);if(callback != undefined)callback();}); }, SPAWN_ZONE: function(params) { if(params == "") { engine.console.print("Usage:\nSPAWN_ZONE \nSPAWN_ZONE \nSPAWN_ZONE \nSPAWN_ZONE \n\nInstead of one can write: L [...] Z\nInstead of one can write: P [...] Z"); } else { var zone = {}, args = params.split(" "); if(args[0] == "n") { zone.name = args.slice(0,2)[1]; } zone.type = args[0]; if(zone.type == "acceleration" || zone.type == "speed") { zone.value = args.slice(1,2)[0]; } if(args[1] === "L") { for(var i=2;args[i]=="Z"||i>args.length;i+=2) { if(i == 2) { zone.x = args[i] *engine.REAL_ARENA_SIZE_FACTOR; zone.y = args[i+1]*engine.REAL_ARENA_SIZE_FACTOR; } } args.slice(2,i); } else { zone.x = args[1]*engine.REAL_ARENA_SIZE_FACTOR; zone.y = args[2]*engine.REAL_ARENA_SIZE_FACTOR; } if(args[3] === "P") { engine.console.print("WARNING: ShapePolygon may not currently work. Use at your own risk.\n",false); for(var i=3;args[i]=="Z"||i>args.length;i+=2) { } args.slice(3,i); } else { zone.radius = args[3]*engine.REAL_ARENA_SIZE_FACTOR; } zone.expansion = args[4]*1; zone.xdir = args[5]*1; zone.ydir = args[6]*1; zone.bounce = Boolean(parseInt+(args[7]))&&args[7]!="false"; if(args[7] != undefined) { zone.color = new THREE.Color(args[7]/15,args[8]/15,args[9]/15); } new Zone(zone).spawn(); console.log("new Zone: "+zone); } }, SPAWN_WALL: function(params) { if(params == "") { engine.console.print("Usage:\nSPAWN_WALL [...]\n"); } else { var params = params.split(" "), height = params.slice(0,1)[0]*1, points = []; for(var q=0;q=0;x--) { if(x == args[0]) { engine.zones.children[x].position.x = args[1]*engine.REAL_ARENA_SIZE_FACTOR; engine.zones.children[x].position.y = args[2]*engine.REAL_ARENA_SIZE_FACTOR; return true; } } engine.console.print("Invalid zone ID\n"); }, SET_AI_PATH: function(params) { var args = params.split(" "); if(args[0] == "*") { } else { var cycle = getPlayer(args.shift()); if(cycle) { for(var x=0,len=args.length;x<0;x+=2) { cycle.push([args[x],args[x+1]]); } } else { engine.console.print("Usage: ..."); } } }, CLEAR_AI_POSITION: function(params) { }, LIST_ZONES: function(params="") { var found = 0; for(var x=0,len=engine.zones.children.length;x=0;--i) { if(sets[i] == setting) { var settingFound = false; for(var i=netChanged.length-1;i>=0;--i) { if(netChanged[i][0] == setting) settingFound = true; } if(!settingFound) netChanged.push([setting,chsetting("CYCLE_SPEED",undefined,true)]); return "0xff7f7f"+chsetting(setting,value,false," on server order","0x808080"); } } return false; } function saveusercfg() { var usercfg = ""; for(var i=0;i -1) { if(len != 0) print += ", "; len++; print += sets[i]; } } if(len > 0) engine.console.print("Perhaps you meant: "+print+"\n"); } } return exec; } function mkSettingCallback(setting,stringify=false) { if(stringify) return function(set){return ""+chsetting(setting,set,true)} else return function(set){return chsetting(setting,set,true)} } function getargs() { var s = window.location.hash.replace("#","").split("&"); _GET = {}; for(var i=0,len=s.length;i\n\\n\\n\t\\n\t\t\