// // courseScene.js //-------------------- // Manages the ingame state of a course. // by RHY3756547 // // includes: narc.js // formats/* // engine/* // entities/* // gl-matrix.js // render/* // window.courseScene = function(mainNarc, texNarc, music, chars, options, gameRes) { var startSetups = [ {maxplayers:12, toAline:4, xspacing:32, yspacing:32, liney:160}, {maxplayers:24, toAline:4, xspacing:32, yspacing:32, liney:80}, {maxplayers:36, toAline:6, xspacing:21, yspacing:21, liney:80}, {maxplayers:48, toAline:6, xspacing:21, yspacing:21, liney:54}, {maxplayers:64, toAline:8, xspacing:16, yspacing:16, liney:54}, {maxplayers:112, toAline:8, xspacing:16, yspacing:16, liney:32}, ] var scn = this; scn.sndUpdate = sndUpdate; scn.update = update; scn.draw = draw; scn.removeParticle = removeParticle; scn.removeEntity = removeEntity; scn.updateMode = updateMode; scn.lapAdvance = lapAdvance; scn.fileBank = {}; var loadFunc = { $nsbmd: nsbmd, $nsbtx: nsbtx, $nsbca: nsbca, $nsbta: nsbta, $nsbtp: nsbtp, } scn.typeRes = []; scn.gameRes = gameRes; scn.lightMat = []; scn.farShadMat = []; scn.shadMat = []; //game mode initialization scn.mode = { mode: -1, time: 0 }; var musicRestartTimer = -1; var musicRestart = 3.5*60; var musicRestartType = 0; var finishers = []; //load main course var courseTx = new nsbtx(texNarc.getFile("/course_model.nsbtx"), false, true); var taFile = mainNarc.getFile("/course_model.nsbta"); if (taFile != null) var courseTa = new nsbta(taFile); //can be null var courseMdl = new nsbmd(mainNarc.getFile("/course_model.nsbmd")); var course = new nitroModel(courseMdl, courseTx) if (taFile != null) course.loadTexAnim(courseTa); //load sky var skyTx = new nsbtx(texNarc.getFile("/course_model_V.nsbtx"), false, true); var staFile = mainNarc.getFile("/course_model_V.nsbta"); if (staFile != null) var skyTa = new nsbta(staFile); //can be null console.log("--------- LOADING SKY ---------") var skyMdl = new nsbmd(mainNarc.getFile("/course_model_V.nsbmd")); var sky = new nitroModel(skyMdl, skyTx) if (staFile != null) sky.loadTexAnim(skyTa); ckcl = new kcl(mainNarc.getFile("/course_collision.kcl"), false); cnkm = new nkm(mainNarc.getFile("/course_map.nkm")); scn.course = course; scn.sky = sky; scn.kcl = ckcl; scn.nkm = cnkm; scn.entities = []; //these should never change scn.karts = []; //these should probably not change scn.items = new ItemController(scn); //these should change a lot!! scn.particles = []; //not synced with server at all scn.colEnt = []; scn.musicPlayer = null; startCourse(chars); var frame = 0; var entsToRemove = []; function draw(gl, pMatrix, shadow) { gl.cullFace(gl.BACK); /*var mat = scn.camera.getView(scn); var pMatrix = mat.p; var mvMatrix = mat.mv;*/ var mvMatrix = mat4.create(); nitroRender.setAlpha(1); if (!shadow) { var skyMat = mat4.scale(mat4.create(), mvMatrix, [1/64, 1/64, 1/64]); sky.setFrame(frame); sky.draw(skyMat, pMatrix); } var lvlMat = mat4.scale(mat4.create(), mvMatrix, [1/64, 1/64, 1/64]);//[2, 2, 2]); course.setFrame(frame); course.draw(lvlMat, pMatrix); var transE = []; mat4.scale(mvMatrix, mvMatrix, [1/1024, 1/1024, 1/1024]) //"so why are these separated rhys??" // //fantastic i'm glad you asked //if we draw lots of the same model, not animated in a row we don't need to resend the matStack for that model //which saves a lot of time for the 2 extra model types per car. for (var i=0; i -1) { musicRestartTimer++; if (musicRestartTimer > musicRestart) { scn.musicPlayer = nitroAudio.playSound(music, {volume:2, bpmMultiplier:(musicRestartType==0)?1.25:1}, null); musicRestartTimer = -1; } } for (var i=0; i winPercent) continue; finishTuple = finishPercents[i]; } kart.controller = new controlRaceCPU(scn.nkm, {}); kart.controller.setKart(kart); kart.anim.setAnim(winPercent>0.5?kart.charRes.LoseA:kart.charRes.winA); kart.animMode = "raceEnd"; scn.camera = (new cameraSpectator(kart, scn)); nitroAudio.playSound(finishTuple[1], {volume:2}, 0); nitroAudio.playSound(finishTuple[2], {volume:2}, null); nitroAudio.instaKill(scn.musicPlayer); musicRestartTimer = 0; musicRestart = 7.5*60; musicRestartType = 1; music = finishTuple[3]; scn.entities.push(new Race3DUI(scn, "goal")); } else if (kart.lapNumber < 4) nitroAudio.playSound(65, {volume:2}, 0); } if (kart.lapNumber == 4) finishers.push(kart); } function startPosition(toAline, xspacing, yspacing, liney, angle, i) { var horizN = i%toAline; var vertN = Math.floor(i/toAline); var staggered = (vertN%2); //second line moves 1/2 x spacing to the right var relPos = [(horizN-(toAline/2)-0.25)*xspacing+staggered*0.5, 8, -(horizN*yspacing + vertN*liney)]; var mat = mat4.rotateY([], mat4.create(), angle*(Math.PI/180)); vec3.transformMat4(relPos, relPos, mat); return relPos; } function loadRes(res, id) { var models = []; for (var i=0; i 0) { //beeps for countdown nitroAudio.playSound(39, {bpmMultiplier:16}, 0); } break; case 2: //show ui and play music at certain time after go if (mode.time == 1) { scn.musicPlayer = nitroAudio.playSound(music, {volume:2}, null); } // break; } } //win sting: 46 //ok sting: 47 //lose sting: 48 //battle lose sting: 49 //battle win sting: 50 //ok sting??: 51 //mission mode win sting: 52 //mission mode win2 sting: 53 //mission mode superwin sting: 54 //boss win sting: 55 //ok music: 56 //lose music: 57 //win music: 58 //racelose : 61 //ok music: 58 //good time trials music: 59 //ok time trials: 60 //final lap: 62 //full results win: 63 //results draw: 64 //full results lose: 65 //gp results cutscene music: 66 //gp results win music: 67 //??? : 68 //credits: 69-70 // star: 73 scn.mode = mode; } }