SC CODE: // Copyright 2024. Civilware. All rights reserved.
// TELA Decentralized Web Document (TELA-DOC-1)
Function InitializePrivate() Uint64
10 IF init() == 0 THEN GOTO 30
20 RETURN 1
30 STORE("nameHdr", "data1.js")
31 STORE("descrHdr", "Data file 1")
32 STORE("iconURLHdr", "")
33 STORE("dURL", "data1.js")
34 STORE("docType", "TELA-JS-1")
35 STORE("subDir", "")
36 STORE("fileCheckC", "35b74e34f2904a24a3eff7238ce09ad231ad77aebf68819e19ae62072656ef2")
37 STORE("fileCheckS", "2be10bd3ee3dc4d66d0d2301ba851242a6fd9e2b76071b164a3b43200edf3b67")
100 RETURN 0
End Function
Function init() Uint64
10 IF EXISTS("owner") == 0 THEN GOTO 30
20 RETURN 1
30 STORE("owner", address())
50 STORE("docVersion", "1.0.0")
60 STORE("hash", HEX(TXID()))
70 STORE("likes", 0)
80 STORE("dislikes", 0)
100 RETURN 0
End Function
Function address() String
10 DIM s as String
20 LET s = SIGNER()
30 IF IS_ADDRESS_VALID(s) THEN GOTO 50
40 RETURN "anon"
50 RETURN ADDRESS_STRING(s)
End Function
Function Rate(r Uint64) Uint64
10 DIM addr as String
15 LET addr = address()
16 IF r < 100 && EXISTS(addr) == 0 && addr != "anon" THEN GOTO 30
20 RETURN 1
30 STORE(addr, ""+r+"_"+BLOCK_HEIGHT())
40 IF r < 50 THEN GOTO 70
50 STORE("likes", LOAD("likes")+1)
60 RETURN 0
70 STORE("dislikes", LOAD("dislikes")+1)
100 RETURN 0
End Function
/*function rotationX(t){const n=Math.cos(t),r=Math.sin(t);return new Float32Array([1,0,0,0,0,n,-r,0,0,r,n,0,0,0,0,1])}function rotationY(t){const n=Math.cos(t),r=Math.sin(t);return new Float32Array([n,0,r,0,0,1,0,0,-r,0,n,0,0,0,0,1])}function rotationZ(t){const n=Math.cos(t),r=Math.sin(t);return new Float32Array([n,-r,0,0,r,n,0,0,0,0,1,0,0,0,0,1])}function scaleMatrix(t,n,r){return new Float32Array([t,0,0,0,0,n,0,0,0,0,r,0,0,0,0,1])}function modelMatrix(t,n,r){return new Float32Array([1,0,0,0,0,1,0,0,0,0,1,0,t,n,r,1])}function multiply(t,n){const r=new Float32Array(16);for(let o=0;o<4;o++)for(let a=0;a<4;a++)r[4*o+a]=t[0+a]*n[4*o+0]+t[4+a]*n[4*o+1]+t[8+a]*n[4*o+2]+t[12+a]*n[4*o+3];return r}function translate(t,n,r){return[1,0,0,0,0,1,0,0,0,0,1,0,t,n,r,1]}function normalize(t){const n=Math.hypot(t[0],t[1],t[2]);return n>0?[t[0]/n,t[1]/n,t[2]/n]:[0,0,0]}function multiplyMat4Vec4(t,n){return[t[0]*n[0]+t[4]*n[1]+t[8]*n[2]+t[12]*n[3],t[1]*n[0]+t[5]*n[1]+t[9]*n[2]+t[13]*n[3],t[2]*n[0]+t[6]*n[1]+t[10]*n[2]+t[14]*n[3],t[3]*n[0]+t[7]*n[1]+t[11]*n[2]+t[15]*n[3]]}function distance(t,n){const r=t.x-n.x,o=t.y-n.y,a=t.z-n.z;return Math.sqrt(r*r+o*o+a*a)}function computeNormal(t,e,r){const o=[e[0]-t[0],e[1]-t[1],e[2]-t[2]],n=[r[0]-t[0],r[1]-t[1],r[2]-t[2]],a=[o[1]*n[2]-o[2]*n[1],o[2]*n[0]-o[0]*n[2],o[0]*n[1]-o[1]*n[0]],s=Math.hypot(a[0],a[1],a[2]);return[a[0]/s,a[1]/s,a[2]/s]}function generateNormals(t){const e=[];for(let r=0;r<t.length;r+=9){const o=computeNormal([t[r],t[r+1],t[r+2]],[t[r+3],t[r+4],t[r+5]],[t[r+6],t[r+7],t[r+8]]);e.push(...o,...o,...o)}return new Float32Array(e)}function createWheelNormals(t){const e=[];for(let r=0;r<t;r++){const o=r*(2*Math.PI/t);e.push(Math.cos(o),0,Math.sin(o))}return e}function generateColorMap(t,e=.8,r=.6,o=.3){const n=new Float32Array(3*t.length);for(let a=0;a<t.length;a++)n[3*a+0]=e,n[3*a+1]=r,n[3*a+2]=o;return n}function createTankHullMesh(t,e,r,o=!1){const n=.5*t,a=.5*e,s=.5*r,l=.4*a,c=[-n,-a,s,n,-a,s,n,l,s,-n,-a,s,n,l,s,-n,l,s,-n,-a,-s,-n,l,-s,n,l,-s,-n,-a,-s,n,l,-s,n,-a,-s,-n,-a,-s,-n,-a,s,-n,l,s,-n,-a,-s,-n,l,s,-n,l,-s,n,-a,-s,n,l,-s,n,l,s,n,-a,-s,n,l,s,n,-a,s,-n,l,-s,-n,l,s,n,l,s,-n,l,-s,n,l,s,n,l,-s,-n,-a,-s,n,-a,-s,n,-a,s,-n,-a,-s,n,-a,s,-n,-a,s];return colors=o?enemyTankColors:tankColors,{vertices:new Float32Array(c),normals:new Float32Array(generateNormals(c)),colors:new Float32Array(colors),uvs:new Float32Array(cubeUVs)}}const cubeUVs=new Float32Array([0,0,1,0,1,1,0,0,1,1,0,1,0,0,1,0,1,1,0,0,1,1,0,1,0,0,1,0,1,1,0,0,1,1,0,1,0,0,1,0,1,1,0,0,1,1,0,1,0,0,1,0,1,1,0,0,1,1,0,1,0,0,1,0,1,1,0,0,1,1,0,1]);function createBoxMesh(t=cubeColors){return{vertices:new Float32Array(cubeVertices),normals:new Float32Array(generateNormals(cubeVertices)),colors:new Float32Array(t)}}function createCylinderMesh(t=1,e=1,r=12,o=!1,n=.8,a=.6,s=.3,l=!1){const c=[],h=[],u=[],M=.25*e;function i(t,e,r){return[t,-r,e]}for(let e=0;e<r;e++){const f=e/r*Math.PI*2,p=(e+1)/r*Math.PI*2,y=Math.cos(f)*t,w=Math.sin(f)*t,A=Math.cos(p)*t,F=Math.sin(p)*t;let m=[[y,M,w],[A,M,F],[y,-M,w],[A,M,F],[A,-M,F],[y,-M,w]];let g=[Math.cos(.5*(f+p)),0,Math.sin(.5*(f+p))];for(let t=0;t<m.length;t++){let[e,r,M]=m[t],[f,p,y]=g;if(o&&([e,r,M]=i(e,r,M),[f,p,y]=i(f,p,y)),c.push(e,r,M),h.push(f,p,y),l){const t=.65+.35*((Math.atan2(M,e)+Math.PI)/(2*Math.PI)),r=n*t,o=a*t,l=s*t;u.push(r,o,l)}else u.push(n,a,s)}}for(let e=0;e<r;e++){const l=e/r*Math.PI*2,f=(e+1)/r*Math.PI*2;let p=[[0,M,0],[Math.cos(l)*t,M,Math.sin(l)*t],[Math.cos(f)*t,M,Math.sin(f)*t]],y=[0,1,0];for(let t=0;t<p.length;t++){let[e,r,l]=p[t],[M,f,w]=y;o&&([e,r,l]=i(e,r,l),[M,f,w]=i(M,f,w)),c.push(e,r,l),h.push(M,f,w),u.push(n,a,s)}}for(let e=0;e<r;e++){const l=e/r*Math.PI*2,f=(e+1)/r*Math.PI*2,p=Math.cos(l)*t,y=Math.sin(l)*t;let w=[[0,-M,0],[Math.cos(f)*t,-M,Math.sin(f)*t],[p,-M,y]],A=[0,-1,0];for(let t=0;t<w.length;t++){let[e,r,l]=w[t],[M,f,p]=A;o&&([e,r,l]=i(e,r,l),[M,f,p]=i(M,f,p)),c.push(e,r,l),h.push(M,f,p),u.push(n,a,s)}}return{vertices:new Float32Array(c),normals:new Float32Array(h),colors:new Float32Array(u)}}const triangleVertices=new Float32Array([-1,1,0,-1,-1,0,1,1,0]),triangleNormals=new Float32Array([0,1,0,0,1,0,0,1,0]),cubeVertices=new Float32Array([-1,-1,1,1,-1,1,1,1,1,-1,-1,1,1,1,1,-1,1,1,-1,-1,-1,-1,1,-1,1,1,-1,-1,-1,-1,1,1,-1,1,-1,-1,-1,-1,-1,-1,-1,1,-1,1,1,-1,-1,-1,-1,1,1,-1,1,-1,1,-1,-1,1,1,-1,1,1,1,1,-1,-1,1,1,1,1,-1,1,-1,1,-1,-1,1,1,1,1,1,-1,1,-1,1,1,1,1,1,-1,-1,-1,-1,1,-1,-1,1,-1,1,-1,-1,-1,1,-1,1,-1,-1,1]),baseColors=new Float32Array([.7,.1,0,.7,.1,0,.7,.1,0,.7,.1,0,.7,.1,0,.7,.1,0,.5,.1,0,.5,.1,0,.5,.1,0,.5,.1,0,.5,.1,0,.5,.1,0,.6,.1,0,.6,.1,0,.6,.1,0,.6,.1,0,.6,.1,0,.6,.1,0,.6,.1,0,.6,.1,0,.6,.1,0,.6,.1,0,.6,.1,0,.6,.1,0,.7,.1,0,.7,.1,0,.7,.1,0,.7,.1,0,.7,.1,0,.7,.1,0,.7,.1,0,.7,.1,0,.7,.1,0,.7,.1,0,.7,.1,0,.7,.1,0]),cubeColors=new Float32Array([.8,.2,0,.8,.2,0,.8,.2,0,.8,.2,0,.8,.2,0,.8,.2,0,.8,.2,0,.8,.2,0,.8,.2,0,.8,.2,0,.8,.2,0,.8,.2,0,.8,.2,0,.8,.2,0,.8,.2,0,.8,.2,0,.8,.2,0,.8,.2,0,.8,.2,0,.8,.2,0,.8,.2,0,.8,.2,0,.8,.2,0,.8,.2,0,.8,.2,0,.8,.2,0,.8,.2,0,.8,.2,0,.8,.2,0,.8,.2,0,.8,.2,0,.8,.2,0,.8,.2,0,.8,.2,0,.8,.2,0,.8,.2,0]),greyColors=new Float32Array([.7,.7,.7,.7,.7,.7,.7,.7,.7,.7,.7,.7,.7,.7,.7,.7,.7,.7,.7,.7,.7,.7,.7,.7,.7,.7,.7,.7,.7,.7,.7,.7,.7,.7,.7,.7,.7,.7,.7,.7,.7,.7,.7,.7,.7,.7,.7,.7,.7,.7,.7,.7,.7,.7,.7,.7,.7,.7,.7,.7,.7,.7,.7,.7,.7,.7,.7,.7,.7,.7,.7,.7,.7,.7,.7,.7,.7,.7,.7,.7,.7,.7,.7,.7,.7,.7,.7,.7,.7,.7,.7,.7,.7,.7,.7,.7,.7,.7,.7,.7,.7,.7,.7,.7,.7,.7,.7,.7]),tankColors=new Float32Array([0,.3,0,0,.3,0,0,.3,0,0,.3,0,0,.3,0,0,.3,0,0,.3,0,0,.3,0,0,.3,0,0,.3,0,0,.3,0,0,.3,0,0,.3,0,0,.3,0,0,.3,0,0,.3,0,0,.3,0,0,.3,0,0,.3,0,0,.3,0,0,.3,0,0,.3,0,0,.3,0,0,.3,0,0,.3,0,0,.3,0,0,.3,0,0,.3,0,0,.3,0,0,.3,0,0,.2,0,0,.2,0,0,.2,0,0,.2,0,0,.2,0,0,.2,0]),enemyTankColors=new Float32Array([.4,.2,0,.4,.2,0,.4,.2,0,.4,.2,0,.4,.2,0,.4,.2,0,.4,.2,0,.4,.2,0,.4,.2,0,.4,.2,0,.4,.2,0,.4,.2,0,.4,.2,0,.4,.2,0,.4,.2,0,.4,.2,0,.4,.2,0,.4,.2,0,.4,.2,0,.4,.2,0,.4,.2,0,.4,.2,0,.4,.2,0,.4,.2,0,.4,.2,0,.4,.2,0,.4,.2,0,.4,.2,0,.4,.2,0,.4,.2,0,.2,.1,0,.2,.1,0,.2,.1,0,.2,.1,0,.2,.1,0,.2,.1,0]);class Transform{constructor(){this.x=0,this.y=0,this.z=0,this.rx=0,this.ry=0,this.rz=0,this.sx=1,this.sy=1,this.sz=1}getMatrix(t=null){const r=modelMatrix(this.x,this.y,this.z),s=rotationX(this.rx),n=rotationY(this.ry),o=rotationZ(this.rz),i=scaleMatrix(this.sx,this.sy,this.sz),e=multiply(r,multiply(n,multiply(o,multiply(s,i))));return t?multiply(t,e):e}getRotationMatrix(){const t=rotationX(this.rx),r=rotationY(this.ry),s=rotationZ(this.rz);return multiply(r,multiply(s,t))}}class SceneObject{constructor(t){this.mesh=t,this.transform=new Transform,this.children=[]}}function getWorldPos(t){return{x:t[12],y:t[13],z:t[14]}}function getForward(t){const r=t[8],s=t[9],n=t[10],o=Math.hypot(r,s,n);return{x:r/o,y:s/o,z:n/o}}function getRight(t){const r=t[0],s=t[1],n=t[2],o=Math.hypot(r,s,n);return{x:r/o,y:s/o,z:n/o}}function getUp(t){const r=t[4],s=t[5],n=t[6],o=Math.hypot(r,s,n);return{x:r/o,y:s/o,z:n/o}}function createBox(t,r,s,n,o,i,e,h=0){const a=new SceneObject(e);return a.transform.x=t,a.transform.y=r,a.transform.z=s,a.transform.ry=h,a.transform.sx=n,a.transform.sy=o,a.transform.sz=i,a.width=n,a.height=o,a.depth=i,a.halfWidth=.5*n,a.halfHeight=.5*o,a.halfDepth=.5*i,a.colliderType="obb",a.obb={},a}function createCylinder(t,r,s,n,o,i,e=0){const h=new SceneObject(i);return h.transform.x=t,h.transform.y=r,h.transform.z=s,h.transform.ry=e,h.transform.sx=n,h.transform.sy=o,h.transform.sz=n,h.colliderType="circle",h.r=n,h.obb={},h}let heightmap=[];function pointToSegmentDistance(t,s,i,e,h,r){const a=h-i,o=r-e;let n=((t-i)*a+(s-e)*o)/(a*a+o*o);n=Math.max(0,Math.min(1,n));const m=t-(i+n*a),l=s-(e+n*o);return Math.sqrt(m*m+l*l)}class TerrainScene{constructor(t){this.size=t.size,this.spacing=t.spacing,this.bigFreq=t.bigFreq,this.bigAmp=t.bigAmp,this.midFreq=t.midFreq,this.midAmp=t.midAmp,this.noiseAmp=t.noiseAmp,this.roads=t.roads||[],this.flats=t.flats||[],this.colors=t.colors||{low:{r:.1,g:.4,b:.1},mid:{r:.4,g:.3,b:.1},high:{r:.6,g:.6,b:.6}},this.heightmap=this.generateBaseHeightmap();for(const t of this.roads)for(const s of t)s.height=this.heightmap[s.z][s.x]}generateBaseHeightmap(){const t=[];for(let s=0;s<this.size;s++){t[s]=[];for(let i=0;i<this.size;i++){const e=Math.sin(i*this.bigFreq)*Math.cos(s*this.bigFreq)*this.bigAmp,h=Math.sin(i*this.midFreq)*Math.cos(s*this.midFreq)*this.midAmp,r=(Math.random()-.5)*this.noiseAmp;t[s][i]=e+h+r}}return t}smooth(t=1){for(let s=0;s<t;s++)this.heightmap=this.smoothHeightmap2D(this.heightmap,this.size)}smoothHeightmap2D(t,s){const i=[];for(let e=0;e<s;e++){i[e]=[];for(let h=0;h<s;h++)i[e][h]=0!==e&&e!==s-1&&0!==h&&h!==s-1?(t[e][h]+t[e][h-1]+t[e][h+1]+t[e-1][h]+t[e+1][h])/5:t[e][h]}return i}microSmooth(){for(let t=0;t<this.size;t++)for(let s=0;s<this.size;s++)this.heightmap[t][s]+=.1*(Math.random()-.5)}carveRoads(t=6){for(const s of this.roads)this.heightmap=this.carveRoad(this.heightmap,this.size,s,t)}carveRoad(t,s,i,e=6){for(let h=0;h<i.length-1;h++){const r=i[h],a=i[h+1];for(let i=0;i<s;i++)for(let h=0;h<s;h++){pointToSegmentDistance(h,i,r.x,r.z,a.x,a.z)<e&&(t[i][h]=.2*t[i][h]+.8*r.height)}}return t}applyFlats(){for(const t of this.flats)this.flattenArea(this.heightmap,t.cx,t.cz,t.radius,t.height);this.smooth(1)}flattenArea(t,s,i,e,h){for(let r=i-e;r<=i+e;r++)for(let a=s-e;a<=s+e;a++){const o=a-s,n=r-i;o*o+n*n<e*e&&(t[r][a]=h)}}generateMesh(){const t=[],s=(this.size-1)*this.spacing/2;for(let i=0;i<this.size-1;i++)for(let e=0;e<this.size-1;e++){const h=this.heightmap[i][e],r=this.heightmap[i][e+1],a=this.heightmap[i+1][e+1],o=this.heightmap[i+1][e],n=e*this.spacing-s,m=i*this.spacing-s,l=(e+1)*this.spacing-s,c=m,g=l,p=(i+1)*this.spacing-s,f=n,d=p;t.push(n,h,m,l,r,c,g,a,p,n,h,m,g,a,p,f,o,d)}const i=new Float32Array(t);return{vertices:i,normals:generateNormals(i).map(t=>-t),colors:this.generateColors(i)}}generateColors(t){const s=new Float32Array(t.length);for(let i=0;i<t.length;i+=3){const e=(t[i+1]+1)/2;let h;h=e<.3?this.colors.low:e<.6?this.colors.mid:this.colors.high,s[i]=h.r,s[i+1]=h.g,s[i+2]=h.b}return s}build(){this.smooth(1),this.microSmooth(),this.carveRoads(12),this.applyFlats(),this.smooth(3);return this.generateMesh()}}function generateGridRoads(t,s){const i=[];for(let e=s;e<t;e+=s){const s=[];for(let i=0;i<t;i+=40)s.push({x:e,z:i});i.push(s)}for(let e=s;e<t;e+=s){const s=[];for(let i=0;i<t;i+=40)s.push({x:i,z:e});i.push(s)}return i}function generateUrbanFlats(t,s,i){const e=[];for(let h=s;h<t;h+=s)for(let r=s;r<t;r+=s)e.push({cx:h-s/2,cz:r-s/2,radius:.45*s,height:i});return e}const hmap={sample(t,s){const i=(terrain.size-1)*terrain.spacing/2;let e=(t+i)/terrain.spacing,h=(s+i)/terrain.spacing,r=Math.floor(e),a=r+1,o=Math.floor(h),n=o+1;r=Math.max(0,Math.min(terrain.size-1,r)),a=Math.max(0,Math.min(terrain.size-1,a)),o=Math.max(0,Math.min(terrain.size-1,o)),n=Math.max(0,Math.min(terrain.size-1,n));const m=e-r,l=h-o;return(terrain.heightmap[o][r]*(1-m)+terrain.heightmap[o][a]*m)*(1-l)+(terrain.heightmap[n][r]*(1-m)+terrain.heightmap[n][a]*m)*l},normal(t,s){const i=this.sample(t-1,s),e=this.sample(t+1,s),h=this.sample(t,s+1),r=this.sample(t,s-1);return normalize([-(e-i),1,-(h-r)])}};const size=513,spacing=1;let terrain={};function createLevel1(){respawnPlayer(-245,-235,-.3*Math.PI);const e=[];terrain=new TerrainScene({size:513,spacing:1,bigFreq:.1,bigAmp:2,midFreq:.15,midAmp:1.5,noiseAmp:.4,roads:[[{x:20,z:40},{x:80,z:100},{x:150,z:140},{x:200,z:200},{x:280,z:260},{x:320,z:260}]],flats:[{cx:250,cz:250,radius:20,height:.5}]});const s=terrain.build(),r=new Mesh(gl,s.vertices,s.normals,s.colors),a=new SceneObject(r);e.push(a);const t=createBoxMesh(baseColors),o=new Mesh(gl,t.vertices,t.normals,t.colors),h=createBase("baseA",50,0,50,[{x:0,y:0,z:0,hw:8,hh:8,hd:8,mesh:o,rotateY:0},{x:0,y:0,z:10,hw:4,hh:8,hd:4,mesh:o,rotateY:0},{x:0,y:0,z:-10,hw:4,hh:8,hd:4,mesh:o,rotateY:0},{x:10,y:0,z:0,hw:4,hh:8,hd:4,mesh:o,rotateY:0},{x:-10,y:0,z:0,hw:4,hh:8,hd:4,mesh:o,rotateY:0}]);game.bases[h.id]=h;for(const s of h.boxes)e.push(s);const n=new Mesh(gl,t.vertices,t.normals,greyColors),c=createBox(15,1,25,20,12,4,n,.5*Math.PI),l=createBox(35,1,5,20,12,4,n,Math.PI),i=createBox(-10,.5,10,1.5,3,1.5,o,.25*Math.PI);e.push(c,l,i),e.push(spawnBarrel(-10,3,5)),e.push(spawnBarrel(-30,3,5));for(const s of e)worldObjects.push(s),scene.push(s);spawnEnemy("chaser",50,50),spawnEnemy("chaser",50,50),spawnEnemy("strafer",50,50)}function createLevel2(){respawnPlayer(45,-235,2*-Math.PI),resetCameraForLookAt(game.player);const e=[];terrain=new TerrainScene({size:513,spacing:5,bigFreq:.1,bigAmp:10,midFreq:0,midAmp:0,noiseAmp:0,roads:generateGridRoads(513,30)});const s=terrain.build(),r=new Mesh(gl,s.vertices,s.normals,s.colors),a=new SceneObject(r);e.push(a);const t=createBoxMesh(baseColors),o=new Mesh(gl,t.vertices,t.normals,t.colors),h=createBase("baseA",50,5,50,[{x:0,y:0,z:0,hw:10,hh:8,hd:6,mesh:o,rotateY:0},{x:12,y:0,z:0,hw:6,hh:8,hd:4,mesh:o,rotateY:0},{x:-12,y:0,z:0,hw:6,hh:8,hd:4,mesh:o,rotateY:0}]);game.bases[h.id]=h;const n=createBase("baseB",220,10,200,[{x:0,y:0,z:0,hw:10,hh:8,hd:6,mesh:o,rotateY:0},{x:12,y:0,z:0,hw:6,hh:8,hd:4,mesh:o,rotateY:0},{x:-12,y:0,z:0,hw:6,hh:8,hd:4,mesh:o,rotateY:0}]);game.bases[n.id]=n;for(const s of[...h.boxes,...n.boxes])e.push(s);const c=new Mesh(gl,t.vertices,t.normals,greyColors),l=createBox(75,1,0,20,12,20,c,.5*Math.PI),i=createBox(0,1,75,20,12,20,c,Math.PI),m=createBox(0,1,-200,20,12,20,c,Math.PI),p=createBox(-50,1,-200,10,12,10,c,.25*Math.PI),w=createBox(150,1,240,10,15,15,c,Math.PI),x=createBox(150,10,200,30,10,4,c,.5*Math.PI),M=createBox(200,10,150,30,10,4,c,Math.PI),y=createBox(-10,5,10,1.5,3,1.5,o,.25*Math.PI);e.push(l,i,m,p,w,y,x,M),e.push(spawnBarrel(-10,3,5));for(const s of e)worldObjects.push(s),scene.push(s);spawnEnemy("chaser",50,50),spawnEnemy("chaser",50,50),spawnEnemy("strafer"),spawnEnemy("tank",150,150),spawnEnemy("strafer",150,150)}function createLevel3(){respawnPlayer(45,-235,2*-Math.PI),resetCameraForLookAt(game.player);const e=[];terrain=new TerrainScene({size:513,spacing:5,bigFreq:.1,bigAmp:1,midFreq:.5,midAmp:.15,noiseAmp:0});const s=terrain.size/2,r=terrain.size/2;for(let e=0;e<terrain.size;e++)for(let a=0;a<terrain.size;a++){const t=a-s,o=e-r,h=Math.sqrt(t*t+o*o),n=Math.exp(-h*h/2e3);terrain.heightmap[e][a]+=30*n}const a=terrain.build(),t=new Mesh(gl,a.vertices,a.normals,a.colors),o=new SceneObject(t);e.push(o);const h=createBoxMesh(baseColors),n=new Mesh(gl,h.vertices,h.normals,h.colors),c=createBase("baseA",0,35,0,[{x:0,y:0,z:0,hw:10,hh:8,hd:6,mesh:n,rotateY:0},{x:12,y:0,z:0,hw:6,hh:8,hd:4,mesh:n,rotateY:0},{x:-12,y:0,z:0,hw:6,hh:8,hd:4,mesh:n,rotateY:0}]);game.bases[c.id]=c;for(const s of[...c.boxes])e.push(s);const l=new Mesh(gl,h.vertices,h.normals,greyColors),i=createBox(-30,30,30,20,10,4,l,.25*Math.PI),m=createBox(30,30,50,20,10,4,l,Math.PI),p=createBox(-40,30,-10,20,10,4,l,.5*Math.PI),w=createBox(50,30,10,40,10,4,l,.5*Math.PI),x=createBox(-20,30,-30,20,10,4,l,Math.PI),M=createBox(30,30,-30,20,10,4,l,Math.PI);e.push(i,m,p,w,x,M);const y=createCylinderMesh(1.2,2,12),d=new Mesh(gl,y.vertices,y.normals,y.colors);e.push(createCylinder(-5,30,8,1.2,2,d));const g=createCylinderMesh(.5,6,12),B=new Mesh(gl,g.vertices,g.normals,g.colors);e.push(createCylinder(-5,32,8,.5,6,B));const b=createCylinderMesh(.2,3,12),u=new Mesh(gl,b.vertices,b.normals,b.colors);e.push(createCylinder(-5,38,8,.2,3,u));const P=createCylinderMesh(1.5,4,16,!1,.5,.2,.1),f=(new Mesh(gl,P.vertices,P.normals,P.colors),spawnBarrel(20,32,-5));f.transform.rx=.5*Math.PI,e.push(f);const z=spawnBarrel(24,32,-5);z.transform.rx=.5*Math.PI,e.push(z);for(const s of e)worldObjects.push(s),scene.push(s);spawnEnemy("chaser",50,50),spawnEnemy("chaser",50,-50),spawnEnemy("strafer"),spawnEnemy("strafer"),spawnEnemy("tank")}function createLevel4(){respawnPlayer(45,-235,2*-Math.PI),resetCameraForLookAt(game.player);const e=[];terrain=new TerrainScene({size:513,spacing:5,bigFreq:.1,bigAmp:1,midFreq:.5,midAmp:.15,noiseAmp:0,colors:{low:{r:.4,g:.4,b:.3},mid:{r:.5,g:.5,b:.4},high:{r:.7,g:.6,b:.6}}});const s=terrain.build(),r=new Mesh(gl,s.vertices,s.normals,s.colors),a=new SceneObject(r);e.push(a);const t=createBoxMesh(baseColors),o=new Mesh(gl,t.vertices,t.normals,t.colors),h=createBase("baseA",70,0,50,[{x:0,y:0,z:0,hw:10,hh:8,hd:6,mesh:o,rotateY:0},{x:12,y:0,z:0,hw:6,hh:8,hd:4,mesh:o,rotateY:0},{x:-12,y:0,z:0,hw:6,hh:8,hd:4,mesh:o,rotateY:0}]);game.bases[h.id]=h;for(const s of[...h.boxes])e.push(s);const n=new Mesh(gl,t.vertices,t.normals,greyColors),c=createBox(0,0,0,30,10,4,n,Math.PI),l=createBox(70,0,0,30,10,4,n,Math.PI),i=createBox(140,0,0,30,10,4,n,Math.PI),m=createBox(50,0,30,30,10,4,n,.5*Math.PI),p=createBox(90,0,30,30,10,4,n,.5*Math.PI),w=createBox(-26,0,50,50,10,4,n,.5*Math.PI),x=createBox(166,0,50,50,10,4,n,.5*Math.PI),M=createBox(70,0,96,80,10,4,n,Math.PI);e.push(c,l,i,m,p,w,x,M);const y=createCylinderMesh(1.5,4,16,!1,.5,.2,.1),d=(new Mesh(gl,y.vertices,y.normals,y.colors),spawnBarrel(20,2,-5));d.transform.rx=.5*Math.PI,e.push(d);const g=spawnBarrel(26,2,-5);g.transform.rx=.5*Math.PI,e.push(g),e.push(spawnBarrel(50,0,64)),e.push(spawnBarrel(90,0,64));for(const s of e)worldObjects.push(s),scene.push(s);spawnEnemy("chaser",50,50),spawnEnemy("chaser",50,-50),spawnEnemy("strafer"),spawnEnemy("strafer"),spawnEnemy("tank",70,25,0),spawnEnemy("tank",70,35,0)}*/ |
| SC Arguments: [Name:SC_ACTION Type:uint64 Value:'1' Name:SC_CODE Type:string Value:'// Copyright 2024. Civilware. All rights reserved.
// TELA Decentralized Web Document (TELA-DOC-1)
Function InitializePrivate() Uint64
10 IF init() == 0 THEN GOTO 30
20 RETURN 1
30 STORE("nameHdr", "data1.js")
31 STORE("descrHdr", "Data file 1")
32 STORE("iconURLHdr", "")
33 STORE("dURL", "data1.js")
34 STORE("docType", "TELA-JS-1")
35 STORE("subDir", "")
36 STORE("fileCheckC", "35b74e34f2904a24a3eff7238ce09ad231ad77aebf68819e19ae62072656ef2")
37 STORE("fileCheckS", "2be10bd3ee3dc4d66d0d2301ba851242a6fd9e2b76071b164a3b43200edf3b67")
100 RETURN 0
End Function
Function init() Uint64
10 IF EXISTS("owner") == 0 THEN GOTO 30
20 RETURN 1
30 STORE("owner", address())
50 STORE("docVersion", "1.0.0")
60 STORE("hash", HEX(TXID()))
70 STORE("likes", 0)
80 STORE("dislikes", 0)
100 RETURN 0
End Function
Function address() String
10 DIM s as String
20 LET s = SIGNER()
30 IF IS_ADDRESS_VALID(s) THEN GOTO 50
40 RETURN "anon"
50 RETURN ADDRESS_STRING(s)
End Function
Function Rate(r Uint64) Uint64
10 DIM addr as String
15 LET addr = address()
16 IF r < 100 && EXISTS(addr) == 0 && addr != "anon" THEN GOTO 30
20 RETURN 1
30 STORE(addr, ""+r+"_"+BLOCK_HEIGHT())
40 IF r < 50 THEN GOTO 70
50 STORE("likes", LOAD("likes")+1)
60 RETURN 0
70 STORE("dislikes", LOAD("dislikes")+1)
100 RETURN 0
End Function
/*function rotationX(t){const n=Math.cos(t),r=Math.sin(t);return new Float32Array([1,0,0,0,0,n,-r,0,0,r,n,0,0,0,0,1])}function rotationY(t){const n=Math.cos(t),r=Math.sin(t);return new Float32Array([n,0,r,0,0,1,0,0,-r,0,n,0,0,0,0,1])}function rotationZ(t){const n=Math.cos(t),r=Math.sin(t);return new Float32Array([n,-r,0,0,r,n,0,0,0,0,1,0,0,0,0,1])}function scaleMatrix(t,n,r){return new Float32Array([t,0,0,0,0,n,0,0,0,0,r,0,0,0,0,1])}function modelMatrix(t,n,r){return new Float32Array([1,0,0,0,0,1,0,0,0,0,1,0,t,n,r,1])}function multiply(t,n){const r=new Float32Array(16);for(let o=0;o<4;o++)for(let a=0;a<4;a++)r[4*o+a]=t[0+a]*n[4*o+0]+t[4+a]*n[4*o+1]+t[8+a]*n[4*o+2]+t[12+a]*n[4*o+3];return r}function translate(t,n,r){return[1,0,0,0,0,1,0,0,0,0,1,0,t,n,r,1]}function normalize(t){const n=Math.hypot(t[0],t[1],t[2]);return n>0?[t[0]/n,t[1]/n,t[2]/n]:[0,0,0]}function multiplyMat4Vec4(t,n){return[t[0]*n[0]+t[4]*n[1]+t[8]*n[2]+t[12]*n[3],t[1]*n[0]+t[5]*n[1]+t[9]*n[2]+t[13]*n[3],t[2]*n[0]+t[6]*n[1]+t[10]*n[2]+t[14]*n[3],t[3]*n[0]+t[7]*n[1]+t[11]*n[2]+t[15]*n[3]]}function distance(t,n){const r=t.x-n.x,o=t.y-n.y,a=t.z-n.z;return Math.sqrt(r*r+o*o+a*a)}function computeNormal(t,e,r){const o=[e[0]-t[0],e[1]-t[1],e[2]-t[2]],n=[r[0]-t[0],r[1]-t[1],r[2]-t[2]],a=[o[1]*n[2]-o[2]*n[1],o[2]*n[0]-o[0]*n[2],o[0]*n[1]-o[1]*n[0]],s=Math.hypot(a[0],a[1],a[2]);return[a[0]/s,a[1]/s,a[2]/s]}function generateNormals(t){const e=[];for(let r=0;r<t.length;r+=9){const o=computeNormal([t[r],t[r+1],t[r+2]],[t[r+3],t[r+4],t[r+5]],[t[r+6],t[r+7],t[r+8]]);e.push(...o,...o,...o)}return new Float32Array(e)}function createWheelNormals(t){const e=[];for(let r=0;r<t;r++){const o=r*(2*Math.PI/t);e.push(Math.cos(o),0,Math.sin(o))}return e}function generateColorMap(t,e=.8,r=.6,o=.3){const n=new Float32Array(3*t.length);for(let a=0;a<t.length;a++)n[3*a+0]=e,n[3*a+1]=r,n[3*a+2]=o;return n}function createTankHullMesh(t,e,r,o=!1){const n=.5*t,a=.5*e,s=.5*r,l=.4*a,c=[-n,-a,s,n,-a,s,n,l,s,-n,-a,s,n,l,s,-n,l,s,-n,-a,-s,-n,l,-s,n,l,-s,-n,-a,-s,n,l,-s,n,-a,-s,-n,-a,-s,-n,-a,s,-n,l,s,-n,-a,-s,-n,l,s,-n,l,-s,n,-a,-s,n,l,-s,n,l,s,n,-a,-s,n,l,s,n,-a,s,-n,l,-s,-n,l,s,n,l,s,-n,l,-s,n,l,s,n,l,-s,-n,-a,-s,n,-a,-s,n,-a,s,-n,-a,-s,n,-a,s,-n,-a,s];return colors=o?enemyTankColors:tankColors,{vertices:new Float32Array(c),normals:new Float32Array(generateNormals(c)),colors:new Float32Array(colors),uvs:new Float32Array(cubeUVs)}}const cubeUVs=new Float32Array([0,0,1,0,1,1,0,0,1,1,0,1,0,0,1,0,1,1,0,0,1,1,0,1,0,0,1,0,1,1,0,0,1,1,0,1,0,0,1,0,1,1,0,0,1,1,0,1,0,0,1,0,1,1,0,0,1,1,0,1,0,0,1,0,1,1,0,0,1,1,0,1]);function createBoxMesh(t=cubeColors){return{vertices:new Float32Array(cubeVertices),normals:new Float32Array(generateNormals(cubeVertices)),colors:new Float32Array(t)}}function createCylinderMesh(t=1,e=1,r=12,o=!1,n=.8,a=.6,s=.3,l=!1){const c=[],h=[],u=[],M=.25*e;function i(t,e,r){return[t,-r,e]}for(let e=0;e<r;e++){const f=e/r*Math.PI*2,p=(e+1)/r*Math.PI*2,y=Math.cos(f)*t,w=Math.sin(f)*t,A=Math.cos(p)*t,F=Math.sin(p)*t;let m=[[y,M,w],[A,M,F],[y,-M,w],[A,M,F],[A,-M,F],[y,-M,w]];let g=[Math.cos(.5*(f+p)),0,Math.sin(.5*(f+p))];for(let t=0;t<m.length;t++){let[e,r,M]=m[t],[f,p,y]=g;if(o&&([e,r,M]=i(e,r,M),[f,p,y]=i(f,p,y)),c.push(e,r,M),h.push(f,p,y),l){const t=.65+.35*((Math.atan2(M,e)+Math.PI)/(2*Math.PI)),r=n*t,o=a*t,l=s*t;u.push(r,o,l)}else u.push(n,a,s)}}for(let e=0;e<r;e++){const l=e/r*Math.PI*2,f=(e+1)/r*Math.PI*2;let p=[[0,M,0],[Math.cos(l)*t,M,Math.sin(l)*t],[Math.cos(f)*t,M,Math.sin(f)*t]],y=[0,1,0];for(let t=0;t<p.length;t++){let[e,r,l]=p[t],[M,f,w]=y;o&&([e,r,l]=i(e,r,l),[M,f,w]=i(M,f,w)),c.push(e,r,l),h.push(M,f,w),u.push(n,a,s)}}for(let e=0;e<r;e++){const l=e/r*Math.PI*2,f=(e+1)/r*Math.PI*2,p=Math.cos(l)*t,y=Math.sin(l)*t;let w=[[0,-M,0],[Math.cos(f)*t,-M,Math.sin(f)*t],[p,-M,y]],A=[0,-1,0];for(let t=0;t<w.length;t++){let[e,r,l]=w[t],[M,f,p]=A;o&&([e,r,l]=i(e,r,l),[M,f,p]=i(M,f,p)),c.push(e,r,l),h.push(M,f,p),u.push(n,a,s)}}return{vertices:new Float32Array(c),normals:new Float32Array(h),colors:new Float32Array(u)}}const triangleVertices=new Float32Array([-1,1,0,-1,-1,0,1,1,0]),triangleNormals=new Float32Array([0,1,0,0,1,0,0,1,0]),cubeVertices=new Float32Array([-1,-1,1,1,-1,1,1,1,1,-1,-1,1,1,1,1,-1,1,1,-1,-1,-1,-1,1,-1,1,1,-1,-1,-1,-1,1,1,-1,1,-1,-1,-1,-1,-1,-1,-1,1,-1,1,1,-1,-1,-1,-1,1,1,-1,1,-1,1,-1,-1,1,1,-1,1,1,1,1,-1,-1,1,1,1,1,-1,1,-1,1,-1,-1,1,1,1,1,1,-1,1,-1,1,1,1,1,1,-1,-1,-1,-1,1,-1,-1,1,-1,1,-1,-1,-1,1,-1,1,-1,-1,1]),baseColors=new Float32Array([.7,.1,0,.7,.1,0,.7,.1,0,.7,.1,0,.7,.1,0,.7,.1,0,.5,.1,0,.5,.1,0,.5,.1,0,.5,.1,0,.5,.1,0,.5,.1,0,.6,.1,0,.6,.1,0,.6,.1,0,.6,.1,0,.6,.1,0,.6,.1,0,.6,.1,0,.6,.1,0,.6,.1,0,.6,.1,0,.6,.1,0,.6,.1,0,.7,.1,0,.7,.1,0,.7,.1,0,.7,.1,0,.7,.1,0,.7,.1,0,.7,.1,0,.7,.1,0,.7,.1,0,.7,.1,0,.7,.1,0,.7,.1,0]),cubeColors=new Float32Array([.8,.2,0,.8,.2,0,.8,.2,0,.8,.2,0,.8,.2,0,.8,.2,0,.8,.2,0,.8,.2,0,.8,.2,0,.8,.2,0,.8,.2,0,.8,.2,0,.8,.2,0,.8,.2,0,.8,.2,0,.8,.2,0,.8,.2,0,.8,.2,0,.8,.2,0,.8,.2,0,.8,.2,0,.8,.2,0,.8,.2,0,.8,.2,0,.8,.2,0,.8,.2,0,.8,.2,0,.8,.2,0,.8,.2,0,.8,.2,0,.8,.2,0,.8,.2,0,.8,.2,0,.8,.2,0,.8,.2,0,.8,.2,0]),greyColors=new Float32Array([.7,.7,.7,.7,.7,.7,.7,.7,.7,.7,.7,.7,.7,.7,.7,.7,.7,.7,.7,.7,.7,.7,.7,.7,.7,.7,.7,.7,.7,.7,.7,.7,.7,.7,.7,.7,.7,.7,.7,.7,.7,.7,.7,.7,.7,.7,.7,.7,.7,.7,.7,.7,.7,.7,.7,.7,.7,.7,.7,.7,.7,.7,.7,.7,.7,.7,.7,.7,.7,.7,.7,.7,.7,.7,.7,.7,.7,.7,.7,.7,.7,.7,.7,.7,.7,.7,.7,.7,.7,.7,.7,.7,.7,.7,.7,.7,.7,.7,.7,.7,.7,.7,.7,.7,.7,.7,.7,.7]),tankColors=new Float32Array([0,.3,0,0,.3,0,0,.3,0,0,.3,0,0,.3,0,0,.3,0,0,.3,0,0,.3,0,0,.3,0,0,.3,0,0,.3,0,0,.3,0,0,.3,0,0,.3,0,0,.3,0,0,.3,0,0,.3,0,0,.3,0,0,.3,0,0,.3,0,0,.3,0,0,.3,0,0,.3,0,0,.3,0,0,.3,0,0,.3,0,0,.3,0,0,.3,0,0,.3,0,0,.3,0,0,.2,0,0,.2,0,0,.2,0,0,.2,0,0,.2,0,0,.2,0]),enemyTankColors=new Float32Array([.4,.2,0,.4,.2,0,.4,.2,0,.4,.2,0,.4,.2,0,.4,.2,0,.4,.2,0,.4,.2,0,.4,.2,0,.4,.2,0,.4,.2,0,.4,.2,0,.4,.2,0,.4,.2,0,.4,.2,0,.4,.2,0,.4,.2,0,.4,.2,0,.4,.2,0,.4,.2,0,.4,.2,0,.4,.2,0,.4,.2,0,.4,.2,0,.4,.2,0,.4,.2,0,.4,.2,0,.4,.2,0,.4,.2,0,.4,.2,0,.2,.1,0,.2,.1,0,.2,.1,0,.2,.1,0,.2,.1,0,.2,.1,0]);class Transform{constructor(){this.x=0,this.y=0,this.z=0,this.rx=0,this.ry=0,this.rz=0,this.sx=1,this.sy=1,this.sz=1}getMatrix(t=null){const r=modelMatrix(this.x,this.y,this.z),s=rotationX(this.rx),n=rotationY(this.ry),o=rotationZ(this.rz),i=scaleMatrix(this.sx,this.sy,this.sz),e=multiply(r,multiply(n,multiply(o,multiply(s,i))));return t?multiply(t,e):e}getRotationMatrix(){const t=rotationX(this.rx),r=rotationY(this.ry),s=rotationZ(this.rz);return multiply(r,multiply(s,t))}}class SceneObject{constructor(t){this.mesh=t,this.transform=new Transform,this.children=[]}}function getWorldPos(t){return{x:t[12],y:t[13],z:t[14]}}function getForward(t){const r=t[8],s=t[9],n=t[10],o=Math.hypot(r,s,n);return{x:r/o,y:s/o,z:n/o}}function getRight(t){const r=t[0],s=t[1],n=t[2],o=Math.hypot(r,s,n);return{x:r/o,y:s/o,z:n/o}}function getUp(t){const r=t[4],s=t[5],n=t[6],o=Math.hypot(r,s,n);return{x:r/o,y:s/o,z:n/o}}function createBox(t,r,s,n,o,i,e,h=0){const a=new SceneObject(e);return a.transform.x=t,a.transform.y=r,a.transform.z=s,a.transform.ry=h,a.transform.sx=n,a.transform.sy=o,a.transform.sz=i,a.width=n,a.height=o,a.depth=i,a.halfWidth=.5*n,a.halfHeight=.5*o,a.halfDepth=.5*i,a.colliderType="obb",a.obb={},a}function createCylinder(t,r,s,n,o,i,e=0){const h=new SceneObject(i);return h.transform.x=t,h.transform.y=r,h.transform.z=s,h.transform.ry=e,h.transform.sx=n,h.transform.sy=o,h.transform.sz=n,h.colliderType="circle",h.r=n,h.obb={},h}let heightmap=[];function pointToSegmentDistance(t,s,i,e,h,r){const a=h-i,o=r-e;let n=((t-i)*a+(s-e)*o)/(a*a+o*o);n=Math.max(0,Math.min(1,n));const m=t-(i+n*a),l=s-(e+n*o);return Math.sqrt(m*m+l*l)}class TerrainScene{constructor(t){this.size=t.size,this.spacing=t.spacing,this.bigFreq=t.bigFreq,this.bigAmp=t.bigAmp,this.midFreq=t.midFreq,this.midAmp=t.midAmp,this.noiseAmp=t.noiseAmp,this.roads=t.roads||[],this.flats=t.flats||[],this.colors=t.colors||{low:{r:.1,g:.4,b:.1},mid:{r:.4,g:.3,b:.1},high:{r:.6,g:.6,b:.6}},this.heightmap=this.generateBaseHeightmap();for(const t of this.roads)for(const s of t)s.height=this.heightmap[s.z][s.x]}generateBaseHeightmap(){const t=[];for(let s=0;s<this.size;s++){t[s]=[];for(let i=0;i<this.size;i++){const e=Math.sin(i*this.bigFreq)*Math.cos(s*this.bigFreq)*this.bigAmp,h=Math.sin(i*this.midFreq)*Math.cos(s*this.midFreq)*this.midAmp,r=(Math.random()-.5)*this.noiseAmp;t[s][i]=e+h+r}}return t}smooth(t=1){for(let s=0;s<t;s++)this.heightmap=this.smoothHeightmap2D(this.heightmap,this.size)}smoothHeightmap2D(t,s){const i=[];for(let e=0;e<s;e++){i[e]=[];for(let h=0;h<s;h++)i[e][h]=0!==e&&e!==s-1&&0!==h&&h!==s-1?(t[e][h]+t[e][h-1]+t[e][h+1]+t[e-1][h]+t[e+1][h])/5:t[e][h]}return i}microSmooth(){for(let t=0;t<this.size;t++)for(let s=0;s<this.size;s++)this.heightmap[t][s]+=.1*(Math.random()-.5)}carveRoads(t=6){for(const s of this.roads)this.heightmap=this.carveRoad(this.heightmap,this.size,s,t)}carveRoad(t,s,i,e=6){for(let h=0;h<i.length-1;h++){const r=i[h],a=i[h+1];for(let i=0;i<s;i++)for(let h=0;h<s;h++){pointToSegmentDistance(h,i,r.x,r.z,a.x,a.z)<e&&(t[i][h]=.2*t[i][h]+.8*r.height)}}return t}applyFlats(){for(const t of this.flats)this.flattenArea(this.heightmap,t.cx,t.cz,t.radius,t.height);this.smooth(1)}flattenArea(t,s,i,e,h){for(let r=i-e;r<=i+e;r++)for(let a=s-e;a<=s+e;a++){const o=a-s,n=r-i;o*o+n*n<e*e&&(t[r][a]=h)}}generateMesh(){const t=[],s=(this.size-1)*this.spacing/2;for(let i=0;i<this.size-1;i++)for(let e=0;e<this.size-1;e++){const h=this.heightmap[i][e],r=this.heightmap[i][e+1],a=this.heightmap[i+1][e+1],o=this.heightmap[i+1][e],n=e*this.spacing-s,m=i*this.spacing-s,l=(e+1)*this.spacing-s,c=m,g=l,p=(i+1)*this.spacing-s,f=n,d=p;t.push(n,h,m,l,r,c,g,a,p,n,h,m,g,a,p,f,o,d)}const i=new Float32Array(t);return{vertices:i,normals:generateNormals(i).map(t=>-t),colors:this.generateColors(i)}}generateColors(t){const s=new Float32Array(t.length);for(let i=0;i<t.length;i+=3){const e=(t[i+1]+1)/2;let h;h=e<.3?this.colors.low:e<.6?this.colors.mid:this.colors.high,s[i]=h.r,s[i+1]=h.g,s[i+2]=h.b}return s}build(){this.smooth(1),this.microSmooth(),this.carveRoads(12),this.applyFlats(),this.smooth(3);return this.generateMesh()}}function generateGridRoads(t,s){const i=[];for(let e=s;e<t;e+=s){const s=[];for(let i=0;i<t;i+=40)s.push({x:e,z:i});i.push(s)}for(let e=s;e<t;e+=s){const s=[];for(let i=0;i<t;i+=40)s.push({x:i,z:e});i.push(s)}return i}function generateUrbanFlats(t,s,i){const e=[];for(let h=s;h<t;h+=s)for(let r=s;r<t;r+=s)e.push({cx:h-s/2,cz:r-s/2,radius:.45*s,height:i});return e}const hmap={sample(t,s){const i=(terrain.size-1)*terrain.spacing/2;let e=(t+i)/terrain.spacing,h=(s+i)/terrain.spacing,r=Math.floor(e),a=r+1,o=Math.floor(h),n=o+1;r=Math.max(0,Math.min(terrain.size-1,r)),a=Math.max(0,Math.min(terrain.size-1,a)),o=Math.max(0,Math.min(terrain.size-1,o)),n=Math.max(0,Math.min(terrain.size-1,n));const m=e-r,l=h-o;return(terrain.heightmap[o][r]*(1-m)+terrain.heightmap[o][a]*m)*(1-l)+(terrain.heightmap[n][r]*(1-m)+terrain.heightmap[n][a]*m)*l},normal(t,s){const i=this.sample(t-1,s),e=this.sample(t+1,s),h=this.sample(t,s+1),r=this.sample(t,s-1);return normalize([-(e-i),1,-(h-r)])}};const size=513,spacing=1;let terrain={};function createLevel1(){respawnPlayer(-245,-235,-.3*Math.PI);const e=[];terrain=new TerrainScene({size:513,spacing:1,bigFreq:.1,bigAmp:2,midFreq:.15,midAmp:1.5,noiseAmp:.4,roads:[[{x:20,z:40},{x:80,z:100},{x:150,z:140},{x:200,z:200},{x:280,z:260},{x:320,z:260}]],flats:[{cx:250,cz:250,radius:20,height:.5}]});const s=terrain.build(),r=new Mesh(gl,s.vertices,s.normals,s.colors),a=new SceneObject(r);e.push(a);const t=createBoxMesh(baseColors),o=new Mesh(gl,t.vertices,t.normals,t.colors),h=createBase("baseA",50,0,50,[{x:0,y:0,z:0,hw:8,hh:8,hd:8,mesh:o,rotateY:0},{x:0,y:0,z:10,hw:4,hh:8,hd:4,mesh:o,rotateY:0},{x:0,y:0,z:-10,hw:4,hh:8,hd:4,mesh:o,rotateY:0},{x:10,y:0,z:0,hw:4,hh:8,hd:4,mesh:o,rotateY:0},{x:-10,y:0,z:0,hw:4,hh:8,hd:4,mesh:o,rotateY:0}]);game.bases[h.id]=h;for(const s of h.boxes)e.push(s);const n=new Mesh(gl,t.vertices,t.normals,greyColors),c=createBox(15,1,25,20,12,4,n,.5*Math.PI),l=createBox(35,1,5,20,12,4,n,Math.PI),i=createBox(-10,.5,10,1.5,3,1.5,o,.25*Math.PI);e.push(c,l,i),e.push(spawnBarrel(-10,3,5)),e.push(spawnBarrel(-30,3,5));for(const s of e)worldObjects.push(s),scene.push(s);spawnEnemy("chaser",50,50),spawnEnemy("chaser",50,50),spawnEnemy("strafer",50,50)}function createLevel2(){respawnPlayer(45,-235,2*-Math.PI),resetCameraForLookAt(game.player);const e=[];terrain=new TerrainScene({size:513,spacing:5,bigFreq:.1,bigAmp:10,midFreq:0,midAmp:0,noiseAmp:0,roads:generateGridRoads(513,30)});const s=terrain.build(),r=new Mesh(gl,s.vertices,s.normals,s.colors),a=new SceneObject(r);e.push(a);const t=createBoxMesh(baseColors),o=new Mesh(gl,t.vertices,t.normals,t.colors),h=createBase("baseA",50,5,50,[{x:0,y:0,z:0,hw:10,hh:8,hd:6,mesh:o,rotateY:0},{x:12,y:0,z:0,hw:6,hh:8,hd:4,mesh:o,rotateY:0},{x:-12,y:0,z:0,hw:6,hh:8,hd:4,mesh:o,rotateY:0}]);game.bases[h.id]=h;const n=createBase("baseB",220,10,200,[{x:0,y:0,z:0,hw:10,hh:8,hd:6,mesh:o,rotateY:0},{x:12,y:0,z:0,hw:6,hh:8,hd:4,mesh:o,rotateY:0},{x:-12,y:0,z:0,hw:6,hh:8,hd:4,mesh:o,rotateY:0}]);game.bases[n.id]=n;for(const s of[...h.boxes,...n.boxes])e.push(s);const c=new Mesh(gl,t.vertices,t.normals,greyColors),l=createBox(75,1,0,20,12,20,c,.5*Math.PI),i=createBox(0,1,75,20,12,20,c,Math.PI),m=createBox(0,1,-200,20,12,20,c,Math.PI),p=createBox(-50,1,-200,10,12,10,c,.25*Math.PI),w=createBox(150,1,240,10,15,15,c,Math.PI),x=createBox(150,10,200,30,10,4,c,.5*Math.PI),M=createBox(200,10,150,30,10,4,c,Math.PI),y=createBox(-10,5,10,1.5,3,1.5,o,.25*Math.PI);e.push(l,i,m,p,w,y,x,M),e.push(spawnBarrel(-10,3,5));for(const s of e)worldObjects.push(s),scene.push(s);spawnEnemy("chaser",50,50),spawnEnemy("chaser",50,50),spawnEnemy("strafer"),spawnEnemy("tank",150,150),spawnEnemy("strafer",150,150)}function createLevel3(){respawnPlayer(45,-235,2*-Math.PI),resetCameraForLookAt(game.player);const e=[];terrain=new TerrainScene({size:513,spacing:5,bigFreq:.1,bigAmp:1,midFreq:.5,midAmp:.15,noiseAmp:0});const s=terrain.size/2,r=terrain.size/2;for(let e=0;e<terrain.size;e++)for(let a=0;a<terrain.size;a++){const t=a-s,o=e-r,h=Math.sqrt(t*t+o*o),n=Math.exp(-h*h/2e3);terrain.heightmap[e][a]+=30*n}const a=terrain.build(),t=new Mesh(gl,a.vertices,a.normals,a.colors),o=new SceneObject(t);e.push(o);const h=createBoxMesh(baseColors),n=new Mesh(gl,h.vertices,h.normals,h.colors),c=createBase("baseA",0,35,0,[{x:0,y:0,z:0,hw:10,hh:8,hd:6,mesh:n,rotateY:0},{x:12,y:0,z:0,hw:6,hh:8,hd:4,mesh:n,rotateY:0},{x:-12,y:0,z:0,hw:6,hh:8,hd:4,mesh:n,rotateY:0}]);game.bases[c.id]=c;for(const s of[...c.boxes])e.push(s);const l=new Mesh(gl,h.vertices,h.normals,greyColors),i=createBox(-30,30,30,20,10,4,l,.25*Math.PI),m=createBox(30,30,50,20,10,4,l,Math.PI),p=createBox(-40,30,-10,20,10,4,l,.5*Math.PI),w=createBox(50,30,10,40,10,4,l,.5*Math.PI),x=createBox(-20,30,-30,20,10,4,l,Math.PI),M=createBox(30,30,-30,20,10,4,l,Math.PI);e.push(i,m,p,w,x,M);const y=createCylinderMesh(1.2,2,12),d=new Mesh(gl,y.vertices,y.normals,y.colors);e.push(createCylinder(-5,30,8,1.2,2,d));const g=createCylinderMesh(.5,6,12),B=new Mesh(gl,g.vertices,g.normals,g.colors);e.push(createCylinder(-5,32,8,.5,6,B));const b=createCylinderMesh(.2,3,12),u=new Mesh(gl,b.vertices,b.normals,b.colors);e.push(createCylinder(-5,38,8,.2,3,u));const P=createCylinderMesh(1.5,4,16,!1,.5,.2,.1),f=(new Mesh(gl,P.vertices,P.normals,P.colors),spawnBarrel(20,32,-5));f.transform.rx=.5*Math.PI,e.push(f);const z=spawnBarrel(24,32,-5);z.transform.rx=.5*Math.PI,e.push(z);for(const s of e)worldObjects.push(s),scene.push(s);spawnEnemy("chaser",50,50),spawnEnemy("chaser",50,-50),spawnEnemy("strafer"),spawnEnemy("strafer"),spawnEnemy("tank")}function createLevel4(){respawnPlayer(45,-235,2*-Math.PI),resetCameraForLookAt(game.player);const e=[];terrain=new TerrainScene({size:513,spacing:5,bigFreq:.1,bigAmp:1,midFreq:.5,midAmp:.15,noiseAmp:0,colors:{low:{r:.4,g:.4,b:.3},mid:{r:.5,g:.5,b:.4},high:{r:.7,g:.6,b:.6}}});const s=terrain.build(),r=new Mesh(gl,s.vertices,s.normals,s.colors),a=new SceneObject(r);e.push(a);const t=createBoxMesh(baseColors),o=new Mesh(gl,t.vertices,t.normals,t.colors),h=createBase("baseA",70,0,50,[{x:0,y:0,z:0,hw:10,hh:8,hd:6,mesh:o,rotateY:0},{x:12,y:0,z:0,hw:6,hh:8,hd:4,mesh:o,rotateY:0},{x:-12,y:0,z:0,hw:6,hh:8,hd:4,mesh:o,rotateY:0}]);game.bases[h.id]=h;for(const s of[...h.boxes])e.push(s);const n=new Mesh(gl,t.vertices,t.normals,greyColors),c=createBox(0,0,0,30,10,4,n,Math.PI),l=createBox(70,0,0,30,10,4,n,Math.PI),i=createBox(140,0,0,30,10,4,n,Math.PI),m=createBox(50,0,30,30,10,4,n,.5*Math.PI),p=createBox(90,0,30,30,10,4,n,.5*Math.PI),w=createBox(-26,0,50,50,10,4,n,.5*Math.PI),x=createBox(166,0,50,50,10,4,n,.5*Math.PI),M=createBox(70,0,96,80,10,4,n,Math.PI);e.push(c,l,i,m,p,w,x,M);const y=createCylinderMesh(1.5,4,16,!1,.5,.2,.1),d=(new Mesh(gl,y.vertices,y.normals,y.colors),spawnBarrel(20,2,-5));d.transform.rx=.5*Math.PI,e.push(d);const g=spawnBarrel(26,2,-5);g.transform.rx=.5*Math.PI,e.push(g),e.push(spawnBarrel(50,0,64)),e.push(spawnBarrel(90,0,64));for(const s of e)worldObjects.push(s),scene.push(s);spawnEnemy("chaser",50,50),spawnEnemy("chaser",50,-50),spawnEnemy("strafer"),spawnEnemy("strafer"),spawnEnemy("tank",70,25,0),spawnEnemy("tank",70,35,0)}*/'] |