Looks like I have to clean this out...
This commit is contained in:
1 parent
7e213690c8
commit
a16ba9a907
192 files changed
-40154
No files matched your search
@@ -1,98 +0,0 @@
|
||||
//
|
||||
// cameraIngame.js
|
||||
//--------------------
|
||||
// The ingame camera that follows the kart from behind.
|
||||
// by RHY3756547
|
||||
//
|
||||
// includes: main.js
|
||||
//
|
||||
|
||||
window.cameraIngame = function(kart) {
|
||||
|
||||
var thisObj = this;
|
||||
this.kart = kart;
|
||||
this.getView = getView;
|
||||
this.targetShadowPos = [0, 0, 0]
|
||||
|
||||
var mat = mat4.create();
|
||||
|
||||
var camOffset = [0, 32, -48]
|
||||
var lookAtOffset = [0, 16, 0]
|
||||
|
||||
var camNormal = [0, 1, 0];
|
||||
var camAngle = 0;
|
||||
var boostOff = 0;
|
||||
|
||||
function getView(scene) {
|
||||
var basis = buildBasis();
|
||||
var camPos = vec3.transformMat4([], camOffset, basis);
|
||||
var lookAtPos = vec3.transformMat4([], lookAtOffset, basis);
|
||||
|
||||
vec3.scale(camPos, camPos, 1/1024);
|
||||
vec3.scale(lookAtPos, lookAtPos, 1/1024);
|
||||
|
||||
var mat = mat4.lookAt(mat4.create(), camPos, lookAtPos, [0, 1, 0]);
|
||||
var kpos = vec3.clone(kart.pos);
|
||||
if (kart.drifting && !kart.driftLanded && kart.ylock>0) kpos[1] -= kart.ylock;
|
||||
mat4.translate(mat, mat, vec3.scale([], kpos, -1/1024));
|
||||
|
||||
//interpolate visual normal roughly to target
|
||||
camNormal[0] += (kart.kartNormal[0]-camNormal[0])*0.075;
|
||||
camNormal[1] += (kart.kartNormal[1]-camNormal[1])*0.075;
|
||||
camNormal[2] += (kart.kartNormal[2]-camNormal[2])*0.075;
|
||||
vec3.normalize(camNormal, camNormal);
|
||||
|
||||
camAngle += dirDiff(kart.physicalDir+kart.driftOff/2, camAngle)*0.075;
|
||||
camAngle = fixDir(camAngle);
|
||||
|
||||
boostOff += (((kart.boostNorm+kart.boostMT > 0)?5:0) - boostOff)*0.075
|
||||
|
||||
var p = mat4.perspective(mat4.create(), ((70+boostOff)/180)*Math.PI, gl.viewportWidth / gl.viewportHeight, 0.01, 10000.0);
|
||||
|
||||
var dist = 192;
|
||||
this.targetShadowPos = vec3.add([], kart.pos, [Math.sin(kart.angle)*dist, 0, -Math.cos(kart.angle)*dist])
|
||||
|
||||
thisObj.view = {p:p, mv:mat};
|
||||
|
||||
return thisObj.view;
|
||||
}
|
||||
|
||||
function buildBasis() {
|
||||
//order y, x, z
|
||||
var basis = gramShmidt(camNormal, [Math.cos(camAngle), 0, Math.sin(camAngle)], [Math.sin(camAngle), 0, -Math.cos(camAngle)]);
|
||||
var temp = basis[0];
|
||||
basis[0] = basis[1];
|
||||
basis[1] = temp; //todo: cleanup
|
||||
return [
|
||||
basis[0][0], basis[0][1], basis[0][2], 0,
|
||||
basis[1][0], basis[1][1], basis[1][2], 0,
|
||||
basis[2][0], basis[2][1], basis[2][2], 0,
|
||||
0, 0, 0, 1
|
||||
]
|
||||
}
|
||||
|
||||
function gramShmidt(v1, v2, v3) {
|
||||
var u1 = v1;
|
||||
var u2 = vec3.sub([0, 0, 0], v2, project(u1, v2));
|
||||
var u3 = vec3.sub([0, 0, 0], vec3.sub([0, 0, 0], v3, project(u1, v3)), project(u2, v3));
|
||||
return [vec3.normalize(u1, u1), vec3.normalize(u2, u2), vec3.normalize(u3, u3)]
|
||||
}
|
||||
|
||||
function project(u, v) {
|
||||
return vec3.scale([], u, (vec3.dot(u, v)/vec3.dot(u, u)))
|
||||
}
|
||||
|
||||
function fixDir(dir) {
|
||||
return posMod(dir, Math.PI*2);
|
||||
}
|
||||
|
||||
function dirDiff(dir1, dir2) {
|
||||
var d = fixDir(dir1-dir2);
|
||||
return (d>Math.PI)?(-2*Math.PI+d):d;
|
||||
}
|
||||
|
||||
function posMod(i, n) {
|
||||
return (i % n + n) % n;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,118 +0,0 @@
|
||||
//
|
||||
// cameraIntro.js
|
||||
//--------------------
|
||||
// Runs the intro camera for a scene.
|
||||
// by RHY3756547
|
||||
//
|
||||
// includes: main.js
|
||||
//
|
||||
|
||||
window.cameraIntro = function() {
|
||||
|
||||
var thisObj = this;
|
||||
this.kart = kart;
|
||||
this.getView = getView;
|
||||
this.targetShadowPos = [0, 0, 0]
|
||||
|
||||
var mat = mat4.create();
|
||||
|
||||
var curCamNum = -1;
|
||||
var curCam = null;
|
||||
|
||||
var route = null;
|
||||
var routePos = 0;
|
||||
var routeSpeed = 0;
|
||||
var routeProg = 0;
|
||||
var duration = 0;
|
||||
var pointInterp = 0;
|
||||
|
||||
var normalFOV = 70;
|
||||
var zoomLevel = 1;
|
||||
|
||||
var viewW;
|
||||
var viewH;
|
||||
|
||||
function getView(scene, width, height) {
|
||||
if (curCam == null) {
|
||||
restartCam(scene);
|
||||
}
|
||||
viewW = width;
|
||||
viewH = height;
|
||||
|
||||
if (zoomLevel < curCam.zoomMark1) zoomLevel += curCam.zoomSpeedM1;
|
||||
else if (zoomLevel > curCam.zoomMark2) zoomLevel += curCam.zoomSpeedM2;
|
||||
else zoomLevel += curCam.zoomSpeed;
|
||||
|
||||
if (zoomLevel > curCam.zoomEnd) zoomLevel = curCam.zoomEnd;
|
||||
|
||||
if (duration-- < 0) {
|
||||
var cams = scene.nkm.sections["CAME"].entries;
|
||||
if (curCam.nextCam != -1) {
|
||||
curCamNum = curCam.nextCam;
|
||||
curCam = cams[curCamNum];
|
||||
zoomLevel = curCam.zoomStart;
|
||||
|
||||
initCam(scene, curCam)
|
||||
} else {
|
||||
restartCam(scene);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
thisObj.view = camFunc(scene, curCam);
|
||||
}
|
||||
|
||||
function restartCam(scene) {
|
||||
var cams = scene.nkm.sections["CAME"].entries;
|
||||
for (var i=0; i<cams.length; i++) {
|
||||
if (cams[i].firstCam == 2) {
|
||||
curCamNum = i;
|
||||
curCam = cams[curCamNum];
|
||||
zoomLevel = curCam.zoomStart;
|
||||
|
||||
initCam(scene, curCam)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function recalcRouteSpeed() {
|
||||
routeSpeed = (curCam.routeSpeed/100)/60;
|
||||
//(curCam.routeSpeed/20)/vec3.dist(route[routePos].pos, route[(routePos+1)%route.length].pos);
|
||||
}
|
||||
|
||||
var camFunc = function(scene, came) {
|
||||
var camPos = vec3.lerp([], route[routePos].pos, route[(routePos+1)%route.length].pos, routeProg);
|
||||
routeProg += routeSpeed;
|
||||
if (routeProg > 1) {
|
||||
routePos = (routePos+1)%route.length;
|
||||
routeProg = 0;
|
||||
recalcRouteSpeed();
|
||||
}
|
||||
|
||||
pointInterp += (curCam.pointSpeed/100)/60;
|
||||
if (pointInterp > 1) pointInterp = 1;
|
||||
|
||||
var lookAtPos = vec3.lerp([], curCam.pos2, curCam.pos3, pointInterp)
|
||||
|
||||
vec3.scale(camPos, camPos, 1/1024);
|
||||
vec3.scale(lookAtPos, lookAtPos, 1/1024);
|
||||
|
||||
var mat = mat4.lookAt(mat4.create(), camPos, lookAtPos, [0, 1, 0]);
|
||||
var p = mat4.perspective(mat4.create(), (zoomLevel*normalFOV/180)*Math.PI, viewW / viewH, 0.01, 10000.0);
|
||||
|
||||
thisObj.targetShadowPos = lookAtPos;
|
||||
|
||||
return {p:p, mv:mat}
|
||||
}
|
||||
|
||||
var initCam = function(scene, came) {
|
||||
var routes = scene.paths;
|
||||
route = routes[came.camRoute];
|
||||
routePos = 0;
|
||||
routeProg = 0;
|
||||
duration = came.duration;
|
||||
recalcRouteSpeed();
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,216 +0,0 @@
|
||||
//
|
||||
// cameraSpectator.js
|
||||
//--------------------
|
||||
// Spectates a specific kart. Requires NKM AREA and CAME to be set up correctly.
|
||||
// by RHY3756547
|
||||
//
|
||||
// includes: main.js
|
||||
//
|
||||
|
||||
window.cameraSpectator = function(kart) {
|
||||
|
||||
var thisObj = this;
|
||||
this.kart = kart;
|
||||
this.getView = getView;
|
||||
this.targetShadowPos = [0, 0, 0]
|
||||
|
||||
var mat = mat4.create();
|
||||
|
||||
var curCamNum = -1;
|
||||
var curCam = null;
|
||||
|
||||
var route = null;
|
||||
var routePos = 0;
|
||||
var routeSpeed = 0;
|
||||
var routeProg = 0;
|
||||
|
||||
var relPos = [];
|
||||
var posOff = [];
|
||||
|
||||
var normalFOV = 70;
|
||||
var zoomLevel = 1;
|
||||
|
||||
var viewW;
|
||||
var viewH;
|
||||
|
||||
function getView(scene, width, height) {
|
||||
viewW = width;
|
||||
viewH = height;
|
||||
|
||||
var cams = scene.nkm.sections["CAME"].entries;
|
||||
var tArea = getNearestArea(scene.nkm.sections["AREA"].entries, kart.pos)
|
||||
if (tArea.came != curCamNum) {
|
||||
//restart camera.
|
||||
curCamNum = tArea.came;
|
||||
curCam = cams[curCamNum];
|
||||
zoomLevel = curCam.zoomStart;
|
||||
|
||||
initCam[curCam.camType](scene, curCam)
|
||||
}
|
||||
|
||||
if (zoomLevel < curCam.zoomMark1) zoomLevel += curCam.zoomSpeedM1;
|
||||
else if (zoomLevel > curCam.zoomMark2) zoomLevel += curCam.zoomSpeedM2;
|
||||
else zoomLevel += curCam.zoomSpeed;
|
||||
|
||||
if (zoomLevel > curCam.zoomEnd) zoomLevel = curCam.zoomEnd;
|
||||
|
||||
thisObj.view = camFunc[curCam.camType](scene, curCam);
|
||||
return thisObj.view;
|
||||
}
|
||||
|
||||
var camFunc = [];
|
||||
|
||||
camFunc[1] = function(scene, came) {
|
||||
var camPos = vec3.lerp([], route[routePos].pos, route[(routePos+1)%route.length].pos, routeProg);
|
||||
routeProg += routeSpeed;
|
||||
if (routeProg > 1) {
|
||||
routePos = (routePos+1)%route.length;
|
||||
routeProg = 0;
|
||||
recalcRouteSpeed();
|
||||
}
|
||||
|
||||
var lookAtPos = vec3.transformMat4([], [0, 4, 0], kart.mat);
|
||||
|
||||
vec3.scale(camPos, camPos, 1/1024);
|
||||
vec3.scale(lookAtPos, lookAtPos, 1/1024);
|
||||
|
||||
var mat = mat4.lookAt(mat4.create(), camPos, lookAtPos, [0, 1, 0]);
|
||||
var p = mat4.perspective(mat4.create(), (zoomLevel*normalFOV/180)*Math.PI, viewW / viewH, 0.01, 10000.0);
|
||||
|
||||
thisObj.targetShadowPos = kart.pos;
|
||||
|
||||
return {p:p, mv:mat}
|
||||
}
|
||||
|
||||
camFunc[0] = function(scene, came) { //point cam
|
||||
var camPos = vec3.clone(came.pos1);
|
||||
|
||||
var lookAtPos = vec3.transformMat4([], [0, 4, 0], kart.mat);
|
||||
|
||||
vec3.scale(camPos, camPos, 1/1024);
|
||||
vec3.scale(lookAtPos, lookAtPos, 1/1024);
|
||||
|
||||
var mat = mat4.lookAt(mat4.create(), camPos, lookAtPos, [0, 1, 0]);
|
||||
var p = mat4.perspective(mat4.create(), (zoomLevel*normalFOV/180)*Math.PI, viewW / viewH, 0.01, 10000.0);
|
||||
|
||||
thisObj.targetShadowPos = kart.pos;
|
||||
|
||||
return {p:p, mv:mat}
|
||||
}
|
||||
|
||||
camFunc[5] = function(scene, came) { //dash cam
|
||||
var basis = kart.basis;
|
||||
var camPos = vec3.transformMat4([], relPos, basis);
|
||||
var lookAtPos = vec3.transformMat4([], [0, 0, 0], basis);
|
||||
|
||||
vec3.scale(camPos, camPos, 1/1024);
|
||||
vec3.scale(lookAtPos, lookAtPos, 1/1024);
|
||||
|
||||
var mat = mat4.lookAt(mat4.create(), camPos, lookAtPos, [0, 1, 0]);
|
||||
|
||||
var off = mat4.create();
|
||||
mat4.translate(off, off, [-came.pos3[0]/1024, came.pos3[1]/1024, -came.pos3[2]/1024]);
|
||||
mat4.mul(mat, off, mat);
|
||||
|
||||
var kpos = vec3.clone(kart.pos);
|
||||
if (kart.drifting && !kart.driftLanded && kart.ylock>0) kpos[1] -= kart.ylock;
|
||||
mat4.translate(mat, mat, vec3.scale([], kpos, -1/1024));
|
||||
|
||||
var p = mat4.perspective(mat4.create(), (zoomLevel*normalFOV/180)*Math.PI, viewW / viewH, 0.01, 10000.0);
|
||||
|
||||
thisObj.targetShadowPos = kart.pos;
|
||||
|
||||
return {p:p, mv:mat}
|
||||
}
|
||||
|
||||
camFunc[2] = camFunc[0];
|
||||
|
||||
var initCam = [];
|
||||
|
||||
initCam[1] = function(scene, came) {
|
||||
var routes = scene.paths;
|
||||
route = routes[came.camRoute];
|
||||
routePos = 0;
|
||||
routeProg = 0;
|
||||
recalcRouteSpeed();
|
||||
|
||||
}
|
||||
|
||||
initCam[2] = function(scene, came) {
|
||||
}
|
||||
|
||||
function recalcRouteSpeed() {
|
||||
routeSpeed = (curCam.routeSpeed/100)/60;
|
||||
//(curCam.routeSpeed/20)/vec3.dist(route[routePos].pos, route[(routePos+1)%route.length].pos);
|
||||
}
|
||||
|
||||
initCam[5] = function(scene, came) {
|
||||
var mat = mat4.create();
|
||||
mat4.rotateY(mat, mat, (180-came.pos2[0])*(Math.PI/180));
|
||||
mat4.rotateX(mat, mat, -came.pos2[1]*(Math.PI/180));
|
||||
|
||||
|
||||
relPos = vec3.transformMat4([], [0, 0, -came.pos2[2]], mat);
|
||||
/*var basis = kart.basis;
|
||||
relPos = vec3.sub(relPos, came.pos1, kart.pos);
|
||||
vec3.transformMat4(relPos, relPos, mat4.invert([], basis));*/
|
||||
}
|
||||
|
||||
initCam[0] = initCam[2];
|
||||
|
||||
|
||||
function getNearestArea(areas, pos) {
|
||||
var smallestDist = Infinity;
|
||||
var closestArea = null;
|
||||
for (var i=0; i<areas.length; i++) {
|
||||
var a = areas[i];
|
||||
var sub = vec3.sub([], a.pos, pos);
|
||||
vec3.divide(sub, sub, a.dimensions);
|
||||
var dist = Math.sqrt(sub[0]*sub[0] + sub[1]*sub[1] + sub[2]*sub[2]);
|
||||
if (dist<smallestDist && a.came != 255) {
|
||||
smallestDist = dist;
|
||||
closestArea = a;
|
||||
}
|
||||
}
|
||||
return closestArea;
|
||||
}
|
||||
|
||||
function buildBasis() {
|
||||
//order y, x, z
|
||||
var basis = gramShmidt(camNormal, [Math.cos(camAngle), 0, Math.sin(camAngle)], [Math.sin(camAngle), 0, -Math.cos(camAngle)]);
|
||||
var temp = basis[0];
|
||||
basis[0] = basis[1];
|
||||
basis[1] = temp; //todo: cleanup
|
||||
return [
|
||||
basis[0][0], basis[0][1], basis[0][2], 0,
|
||||
basis[1][0], basis[1][1], basis[1][2], 0,
|
||||
basis[2][0], basis[2][1], basis[2][2], 0,
|
||||
0, 0, 0, 1
|
||||
]
|
||||
}
|
||||
|
||||
function gramShmidt(v1, v2, v3) {
|
||||
var u1 = v1;
|
||||
var u2 = vec3.sub([0, 0, 0], v2, project(u1, v2));
|
||||
var u3 = vec3.sub([0, 0, 0], vec3.sub([0, 0, 0], v3, project(u1, v3)), project(u2, v3));
|
||||
return [vec3.normalize(u1, u1), vec3.normalize(u2, u2), vec3.normalize(u3, u3)]
|
||||
}
|
||||
|
||||
function project(u, v) {
|
||||
return vec3.scale([], u, (vec3.dot(u, v)/vec3.dot(u, u)))
|
||||
}
|
||||
|
||||
function fixDir(dir) {
|
||||
return posMod(dir, Math.PI*2);
|
||||
}
|
||||
|
||||
function dirDiff(dir1, dir2) {
|
||||
var d = fixDir(dir1-dir2);
|
||||
return (d>Math.PI)?(-2*Math.PI+d):d;
|
||||
}
|
||||
|
||||
function posMod(i, n) {
|
||||
return (i % n + n) % n;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,336 +0,0 @@
|
||||
//
|
||||
// collisionTypes.js
|
||||
//--------------------
|
||||
// Includes enums for collision types.
|
||||
// by RHY3756547
|
||||
//
|
||||
// includes: gl-matrix.js (glMatrix 2.0)
|
||||
// /formats/kcl.js
|
||||
//
|
||||
|
||||
|
||||
window.MKDS_COLSOUNDS = new function() {
|
||||
this.DRIFT_ASPHALT = 84;
|
||||
this.DRIFT_CONCRETE = 85;
|
||||
this.DRIFT_EDGE = 86; //happens when you hit an edge while drifting?
|
||||
this.DRIFT_DIRT = 87;
|
||||
this.DRIFT_ROAD = 88;
|
||||
this.DRIFT_STONE = 89;
|
||||
this.DRIFT_SAND = 90;
|
||||
this.DRIFT_ICE = 91;
|
||||
this.DRIFT_GLASS = 92;
|
||||
this.DRIFT_WATER = 93;
|
||||
this.DRIFT_BOARD = 94; //boardwalk!
|
||||
this.DRIFT_CARPET = 95; //like luigis mansion
|
||||
this.DRIFT_METALGAUZE = 96;
|
||||
this.DRIFT_PLASTIC = 97;
|
||||
this.DRIFT_RAINBOW = 99;
|
||||
this.DRIFT_MARSH = 100; //luigis mansion
|
||||
|
||||
this.LAND_ASPHALT = 103;
|
||||
this.LAND_SAND = 104;
|
||||
this.LAND_DIRT = 105;
|
||||
this.LAND_ICE = 106;
|
||||
this.LAND_GRASS = 107;
|
||||
this.LAND_SNOW = 108;
|
||||
this.LAND_METALGAUZE = 109;
|
||||
this.LAND_MARSH = 110;
|
||||
this.LAND_WATER = 111;
|
||||
this.LAND_WATERDEEP = 112;
|
||||
this.LAND_CARPET = 113;
|
||||
|
||||
this.DRIVE_DIRT = 114;
|
||||
this.DRIVE_GRASS = 115;
|
||||
this.DRIVE_WATER = 116;
|
||||
this.DRIVE_STONE = 117;
|
||||
this.DRIVE_SAND = 118;
|
||||
this.DRIVE_MARSH = 119;
|
||||
this.DRIVE_CARPET = 120;
|
||||
|
||||
this.HIT_CAR = 128;
|
||||
this.HIT_CONCRETE = 129;
|
||||
this.HIT_FENCE = 130;
|
||||
this.HIT_WOOD = 131;
|
||||
this.HIT_TREE = 132;
|
||||
this.HIT_BUSH = 133;
|
||||
this.HIT_CLIFF = 134;
|
||||
this.HIT_SIGN = 135;
|
||||
this.HIT_ICE = 136;
|
||||
this.HIT_SNOW = 137;
|
||||
this.HIT_TABLE = 138;
|
||||
this.HIT_BOUNCY = 139;
|
||||
this.HIT_JELLY = 140;
|
||||
this.HIT_METALGAUZE = 141;
|
||||
this.HIT_METAL = 142;
|
||||
|
||||
this.BRAKE = 143;
|
||||
this.BRAKE_CONCRETE = 144;
|
||||
this.BRAKE_DIRT = 145;
|
||||
this.BRAKE_STONE = 146;
|
||||
this.BRAKE_ICE = 147;
|
||||
this.BRAKE_GLASS = 148;
|
||||
this.BRAKE_WATER = 149;
|
||||
this.BRAKE_BOARD = 150; //boardwalk
|
||||
this.BRAKE_CARPET = 151;
|
||||
this.BRAKE_METALGAUZE = 152;
|
||||
this.BRAKE_PLASTIC = 153;
|
||||
this.BRAKE_METAL = 154;
|
||||
this.BRAKE_RAINBOW = 155;
|
||||
this.BRAKE_MARSH = 156;
|
||||
|
||||
this.BRAKE_BOOST = 158;
|
||||
|
||||
}
|
||||
|
||||
window.MKDS_COLTYPE = new (function(){
|
||||
this.ROAD = 0x00;
|
||||
this.OFFROADMAIN = 0x01;
|
||||
this.OFFROAD3 = 0x02;
|
||||
this.OFFROAD2 = 0x03;
|
||||
this.RAINBOWFALL = 0x04;
|
||||
this.OFFROAD1 = 0x05;
|
||||
this.SLIPPERY = 0x06;
|
||||
this.BOOST = 0x07;
|
||||
this.WALL = 0x08;
|
||||
this.WALL2 = 0x09;
|
||||
this.OOB = 0x0A; //voids out the player, returns to lakitu checkpoint.
|
||||
this.FALL = 0x0B; //like out of bounds, but you fall through it.
|
||||
this.JUMP_PAD = 0x0C; //jump pads on GBA levels
|
||||
this.STICKY = 0x0D; //sets gravity to negative this plane's normal until the object hasn't collided for a few frames.
|
||||
this.SMALLJUMP = 0x0E; //choco island 2's disaster ramps
|
||||
this.CANNON = 0x0F; //activates cannon. basic effect id is the cannon to use.
|
||||
this.UNKNOWN = 0x10; //it is a mystery...
|
||||
this.FALLSWATER = 0x11; //points to falls object in nkm, gets motion parameters from there.
|
||||
this.BOOST2 = 0x12;
|
||||
this.LOOP = 0x13; //like sticky but with boost applied. see rainbow road ds
|
||||
this.SOUNDROAD = 0x14;
|
||||
this.RR_SPECIAL_WALL = 0x15;
|
||||
|
||||
this.GROUP_ROAD = [
|
||||
this.ROAD, this.OFFROAD1, this.OFFROAD2, this.OFFROAD3, this.OFFROAD4, this.SLIPPERY, this.BOOST,
|
||||
this.JUMP_PAD, this.STICKY, this.SMALLJUMP, this.FALLSWATER, this.BOOST2, this.LOOP, this.SOUNDROAD,
|
||||
this.OOB, this.OFFROADMAIN
|
||||
]
|
||||
|
||||
this.GROUP_SOLID = [
|
||||
this.ROAD, this.OFFROAD1, this.OFFROAD2, this.OFFROAD3, this.OFFROAD4, this.SLIPPERY, this.BOOST,
|
||||
this.JUMP_PAD, this.STICKY, this.SMALLJUMP, this.FALLSWATER, this.BOOST2, this.LOOP, this.SOUNDROAD,
|
||||
this.OOB, this.OFFROADMAIN,
|
||||
|
||||
this.WALL, this.WALL2, this.RR_SPECIAL_WALL
|
||||
]
|
||||
|
||||
this.GROUP_WALL = [
|
||||
this.WALL, this.WALL2, this.RR_SPECIAL_WALL
|
||||
]
|
||||
|
||||
this.GROUP_BOOST = [
|
||||
this.BOOST, this.BOOST2, this.LOOP
|
||||
]
|
||||
|
||||
this.PHYS_MAP = new Array(31);
|
||||
this.PHYS_MAP[this.ROAD] = 0;
|
||||
this.PHYS_MAP[this.OFFROAD3] = 2;
|
||||
this.PHYS_MAP[this.OFFROAD2] = 3;
|
||||
this.PHYS_MAP[this.OFFROAD1] = 4;
|
||||
this.PHYS_MAP[this.OFFROADMAIN] = 5;
|
||||
this.PHYS_MAP[this.SLIPPERY] = 6;
|
||||
this.PHYS_MAP[this.BOOST] = 8;
|
||||
this.PHYS_MAP[this.BOOST2] = 8;
|
||||
this.PHYS_MAP[this.FALLSWATER] = 10;
|
||||
this.PHYS_MAP[this.LOOP] = 11;
|
||||
|
||||
//collision sound handlers
|
||||
|
||||
var waterRoad = {drift: MKDS_COLSOUNDS.DRIFT_WATER, brake: MKDS_COLSOUNDS.BRAKE_WATER, land: MKDS_COLSOUNDS.LAND_WATER, drive: MKDS_COLSOUNDS.DRIVE_WATER};
|
||||
|
||||
this.SOUNDMAP = {
|
||||
0x00: //road
|
||||
[
|
||||
{drift: MKDS_COLSOUNDS.DRIFT_ASPHALT, brake: MKDS_COLSOUNDS.BRAKE, land: MKDS_COLSOUNDS.LAND_ASPHALT},
|
||||
{drift: MKDS_COLSOUNDS.DRIFT_SAND, brake: MKDS_COLSOUNDS.BRAKE_SAND, land: MKDS_COLSOUNDS.LAND_SAND, drive: MKDS_COLSOUNDS.DRIVE_SAND},
|
||||
{drift: MKDS_COLSOUNDS.DRIFT_STONE, brake: MKDS_COLSOUNDS.BRAKE_STONE, land: MKDS_COLSOUNDS.LAND_ASPHALT, drive: MKDS_COLSOUNDS.DRIVE_STONE},
|
||||
{drift: MKDS_COLSOUNDS.DRIFT_CONCRETE, brake: MKDS_COLSOUNDS.BRAKE_CONCRETE, land: MKDS_COLSOUNDS.LAND_ASPHALT},
|
||||
{drift: MKDS_COLSOUNDS.DRIFT_BOARD, brake: MKDS_COLSOUNDS.BRAKE_BOARD, land: MKDS_COLSOUNDS.LAND_ASPHALT},
|
||||
|
||||
{drift: MKDS_COLSOUNDS.DRIFT_ASPHALT, brake: MKDS_COLSOUNDS.BRAKE, land: MKDS_COLSOUNDS.LAND_SNOW}, //snow?
|
||||
|
||||
{drift: MKDS_COLSOUNDS.DRIFT_METALGAUZE, brake: MKDS_COLSOUNDS.BRAKE_METALGAUZE, land: MKDS_COLSOUNDS.LAND_METALGAUZE},
|
||||
{drift: MKDS_COLSOUNDS.DRIFT_ASPHALT, brake: MKDS_COLSOUNDS.BRAKE, land: MKDS_COLSOUNDS.LAND_ASPHALT},
|
||||
],
|
||||
|
||||
0x01: //road 2 the roadening
|
||||
[
|
||||
{drift: MKDS_COLSOUNDS.DRIFT_ASPHALT, brake: MKDS_COLSOUNDS.BRAKE, land: MKDS_COLSOUNDS.LAND_ASPHALT},
|
||||
{drift: MKDS_COLSOUNDS.DRIFT_ASPHALT, brake: MKDS_COLSOUNDS.BRAKE, land: MKDS_COLSOUNDS.LAND_ASPHALT},
|
||||
{drift: MKDS_COLSOUNDS.DRIFT_ASPHALT, brake: MKDS_COLSOUNDS.BRAKE, land: MKDS_COLSOUNDS.LAND_ASPHALT},
|
||||
{drift: MKDS_COLSOUNDS.DRIFT_WATER, brake: MKDS_COLSOUNDS.BRAKE_WATER, land: MKDS_COLSOUNDS.LAND_WATERDEEP, drive: MKDS_COLSOUNDS.DRIVE_WATER},
|
||||
{drift: MKDS_COLSOUNDS.DRIFT_ASPHALT, brake: MKDS_COLSOUNDS.BRAKE, land: MKDS_COLSOUNDS.LAND_ASPHALT},
|
||||
{},
|
||||
{},
|
||||
{}
|
||||
],
|
||||
|
||||
0x02: //road 3
|
||||
[
|
||||
{drift: MKDS_COLSOUNDS.DRIFT_SAND, brake: MKDS_COLSOUNDS.BRAKE_SAND , land: MKDS_COLSOUNDS.LAND_SAND, drive: MKDS_COLSOUNDS.DRIVE_SAND},
|
||||
waterRoad,
|
||||
|
||||
{drift: MKDS_COLSOUNDS.DRIFT_ASPHALT, brake: MKDS_COLSOUNDS.BRAKE, land: MKDS_COLSOUNDS.LAND_SNOW}, //snow
|
||||
|
||||
{drift: MKDS_COLSOUNDS.DRIFT_SAND, brake: MKDS_COLSOUNDS.BRAKE_SAND, land: MKDS_COLSOUNDS.LAND_SAND, drive: MKDS_COLSOUNDS.DRIVE_SAND},
|
||||
{},
|
||||
{},
|
||||
{},
|
||||
{}
|
||||
],
|
||||
|
||||
0x03: //road 4
|
||||
[
|
||||
{drift: MKDS_COLSOUNDS.DRIFT_SAND, brake: MKDS_COLSOUNDS.BRAKE_SAND , land: MKDS_COLSOUNDS.LAND_SAND, drive: MKDS_COLSOUNDS.DRIVE_SAND},
|
||||
{drift: MKDS_COLSOUNDS.DRIFT_DIRT, brake: MKDS_COLSOUNDS.BRAKE_DIRT, land: MKDS_COLSOUNDS.LAND_DIRT, drive: MKDS_COLSOUNDS.DRIVE_DIRT},
|
||||
|
||||
{drift: MKDS_COLSOUNDS.DRIFT_ASPHALT, brake: MKDS_COLSOUNDS.BRAKE, land: MKDS_COLSOUNDS.LAND_GRASS, drive: MKDS_COLSOUNDS.DRIVE_GRASS},
|
||||
|
||||
{drift: MKDS_COLSOUNDS.DRIFT_SAND, brake: MKDS_COLSOUNDS.BRAKE_SAND, land: MKDS_COLSOUNDS.LAND_SAND, drive: MKDS_COLSOUNDS.DRIVE_SAND},
|
||||
{drift: MKDS_COLSOUNDS.DRIFT_SAND, brake: MKDS_COLSOUNDS.BRAKE_SAND, land: MKDS_COLSOUNDS.LAND_SAND, drive: MKDS_COLSOUNDS.DRIVE_SAND},
|
||||
{drift: MKDS_COLSOUNDS.DRIFT_ASPHALT, brake: MKDS_COLSOUNDS.BRAKE, land: MKDS_COLSOUNDS.LAND_SNOW}, //snow
|
||||
{},
|
||||
{}
|
||||
],
|
||||
|
||||
0x05: //road 5
|
||||
[
|
||||
{drift: MKDS_COLSOUNDS.DRIFT_SAND, brake: MKDS_COLSOUNDS.BRAKE_SAND , land: MKDS_COLSOUNDS.LAND_SAND, drive: MKDS_COLSOUNDS.DRIVE_SAND},
|
||||
{drift: MKDS_COLSOUNDS.DRIFT_DIRT, brake: MKDS_COLSOUNDS.BRAKE_DIRT, land: MKDS_COLSOUNDS.LAND_DIRT, drive: MKDS_COLSOUNDS.DRIVE_DIRT},
|
||||
|
||||
{drift: MKDS_COLSOUNDS.DRIFT_ASPHALT, brake: MKDS_COLSOUNDS.BRAKE, land: MKDS_COLSOUNDS.LAND_GRASS, drive: MKDS_COLSOUNDS.DRIVE_GRASS},
|
||||
|
||||
{drift: MKDS_COLSOUNDS.DRIFT_SAND, brake: MKDS_COLSOUNDS.BRAKE_SAND, land: MKDS_COLSOUNDS.LAND_SAND, drive: MKDS_COLSOUNDS.DRIVE_SAND},
|
||||
{drift: MKDS_COLSOUNDS.DRIFT_ASPHALT, brake: MKDS_COLSOUNDS.BRAKE, land: MKDS_COLSOUNDS.LAND_GRASS, drive: MKDS_COLSOUNDS.DRIVE_GRASS},
|
||||
{},
|
||||
{},
|
||||
{}
|
||||
],
|
||||
|
||||
0x06: //slippery
|
||||
[
|
||||
{drift: MKDS_COLSOUNDS.DRIFT_ICE, brake: MKDS_COLSOUNDS.BRAKE_ICE, land:MKDS_COLSOUNDS.LAND_ICE},
|
||||
{drift: MKDS_COLSOUNDS.DRIFT_MARSH, brake: MKDS_COLSOUNDS.BRAKE_MARSH, land:MKDS_COLSOUNDS.LAND_MARSH, drive: MKDS_COLSOUNDS.DRIVE_MARSH},
|
||||
{},
|
||||
{},
|
||||
{},
|
||||
{},
|
||||
{},
|
||||
{}
|
||||
],
|
||||
|
||||
0x07: //bo0st
|
||||
[
|
||||
{drift: MKDS_COLSOUNDS.BRAKE_PLASTIC, brake: MKDS_COLSOUNDS.BRAKE_PLASTIC, land:MKDS_COLSOUNDS.LAND_ASPHALT},
|
||||
{drift: MKDS_COLSOUNDS.BRAKE_PLASTIC, brake: MKDS_COLSOUNDS.BRAKE_PLASTIC, land:MKDS_COLSOUNDS.LAND_ASPHALT},
|
||||
{},
|
||||
{},
|
||||
{},
|
||||
{},
|
||||
{},
|
||||
{}
|
||||
],
|
||||
|
||||
0x08: //wall
|
||||
[//placeholders
|
||||
{hit: MKDS_COLSOUNDS.HIT_CONCRETE},
|
||||
{hit: MKDS_COLSOUNDS.HIT_CLIFF},
|
||||
{hit: MKDS_COLSOUNDS.HIT_SIGN}, //cliff
|
||||
{hit: MKDS_COLSOUNDS.HIT_WOOD},
|
||||
{hit: MKDS_COLSOUNDS.HIT_BUSH},
|
||||
{},
|
||||
{hit: MKDS_COLSOUNDS.HIT_JELLY},
|
||||
{hit: MKDS_COLSOUNDS.HIT_ICE},
|
||||
],
|
||||
|
||||
0x09: //wall 2
|
||||
[
|
||||
{hit: MKDS_COLSOUNDS.HIT_CONCRETE},
|
||||
{hit: MKDS_COLSOUNDS.HIT_STONE},
|
||||
{hit: MKDS_COLSOUNDS.HIT_METAL},
|
||||
{hit: MKDS_COLSOUNDS.HIT_WOOD},
|
||||
{hit: MKDS_COLSOUNDS.HIT_BUSH},
|
||||
{},
|
||||
{hit: MKDS_COLSOUNDS.HIT_JELLY},
|
||||
{hit: MKDS_COLSOUNDS.HIT_ICE},
|
||||
],
|
||||
|
||||
0x10: //wall 3
|
||||
[
|
||||
{hit: MKDS_COLSOUNDS.HIT_CONCRETE},
|
||||
{},
|
||||
{},
|
||||
{},
|
||||
{},
|
||||
{},
|
||||
{},
|
||||
{},
|
||||
],
|
||||
|
||||
0x15: //wall with sound effect
|
||||
[
|
||||
{hit: MKDS_COLSOUNDS.HIT_CONCRETE},
|
||||
{hit: MKDS_COLSOUNDS.HIT_STONE},
|
||||
{hit: MKDS_COLSOUNDS.HIT_RAINBOW}, //only diff i think
|
||||
{hit: MKDS_COLSOUNDS.HIT_WOOD},
|
||||
{hit: MKDS_COLSOUNDS.HIT_BUSH},
|
||||
{},
|
||||
{hit: MKDS_COLSOUNDS.HIT_JELLY},
|
||||
{hit: MKDS_COLSOUNDS.HIT_ICE},
|
||||
],
|
||||
|
||||
0x11: [ //yoshi falls water
|
||||
waterRoad,
|
||||
waterRoad,
|
||||
waterRoad,
|
||||
waterRoad,
|
||||
waterRoad,
|
||||
waterRoad,
|
||||
waterRoad,
|
||||
waterRoad
|
||||
],
|
||||
|
||||
0x12: //boost
|
||||
[
|
||||
{drift: MKDS_COLSOUNDS.BRAKE_PLASTIC, brake: MKDS_COLSOUNDS.BRAKE_PLASTIC, land:MKDS_COLSOUNDS.LAND_ASPHALT},
|
||||
{},
|
||||
{},
|
||||
{},
|
||||
{},
|
||||
{},
|
||||
{},
|
||||
{}
|
||||
],
|
||||
|
||||
0x13: //looping
|
||||
[
|
||||
{drift: MKDS_COLSOUNDS.DRIFT_ASPHALT, brake: MKDS_COLSOUNDS.BRAKE, land:MKDS_COLSOUNDS.LAND_ASPHALT},
|
||||
{drift: MKDS_COLSOUNDS.DRIFT_RAINBOW, brake: MKDS_COLSOUNDS.BRAKE_RAINBOW, land:MKDS_COLSOUNDS.LAND_ASPHALT},
|
||||
{},
|
||||
{},
|
||||
{},
|
||||
{},
|
||||
{},
|
||||
{}
|
||||
],
|
||||
|
||||
0x14: //road with sfx
|
||||
[
|
||||
{},
|
||||
{drift: MKDS_COLSOUNDS.DRIFT_CARPET, brake: MKDS_COLSOUNDS.BRAKE_CARPET, land:MKDS_COLSOUNDS.LAND_CARPET, drive: MKDS_COLSOUNDS.DRIVE_CARPET},
|
||||
{drift: MKDS_COLSOUNDS.DRIFT_RAINBOW, brake: MKDS_COLSOUNDS.BRAKE_RAINBOW, land:MKDS_COLSOUNDS.LAND_ASPHALT},
|
||||
{},
|
||||
{}, //stairs
|
||||
{},
|
||||
{},
|
||||
{}
|
||||
]
|
||||
}
|
||||
|
||||
})()
|
||||
@@ -1,35 +0,0 @@
|
||||
//
|
||||
// controlDefault.js
|
||||
//--------------------
|
||||
// Provides default (keyboard) controls for kart. In future there will be an AI controller and default will support gamepad.
|
||||
// by RHY3756547
|
||||
//
|
||||
// includes: main.js
|
||||
//
|
||||
|
||||
window.controlDefault = function() {
|
||||
|
||||
var thisObj = this;
|
||||
this.local = true;
|
||||
var kart;
|
||||
|
||||
this.setKart = function(k) {
|
||||
kart = k;
|
||||
thisObj.kart = k;
|
||||
}
|
||||
this.fetchInput = fetchInput;
|
||||
|
||||
function fetchInput() {
|
||||
return {
|
||||
accel: keysArray[88], //x
|
||||
decel: keysArray[90], //z
|
||||
drift: keysArray[83], //s
|
||||
item: keysArray[65], //a
|
||||
|
||||
//-1 to 1, intensity.
|
||||
turn: (keysArray[37]?-1:0)+(keysArray[39]?1:0),
|
||||
airTurn: (keysArray[40]?-1:0)+(keysArray[38]?1:0) //air excitebike turn, doesn't really have much function
|
||||
};
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,41 +0,0 @@
|
||||
//
|
||||
// controlDefault.js
|
||||
//--------------------
|
||||
// Provides default (keyboard) controls for kart. In future there will be an AI controller and default will support gamepad.
|
||||
// by RHY3756547
|
||||
//
|
||||
// includes: main.js
|
||||
//
|
||||
|
||||
window.controlNetwork = function() {
|
||||
|
||||
var t = this;
|
||||
var kart;
|
||||
|
||||
this.local = false;
|
||||
this.turn = 0;
|
||||
this.airTurn = 0;
|
||||
this.binput = 0;
|
||||
|
||||
this.setKart = function(k) {
|
||||
kart = k;
|
||||
t.kart = k;
|
||||
}
|
||||
this.fetchInput = fetchInput;
|
||||
|
||||
function fetchInput() {
|
||||
//local controllers generally just return input and handle items - the network controller restores kart data from the stream sent from the server. Obviously this data needs to be verified by the server...
|
||||
|
||||
return {
|
||||
accel: t.binput&1, //x
|
||||
decel: t.binput&2, //z
|
||||
drift: t.binput&4, //s
|
||||
item: false,//keysArray[65], //a
|
||||
|
||||
//-1 to 1, intensity.
|
||||
turn: t.turn,//(keysArray[37]?-1:0)+(keysArray[39]?1:0),
|
||||
airTurn: t.airTurn//(keysArray[40]?-1:0)+(keysArray[38]?1:0) //air excitebike turn, doesn't really have much function
|
||||
};
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,141 +0,0 @@
|
||||
//
|
||||
// controlRaceCPU.js
|
||||
//--------------------
|
||||
// Provides AI control for default races
|
||||
// by RHY3756547
|
||||
//
|
||||
// includes: main.js
|
||||
//
|
||||
|
||||
window.controlRaceCPU = function(nkm) {
|
||||
|
||||
var thisObj = this;
|
||||
var kart;
|
||||
|
||||
this.setKart = function(k) {
|
||||
kart = k;
|
||||
thisObj.kart = k;
|
||||
calcDestNorm();
|
||||
}
|
||||
|
||||
this.fetchInput = fetchInput;
|
||||
|
||||
var battleMode = (nkm.sections["EPAT"] == null);
|
||||
|
||||
var paths, points;
|
||||
if (battleMode) { //MEEPO!!
|
||||
var paths = nkm.sections["MEPA"].entries;
|
||||
var points = nkm.sections["MEPO"].entries;
|
||||
} else {
|
||||
var paths = nkm.sections["EPAT"].entries;
|
||||
var points = nkm.sections["EPOI"].entries;
|
||||
}
|
||||
|
||||
var ePath = paths[0];
|
||||
var ePoiInd = ePath.startInd;
|
||||
var ePoi = points[ePath.startInd];
|
||||
|
||||
var posOffset = [0, 0, 0];
|
||||
var destOff = [0, 0, 0];
|
||||
var offTrans = 0;
|
||||
chooseNewOff();
|
||||
|
||||
var destNorm;
|
||||
var destConst;
|
||||
var destPoint;
|
||||
|
||||
function fetchInput() {
|
||||
//basically as a cpu, we're really dumb and need a constant supply of points to drive to.
|
||||
//battle mode AI is a lot more complex, but since we're only going in one direction it can be kept simple.
|
||||
|
||||
var accel = true; //currently always driving forward. should change for sharp turns and when we get stuck on a wall
|
||||
//(drive in direction of wall? we may need to reverse, "if stuck for too long we can just call lakitu and the players won't even notice" - Nintendo)
|
||||
|
||||
var dist = vec3.dot(destNorm, kart.pos) + destConst;
|
||||
if (dist < ePoi.pointSize) advancePoint();
|
||||
|
||||
destPoint = vec3.add([], ePoi.pos, vec3.scale([], vec3.lerp([], posOffset, destOff, offTrans), ePoi.pointSize));
|
||||
var dirToPt = Math.atan2(destPoint[0]-kart.pos[0], kart.pos[2]-destPoint[2]);
|
||||
|
||||
var diff = dirDiff(dirToPt, kart.physicalDir);
|
||||
var turn = Math.min(Math.max(-1, (diff*3)), 1);
|
||||
|
||||
offTrans += 1/240;
|
||||
|
||||
if (offTrans >= 1) chooseNewOff();
|
||||
|
||||
return {
|
||||
accel: accel, //x
|
||||
decel: false, //z
|
||||
drift: false, //s
|
||||
item: false, //a
|
||||
|
||||
//-1 to 1, intensity.
|
||||
turn: turn,
|
||||
airTurn: 0 //air excitebike turn, doesn't really have much function
|
||||
};
|
||||
}
|
||||
|
||||
function chooseNewOff() {
|
||||
posOffset = destOff;
|
||||
var ang = Math.random()*Math.PI*2;
|
||||
var strength = Math.random();
|
||||
destOff = [Math.sin(ang)*strength, 0, Math.cos(ang)*strength];
|
||||
offTrans = 0;
|
||||
}
|
||||
|
||||
|
||||
function calcDestNorm() {
|
||||
var norm = vec3.sub([], kart.pos, ePoi.pos);
|
||||
vec3.normalize(norm, norm);
|
||||
|
||||
destNorm = norm;
|
||||
destConst = -vec3.dot(ePoi.pos, norm)
|
||||
|
||||
}
|
||||
|
||||
function advancePoint() {
|
||||
if (++ePoiInd < ePath.startInd+ePath.pathLen) {
|
||||
//next within this path
|
||||
ePoi = points[ePoiInd];
|
||||
} else {
|
||||
//advance to one of next possible paths
|
||||
|
||||
if (battleMode) {
|
||||
var pathInd = ((Math.random()>0.5 && ePath.source.length>0)?ePath.source:ePath.dest)[Math.floor(Math.random()*ePath.dest.length)];
|
||||
ePoiInd = pathInd;
|
||||
ePoi = points[ePoiInd];
|
||||
recomputePath();
|
||||
} else {
|
||||
var pathInd = ePath.dest[Math.floor(Math.random()*ePath.dest.length)];
|
||||
ePath = paths[pathInd];
|
||||
ePoi = points[ePath.startInd];
|
||||
ePoiInd = ePath.startInd;
|
||||
}
|
||||
}
|
||||
calcDestNorm();
|
||||
}
|
||||
|
||||
function recomputePath() { //use if point is set by anything but the path system, eg. respawn
|
||||
for (var i=0; i<paths.length; i++) {
|
||||
var rel = (ePoiInd-paths[i].startInd);
|
||||
if (rel >= 0 && rel < paths[i].pathLen) {
|
||||
ePath = paths[i];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function fixDir(dir) {
|
||||
return posMod(dir, Math.PI*2);
|
||||
}
|
||||
|
||||
function dirDiff(dir1, dir2) {
|
||||
var d = fixDir(dir1-dir2);
|
||||
return (d>Math.PI)?(-2*Math.PI+d):d;
|
||||
}
|
||||
|
||||
function posMod(i, n) {
|
||||
return (i % n + n) % n;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,100 +0,0 @@
|
||||
//
|
||||
// ingameRes.js
|
||||
//--------------------
|
||||
// Provides access to general ingame resources.
|
||||
// by RHY3756547
|
||||
//
|
||||
|
||||
window.IngameRes = function(rom) {
|
||||
var r = this;
|
||||
this.kartPhys = new kartphysicalparam(rom.getFile("/data/KartModelMenu/kartphysicalparam.bin"));
|
||||
this.kartOff = new kartoffsetdata(rom.getFile("/data/KartModelMenu/kartoffsetdata.bin"));
|
||||
this.MapObj = new narc(lz77.decompress(rom.getFile("/data/Main/MapObj.carc"))); //contains generic map obj, look in here when mapobj res is missing from course. (itembox etc)
|
||||
this.MainRace = new narc(lz77.decompress(rom.getFile("/data/MainRace.carc"))); //contains item models.
|
||||
this.MainEffect = new narc(lz77.decompress(rom.getFile("/data/MainEffect.carc"))); //contains particles.
|
||||
this.Main2D = new narc(lz77.decompress(rom.getFile("/data/Main2D.carc")));
|
||||
|
||||
this.KartModelSub = new narc(lz77.decompress(rom.getFile("/data/KartModelSub.carc"))); //contains characters + animations
|
||||
|
||||
this.Race = new narc(lz77.decompress(rom.getFile("/data/Scene/Race.carc"))); //contains lakitu, count, various graphics
|
||||
this.RaceLoc = new narc(lz77.decompress(rom.getFile("/data/Scene/Race_us.carc"))); //contains lakitu lap signs, START, YOU WIN etc. some of these will be replaced by hi res graphics by default.
|
||||
|
||||
this.MainFont = new nftr(r.Main2D.getFile("marioFont.NFTR"));
|
||||
//debugger;
|
||||
|
||||
this.getChar = getChar;
|
||||
this.getKart = getKart;
|
||||
|
||||
var itemNames = [
|
||||
"banana", "bomb", "gesso" /*squid*/, "kinoko" /*mushroom*/, "kinoko_p" /*queen shroom*/, "koura_g" /*green shell*/, "koura_r" /*red shell*/, "star", "teresa" /*boo*/, "thunder",
|
||||
"koura_w" /*blue shell item rep*/, "f_box", "killer" /*bullet bill*/
|
||||
]
|
||||
|
||||
var charNames = [
|
||||
"mario", "donkey", "kinopio", "koopa", "peach", "wario", "yoshi", "luigi", "karon", "daisy", "waluigi", "robo", "heyho"
|
||||
]
|
||||
|
||||
var charAbbrv = [
|
||||
"MR", "DK", "KO", "KP", "PC", "WR", "YS", "LG", "KA", "DS", "WL", "RB", "HH"
|
||||
]
|
||||
|
||||
var tireName = ["kart_tire_L", "kart_tire_M", "kart_tire_S"];
|
||||
|
||||
var characters = [];
|
||||
var karts = [];
|
||||
|
||||
loadItems();
|
||||
loadTires();
|
||||
|
||||
function loadItems() { //loads physical representations of items
|
||||
var t = {}
|
||||
for (var i=0; i<itemNames.length; i++) {
|
||||
var n = itemNames[i];
|
||||
t[n] = new nitroModel(new nsbmd(r.MainRace.getFile("/Item/it_"+n+".nsbmd")));
|
||||
}
|
||||
t.blueShell = new nitroModel(new nsbmd(r.MainRace.getFile("/Item/koura_w.nsbmd")));
|
||||
t.splat = new nitroModel(new nsbmd(r.MainRace.getFile("/Item/geso_sumi.nsbmd")));
|
||||
r.items = t;
|
||||
}
|
||||
|
||||
function loadTires() {
|
||||
var path = "/data/KartModelMenu/kart/tire/";
|
||||
var tires = {};
|
||||
for (var i=0; i<tireName.length; i++) tires[tireName[i]] = new nitroModel(new nsbmd(rom.getFile(path+tireName[i]+".nsbmd")), new nsbtx(rom.getFile(path+tireName[i]+".nsbtx")));
|
||||
r.tireRes = tires;
|
||||
}
|
||||
|
||||
function getChar(ind) {
|
||||
if (characters[ind] != null) return characters[ind];
|
||||
var base = "/character/"+charNames[ind]+"/P_"+charAbbrv[ind];
|
||||
|
||||
var obj = {
|
||||
model: new nitroModel(new nsbmd(r.KartModelSub.getFile(base+".nsbmd")), new nsbtx(r.KartModelSub.getFile(base+".nsbtx")), {tex:{1:2}, pal:{1:2}}),
|
||||
driveA: new nsbca(r.KartModelSub.getFile(base+"_drive.nsbca")),
|
||||
loseA: new nsbca(r.KartModelSub.getFile(base+"_lose.nsbca")),
|
||||
spinA: new nsbca(r.KartModelSub.getFile(base+"_spin.nsbca")),
|
||||
winA: new nsbca(r.KartModelSub.getFile(base+"_win.nsbca")),
|
||||
}
|
||||
characters[ind] = obj;
|
||||
return characters[ind];
|
||||
}
|
||||
|
||||
var letters = ["a", "b", "c"]
|
||||
|
||||
function getKart(ind) { //returns a nitroModel, but also includes a property "shadVol" containing the kart's shadow volume.
|
||||
if (karts[ind] != null) return karts[ind];
|
||||
var c = Math.floor(ind/3);
|
||||
var t = ind%3;
|
||||
if (t == 0) c = 0; //only mario has standard kart
|
||||
|
||||
var name = charAbbrv[c]+"_"+letters[t];
|
||||
var path = "/data/KartModelMenu/kart/"+charNames[c]+"/kart_"+name;
|
||||
|
||||
var model = new nitroModel(new nsbmd(rom.getFile(path+".nsbmd")), new nsbtx(rom.getFile(path+".nsbtx")));
|
||||
model.shadVol = new nitroModel(new nsbmd(rom.getFile("/data/KartModelMenu/kart/shadow/sh_"+name+".nsbmd")));
|
||||
//todo, assign special pallete for A karts
|
||||
|
||||
karts[ind] = model;
|
||||
return karts[ind];
|
||||
}
|
||||
}
|
||||
@@ -1,114 +0,0 @@
|
||||
//
|
||||
// itemController.js
|
||||
//--------------------
|
||||
// An item controller for scenes. Allows items to be synced to multiple clients.
|
||||
// by RHY3756547
|
||||
//
|
||||
// includes: gl-matrix.js (glMatrix 2.0)
|
||||
//
|
||||
|
||||
window.ItemController = function(scene) {
|
||||
var t = this;
|
||||
t.scene = scene;
|
||||
t.items = [];
|
||||
t.curInd = 0; //next item index. Max value is insanely high so there shouldn't be much of a problem.
|
||||
t.cliID = 0; //client id, used along with item index to specify your items.
|
||||
t.time = 0;
|
||||
|
||||
t.addItem = addItem;
|
||||
t.changeItem = changeItem;
|
||||
t.update = update;
|
||||
t.draw = draw;
|
||||
|
||||
var RedShell, Banana, Bomb, BlueShell, Star, MultiItem, Shroom, TripleShroom, QueenShroom, Bullet, Ghost, Squid //these are all null
|
||||
|
||||
var itemFunc = [
|
||||
GreenShell,
|
||||
RedShell,
|
||||
Banana,
|
||||
Bomb,
|
||||
BlueShell,
|
||||
Star,
|
||||
MultiItem, //triple shells, lucky 7 if you're into that kind of thing
|
||||
Shroom,
|
||||
TripleShroom,
|
||||
QueenShroom,
|
||||
Bullet,
|
||||
Ghost,
|
||||
Squid
|
||||
]
|
||||
|
||||
function update(scene) {
|
||||
var itC = t.items.slice(0);
|
||||
for (var i=0; i<itC.length; i++) {
|
||||
var ent = itC[i];
|
||||
ent.update(scene);
|
||||
}
|
||||
}
|
||||
|
||||
function draw(mvMatrix, pMatrix, gl) {
|
||||
for (var i=0; i<t.items.length; i++) {
|
||||
var e = t.items[i];
|
||||
t.items[i].draw(mvMatrix, pMatrix, gl);
|
||||
}
|
||||
}
|
||||
|
||||
function addItem(type, ownerKart, params) {
|
||||
//sends add item packet. params: itemID, time, params, itemType
|
||||
var p = {
|
||||
t:"a",
|
||||
i:t.itemID++,
|
||||
c:t.cliID,
|
||||
d:t.time,
|
||||
f:type,
|
||||
o:ownerKart,
|
||||
p:params
|
||||
}
|
||||
|
||||
resvPacket(p); //instantly respond to own packets
|
||||
}
|
||||
|
||||
function changeItem(item, funcNum, reason, params) {
|
||||
//sends change item packet. params: itemID, cliID, function, reason, params
|
||||
var p = {
|
||||
t:"c",
|
||||
i:item.itemID,
|
||||
c:item.cliID,
|
||||
f:funcNum,
|
||||
r:reason,
|
||||
p:params
|
||||
}
|
||||
|
||||
resvPacket(p); //instantly respond to own packets
|
||||
}
|
||||
|
||||
function resvPacket(p) {
|
||||
switch (p.t) {
|
||||
case "ci":
|
||||
var func = itemFunc[p.f];
|
||||
if (func != null) {
|
||||
var item = new func(scene, scene.karts[p.o], p.d, p.i, p.c, p.p);
|
||||
t.items.push(item);
|
||||
} else console.error("item id incorrect??")
|
||||
break;
|
||||
case "~i":
|
||||
var it = getItemObj(p.c, p.i);
|
||||
if (it != null) {
|
||||
var func = it.cFunc[p.f];
|
||||
if (func != null) {
|
||||
func(p.r, p.p);
|
||||
} else console.error("invalid item change function, maybe wrong type?")
|
||||
} else console.error("attempt to modify item that is either dead or does not exist")
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
function getItemObj(cli, id) {
|
||||
for (var i=0; i<t.items.length; i++) {
|
||||
var item = t.items[i];
|
||||
if (item.cliID == cli && item.itemID == id) {
|
||||
return item;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,303 +0,0 @@
|
||||
//
|
||||
// largeSphereCollider.js
|
||||
//--------------------
|
||||
// Provides functions to detect collision against sets of triangles for swept ellipsoids and small rays (low cost, used for green shells).
|
||||
// by RHY3756547
|
||||
//
|
||||
// includes: gl-matrix.js (glMatrix 2.0)
|
||||
// /formats/kcl.js
|
||||
//
|
||||
|
||||
window.lsc = new (function() {
|
||||
|
||||
this.raycast = raycast;
|
||||
this.sweepEllipse = sweepEllipse;
|
||||
this.pointInTriangle = pointInTriangle; //expose this because its kinda useful
|
||||
|
||||
function raycast(pos, dir, kclO, error, ignoreList) { //used for shells, bananas and spammable items. Much faster than sphere sweep. Error used to avoid falling through really small seams between tris.
|
||||
var error = (error==null)?0:error;
|
||||
var t=1;
|
||||
var tris = getTriList(pos, dir, kclO);
|
||||
var colPlane = null;
|
||||
var colPoint = null; //can be calculated from t, but we calculate it anyway so why not include
|
||||
for (var i=0; i<tris.length; i++) {
|
||||
//first, check if we intersect the plane within reasonable t.
|
||||
//only if this happens do we check if the point is in the triangle.
|
||||
//we would also only do sphere sweep if this happens.
|
||||
|
||||
var tri = tris[i];
|
||||
|
||||
if (ignoreList.indexOf(tri) != -1) continue;
|
||||
|
||||
var planeConst = -vec3.dot(tri.Normal, tri.Vertex1);
|
||||
var dist = vec3.dot(tri.Normal, pos) + planeConst;
|
||||
var modDir = vec3.dot(tri.Normal, dir);
|
||||
if (dist < 0 || modDir == 0) continue; //can't collide with back side of polygons! also can't intersect plane with ray perpendicular to plane
|
||||
var newT = -dist/modDir;
|
||||
if (newT>0 && newT<t) {
|
||||
//we have a winner! check if the plane intersecion point is in the triangle.
|
||||
var pt = vec3.add([], pos, vec3.scale([], dir, newT))
|
||||
if (pointInTriangle(tri, pt, error)) {
|
||||
t = newT;
|
||||
colPlane = tri;
|
||||
colPoint = pt; //result!
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (colPlane != null) {
|
||||
return {
|
||||
t: t,
|
||||
plane: colPlane,
|
||||
colPoint: colPoint,
|
||||
normal: colPlane.Normal
|
||||
}
|
||||
} else return null;
|
||||
}
|
||||
|
||||
function modTri(tri, mat) {
|
||||
var obj = {};
|
||||
obj.Vertex1 = vec3.transformMat4([], tri.Vertex1, mat);
|
||||
obj.Vertex2 = vec3.transformMat4([], tri.Vertex2, mat);
|
||||
obj.Vertex3 = vec3.transformMat4([], tri.Vertex3, mat);
|
||||
|
||||
obj.Normal = vec3.transformMat3([], tri.Normal, mat3.fromMat4([], mat));
|
||||
vec3.normalize(obj.Normal, obj.Normal);
|
||||
obj.CollisionType = tri.CollisionType;
|
||||
return obj;
|
||||
}
|
||||
|
||||
function scaleTri(tri, eDim) {
|
||||
var obj = {};
|
||||
obj.Vertex1 = vec3.divide([], tri.Vertex1, eDim);
|
||||
obj.Vertex2 = vec3.divide([], tri.Vertex2, eDim);
|
||||
obj.Vertex3 = vec3.divide([], tri.Vertex3, eDim);
|
||||
|
||||
obj.Normal = tri.Normal
|
||||
obj.CollisionType = tri.CollisionType;
|
||||
return obj;
|
||||
}
|
||||
|
||||
var t, colPlane, colPoint, emb, edge, colO, planeNormal;
|
||||
|
||||
function sweepEllipse(pos, dir, scn, eDimensions, ignoreList) { //used for karts or things that need to occupy physical space.
|
||||
t=1;
|
||||
|
||||
var ed = vec3.divide([], [1, 1, 1], eDimensions);
|
||||
|
||||
var tris = getTriList(pos, dir, scn.kcl);
|
||||
|
||||
var oPos = pos;
|
||||
var oDir = dir;
|
||||
|
||||
var pos = vec3.divide([], pos, eDimensions); //need to rescale position to move into ellipsoid space
|
||||
var dir = vec3.divide([], dir, eDimensions);
|
||||
|
||||
colPlane = null;
|
||||
colPoint = null; //can be calculated from t, but we calculate it anyway so why not include
|
||||
emb = false;
|
||||
edge = false;
|
||||
|
||||
ellipseVTris(pos, dir, tris, eDimensions, ignoreList, true);
|
||||
|
||||
for (var i=0; i<scn.colEnt.length; i++) {
|
||||
var c = scn.colEnt[i];
|
||||
var col = c.getCollision();
|
||||
|
||||
if (vec3.distance(oPos, c.pos) < c.colRad) {
|
||||
ellipseVTris(pos, dir, col.tris, mat4.mul([], mat4.scale([], mat4.create(), ed), col.mat), ignoreList, false, c);
|
||||
}
|
||||
}
|
||||
|
||||
if (colPlane != null) {
|
||||
var norm = vec3.scale([], dir, t)
|
||||
vec3.add(norm, pos, norm);
|
||||
vec3.sub(norm, norm, colPoint);
|
||||
|
||||
if (Math.sqrt(vec3.dot(norm, norm)) < 0.98) emb = true;
|
||||
|
||||
vec3.mul(colPoint, colPoint, eDimensions);
|
||||
|
||||
return {
|
||||
t: t,
|
||||
plane: colPlane,
|
||||
colPoint: colPoint,
|
||||
normal: norm,
|
||||
pNormal: planeNormal,
|
||||
embedded: emb,
|
||||
object: colO
|
||||
}
|
||||
} else return null;
|
||||
}
|
||||
|
||||
function ellipseVTris(pos, dir, tris, mat, ignoreList, eDims, targ) {
|
||||
for (var i=0; i<tris.length; i++) {
|
||||
//first, check if we intersect the plane within reasonable t.
|
||||
//only if this happens do we check if the point is in the triangle.
|
||||
//we would also only do sphere sweep if this happens.
|
||||
|
||||
var oTri = tris[i];
|
||||
if (ignoreList.indexOf(oTri) != -1) continue;
|
||||
|
||||
var tri = (eDims)?scaleTri(tris[i], mat):modTri(tris[i], mat);
|
||||
var planeConst = -vec3.dot(tri.Normal, tri.Vertex1);
|
||||
var dist = vec3.dot(tri.Normal, pos) + planeConst;
|
||||
var modDir = vec3.dot(tri.Normal, dir);
|
||||
|
||||
if (dist < 0) continue; //can't collide with back side of polygons! also can't intersect plane with ray perpendicular to plane
|
||||
|
||||
var t0, t1, embedded = false;
|
||||
if (modDir == 0) {
|
||||
if (Math.abs(dist) < 1) {
|
||||
t0 = 0;
|
||||
t1 = 1;
|
||||
embedded = true;
|
||||
} else {
|
||||
t0 = 1000;
|
||||
t1 = 2000;
|
||||
}
|
||||
} else {
|
||||
t0 = (1-dist)/modDir;
|
||||
t1 = ((-1)-dist)/modDir;
|
||||
}
|
||||
|
||||
if (t0 > t1) { //make sure t0 is smallest value
|
||||
var temp = t1;
|
||||
t1 = t0;
|
||||
t0 = temp;
|
||||
}
|
||||
|
||||
if (!(t0>1 || t1<0)) {
|
||||
//we will intersect this triangle's plane within this frame.
|
||||
//
|
||||
// Three things can happen for the earliest intersection:
|
||||
// - sphere intersects plane of triangle (pt on plane projected from new position is inside triangle)
|
||||
// - sphere intersects edge of triangle
|
||||
// - sphere intersects point of triangle
|
||||
|
||||
if (t0 < 0) { embedded = true; t0 = 0; }
|
||||
if (t1 > 1) t1 = 1;
|
||||
|
||||
var newT = t0;
|
||||
|
||||
//sphere intersects plane of triangle
|
||||
var pt = [];
|
||||
if (embedded) {
|
||||
vec3.sub(pt, pos, vec3.scale([], tri.Normal, dist));
|
||||
} else {
|
||||
vec3.add(pt, pos, vec3.scale([], dir, newT))
|
||||
vec3.sub(pt, pt, tri.Normal); //project new position onto plane along normal
|
||||
}
|
||||
if (pointInTriangle(tri, pt, 0) && newT<t) {
|
||||
t = newT;
|
||||
colPlane = oTri;
|
||||
colPoint = pt; //result!
|
||||
colO = targ;
|
||||
edge = false;
|
||||
emb = embedded;
|
||||
planeNormal = tri.Normal;
|
||||
continue;
|
||||
}
|
||||
|
||||
//no inside intersection check vertices:
|
||||
for (var j=1; j<=3; j++) {
|
||||
var vert = vec3.sub([], pos, tri["Vertex"+j]);
|
||||
var root = getSmallestRoot(vec3.dot(dir, dir), 2*vec3.dot(dir, vert), vec3.dot(vert, vert)-1, t);
|
||||
if (root != null) {
|
||||
t = root;
|
||||
colPlane = oTri;
|
||||
colO = targ;
|
||||
colPoint = vec3.clone(tri["Vertex"+j]); //result!
|
||||
planeNormal = tri.Normal;
|
||||
edge = false;
|
||||
}
|
||||
}
|
||||
|
||||
//... and lines
|
||||
|
||||
for (var j=1; j<=3; j++) {
|
||||
var vert = tri["Vertex"+j];
|
||||
var nextV = tri["Vertex"+((j%3)+1)];
|
||||
|
||||
var distVert = vec3.sub([], vert, pos);
|
||||
var distLine = vec3.sub([], nextV, vert);
|
||||
|
||||
var edgeDist = vec3.dot(distLine, distLine);
|
||||
var edgeDotVelocity = vec3.dot(distLine, dir);
|
||||
var edgeDotVert = vec3.dot(distVert, distLine);
|
||||
|
||||
var root = getSmallestRoot(
|
||||
edgeDist*(-1)*vec3.dot(dir, dir) + edgeDotVelocity*edgeDotVelocity,
|
||||
edgeDist*2*vec3.dot(dir, distVert) - 2*edgeDotVelocity*edgeDotVert,
|
||||
edgeDist*(1-vec3.dot(distVert, distVert)) + edgeDotVert*edgeDotVert,
|
||||
t
|
||||
);
|
||||
|
||||
if (root != null) {
|
||||
var edgePos = (edgeDotVelocity*root - edgeDotVert)/edgeDist;
|
||||
|
||||
if (edgePos >= 0 && edgePos <= 1) {
|
||||
t = root;
|
||||
colPlane = oTri;
|
||||
colO = targ;
|
||||
colPoint = vec3.add([], vert, vec3.scale(distLine, distLine, edgePos)); //result!
|
||||
planeNormal = tri.Normal;
|
||||
edge = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function getSmallestRoot(a, b, c, upperLimit) {
|
||||
var det = (b*b) - 4*(a*c);
|
||||
if (det<0) return null; //no result :'(
|
||||
else {
|
||||
det = Math.sqrt(det);
|
||||
var root1 = ((-b)-det)/(2*a)
|
||||
var root2 = ((-b)+det)/(2*a)
|
||||
|
||||
if (root1 > root2) { //ensure root1 is smallest
|
||||
var temp = root1;
|
||||
root1 = root2;
|
||||
root2 = temp;
|
||||
}
|
||||
|
||||
if (root1>0 && root1<upperLimit) {
|
||||
return root1;
|
||||
} else if (root2>0 && root2<upperLimit) {
|
||||
return root2;
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function pointInTriangle(tri, point, error) { //barycentric check
|
||||
//compute direction vectors to the other verts and the point
|
||||
var v0 = vec3.sub([], tri.Vertex3, tri.Vertex1);
|
||||
var v1 = vec3.sub([], tri.Vertex2, tri.Vertex1);
|
||||
var v2 = vec3.sub([], point, tri.Vertex1);
|
||||
|
||||
//we need to find u and v across the two vectors v0 and v1 such that adding them will result in our point's position
|
||||
//where the unit length of both vectors v0 and v1 is 1, the sum of both u and v should not exceed 1 and neither should be negative
|
||||
|
||||
var dot00 = vec3.dot(v0, v0); var dot01 = vec3.dot(v0, v1); var dot02 = vec3.dot(v0, v2);
|
||||
var dot11 = vec3.dot(v1, v1); var dot12 = vec3.dot(v1, v2);
|
||||
//dot11 and dot00 result in the square of the distance for v0 and v1
|
||||
|
||||
var inverse = 1/(dot00*dot11 - dot01*dot01);
|
||||
var u = (dot11*dot02 - dot01*dot12)*inverse;
|
||||
var v = (dot00*dot12 - dot01*dot02)*inverse;
|
||||
|
||||
return (u>=-error && v>=-error && (u+v)<1+error);
|
||||
}
|
||||
|
||||
function getTriList(pos, diff, kclO) { //gets tris from kcl around a line. currently only fetches from middle point of line, but should include multiple samples for large differences in future.
|
||||
var sample = vec3.add([], pos, vec3.scale([], diff, 0.5))
|
||||
return kclO.getPlanesAt(sample[0], sample[1], sample[2]);
|
||||
}
|
||||
|
||||
})();
|
||||
@@ -1,113 +0,0 @@
|
||||
//
|
||||
// mkdsConst.js
|
||||
//--------------------
|
||||
// Provides various game constants.
|
||||
// by RHY3756547
|
||||
//
|
||||
|
||||
window.MKDSCONST = new (function() {
|
||||
|
||||
this.COURSEDIR = "/data/Course/";
|
||||
|
||||
this.COURSES = [ //in order of course id, nitro through retro
|
||||
"cross_course",
|
||||
"bank_course",
|
||||
"beach_course",
|
||||
"mansion_course",
|
||||
|
||||
"desert_course",
|
||||
"town_course",
|
||||
"pinball_course",
|
||||
"ridge_course",
|
||||
|
||||
"snow_course",
|
||||
"clock_course",
|
||||
"mario_course",
|
||||
"airship_course",
|
||||
|
||||
"stadium_course",
|
||||
"garden_course",
|
||||
"koopa_course",
|
||||
"rainbow_course",
|
||||
|
||||
|
||||
"old_mario_sfc",
|
||||
"old_momo_64",
|
||||
"old_peach_agb",
|
||||
"old_luigi_gc",
|
||||
|
||||
"old_donut_sfc",
|
||||
"old_frappe_64",
|
||||
"old_koopa_agb",
|
||||
"old_baby_gc",
|
||||
|
||||
"old_noko_sfc",
|
||||
"old_choco_64",
|
||||
"old_luigi_agb",
|
||||
"old_kinoko_gc",
|
||||
|
||||
"old_choco_sfc",
|
||||
"old_hyudoro_64",
|
||||
"old_sky_agb",
|
||||
"old_yoshi_gc",
|
||||
|
||||
"mini_stage1",
|
||||
"mini_stage2",
|
||||
"mini_stage3",
|
||||
"mini_stage4",
|
||||
"mini_block_64",
|
||||
"mini_dokan_gc"
|
||||
|
||||
]
|
||||
|
||||
this.COURSE_MUSIC = [
|
||||
74,
|
||||
16,
|
||||
15,
|
||||
21,
|
||||
|
||||
38,
|
||||
17,
|
||||
19,
|
||||
36,
|
||||
|
||||
37,
|
||||
39,
|
||||
74,
|
||||
18,
|
||||
|
||||
19,
|
||||
20,
|
||||
40,
|
||||
41,
|
||||
|
||||
|
||||
22,
|
||||
30,
|
||||
26,
|
||||
33,
|
||||
|
||||
24,
|
||||
31,
|
||||
27,
|
||||
34,
|
||||
|
||||
23,
|
||||
29,
|
||||
26,
|
||||
35,
|
||||
|
||||
25,
|
||||
32,
|
||||
28,
|
||||
33,
|
||||
|
||||
43,
|
||||
43,
|
||||
43,
|
||||
43,
|
||||
43,
|
||||
43
|
||||
]
|
||||
|
||||
})();
|
||||
@@ -1,156 +0,0 @@
|
||||
//
|
||||
// clientScene.js
|
||||
//--------------------
|
||||
// Manages the game state when connected to a server. Drives the course scene and track picker.
|
||||
// by RHY3756547
|
||||
//
|
||||
|
||||
window.clientScene = function(wsUrl, wsInstance, res) {
|
||||
var res = res; //gameRes
|
||||
var t = this;
|
||||
|
||||
var WebSocket = window.WebSocket || window.MozWebSocket;
|
||||
var ws = new WebSocket(wsUrl);
|
||||
ws.binaryType = "arraybuffer";
|
||||
|
||||
t.ws = ws;
|
||||
t.mode = -1;
|
||||
t.activeScene = null;
|
||||
t.myKart = null;
|
||||
|
||||
ws.onopen = function() {
|
||||
console.log("initial connection")
|
||||
//first we need to establish connection to the instance.
|
||||
var obj = {
|
||||
t:"*",
|
||||
i:wsInstance,
|
||||
c:{
|
||||
name:"TestUser"+Math.round(Math.random()*10000),
|
||||
char:Math.floor(Math.random()*12),
|
||||
kart:Math.floor(Math.random()*0x24)
|
||||
}
|
||||
}
|
||||
sendJSONMessage(obj);
|
||||
};
|
||||
|
||||
ws.onmessage = function(evt) {
|
||||
var d = evt.data;
|
||||
if (typeof d != "string") {
|
||||
//binary data
|
||||
var view = new DataView(d);
|
||||
var handler = binH[view.getUint8(0)];
|
||||
if (handler != null) handler(view);
|
||||
} else {
|
||||
//JSON string
|
||||
var obj;
|
||||
try {
|
||||
obj = JSON.parse(d);
|
||||
} catch (err) {
|
||||
debugger; //packet recieved from server is bullshit
|
||||
return;
|
||||
}
|
||||
var handler = wsH["$"+obj.t];
|
||||
if (handler != null) handler(obj);
|
||||
}
|
||||
}
|
||||
|
||||
this.update = function() {
|
||||
if (t.activeScene != null) t.activeScene.update();
|
||||
if (t.myKart != null) sendKartInfo(t.myKart);
|
||||
}
|
||||
|
||||
this.render = function() {
|
||||
if (t.activeScene != null) sceneDrawer.drawTest(gl, t.activeScene, 0, 0, gl.viewportWidth, gl.viewportHeight)
|
||||
}
|
||||
|
||||
function abFromBlob(blob, callback) {
|
||||
var fileReader = new FileReader();
|
||||
fileReader.onload = function() {
|
||||
callback(this.result);
|
||||
};
|
||||
fileReader.readAsArrayBuffer(blob);
|
||||
}
|
||||
|
||||
function sendKartInfo(kart) {
|
||||
var dat = new ArrayBuffer(0x61);
|
||||
var view = new DataView(dat);
|
||||
view.setUint8(0, 32);
|
||||
netKart.saveKart(view, 1, kart, kart.lastInput);
|
||||
ws.send(dat);
|
||||
}
|
||||
|
||||
var wsH = {};
|
||||
wsH["$*"] = function(obj) { //initiate scene.
|
||||
t.myKart = null;
|
||||
if (obj.m == 1) { //race
|
||||
t.mode = 1;
|
||||
|
||||
var mainNarc, texNarc
|
||||
if (obj.c.substr(0, 5) == "mkds/") {
|
||||
var cnum = Number(obj.c.substr(5));
|
||||
var music = MKDSCONST.COURSE_MUSIC[cnum];
|
||||
var cDir = MKDSCONST.COURSEDIR+MKDSCONST.COURSES[cnum];
|
||||
var mainNarc = new narc(lz77.decompress(gameROM.getFile(cDir+".carc")));
|
||||
var texNarc = new narc(lz77.decompress(gameROM.getFile(cDir+"Tex.carc")));
|
||||
setUpCourse(mainNarc, texNarc, music, obj)
|
||||
}
|
||||
else throw "custom tracks are not implemented yet!"
|
||||
}
|
||||
}
|
||||
|
||||
wsH["$+"] = function(obj) { //add kart. only used in debug circumstances. (people can't join normal gamemodes midgame)
|
||||
console.log("kart added");
|
||||
if (t.mode != 1) return;
|
||||
var kart = new Kart([0, -2000, 0], 0, 0, obj.k.kart, obj.k.char, new ((obj.p)?((window.prompt("press y for cpu controlled") == "y")?controlRaceCPU:controlDefault):controlNetwork)(t.activeScene.nkm, {}), t.activeScene);
|
||||
t.activeScene.karts.push(kart);
|
||||
}
|
||||
|
||||
wsH["$-"] = function(obj) { //kart disconnect.
|
||||
t.activeScene.karts[obj.k].active = false;
|
||||
}
|
||||
|
||||
var binH = [];
|
||||
binH[32] = function(view) {
|
||||
//if we are in a race, update kart positions in main scene. we should trust the server on this, however if anything goes wrong it will be caught earlier.
|
||||
if (t.mode != 1) return;
|
||||
|
||||
var n = view.getUint16(0x01, true);
|
||||
var off = 0x03;
|
||||
for (var i=0; i<n; i++) {
|
||||
var kart = t.activeScene.karts[view.getUint16(off, true)];
|
||||
off += 2;
|
||||
if (kart != null && !kart.local) netKart.restoreKart(view, off, kart);
|
||||
off += 0x60;
|
||||
}
|
||||
}
|
||||
|
||||
function setUpCourse(mainNarc, texNarc, music, obj) {
|
||||
var chars = [];
|
||||
for (var i=0; i<obj.k.length; i++) {
|
||||
var k = obj.k[i];
|
||||
var pKart = (i == obj.p);
|
||||
//TODO: custom character support
|
||||
chars.push({charN:k.char, kartN:k.kart, controller:((pKart)?((window.prompt("press y for cpu controlled") == "y")?controlRaceCPU:controlDefault):controlNetwork), raceCam:pKart, extraParams:[{k:"name", v:k.name}, {k:"active", v:k.active}]});
|
||||
|
||||
if (pKart) {
|
||||
for (var i=0; i<7; i++) {
|
||||
var tchar = Math.floor(Math.random()*12);
|
||||
var tkart = Math.floor(Math.random()*0x24);
|
||||
|
||||
chars.push({charN:tchar, kartN:tkart, controller:controlRaceCPU, raceCam:false, extraParams:[{k:"name", v:"no"}, {k:"active", v:true}]});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
t.activeScene = new courseScene(mainNarc, texNarc, music, chars, {}, res);
|
||||
|
||||
for (var i=0; i<obj.k.length; i++) {
|
||||
t.activeScene.karts[i].active = obj.k[i].active;
|
||||
if (t.activeScene.karts[i].local) t.myKart = t.activeScene.karts[i];
|
||||
}
|
||||
}
|
||||
|
||||
function sendJSONMessage(obj) {
|
||||
ws.send(JSON.stringify(obj));
|
||||
}
|
||||
}
|
||||
@@ -1,456 +0,0 @@
|
||||
//
|
||||
// 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<scn.karts.length; i++) if (scn.karts[i].active) scn.karts[i].drawKart(mvMatrix, pMatrix, gl);
|
||||
for (var i=0; i<scn.karts.length; i++) if (scn.karts[i].active) scn.karts[i].drawWheels(mvMatrix, pMatrix, gl);
|
||||
for (var i=0; i<scn.karts.length; i++) if (scn.karts[i].active) scn.karts[i].drawChar(mvMatrix, pMatrix, gl);
|
||||
|
||||
for (var i=0; i<scn.entities.length; i++) {
|
||||
var e = scn.entities[i];
|
||||
if (e.transparent) transE.push(e);
|
||||
else e.draw(mvMatrix, pMatrix, gl);
|
||||
}
|
||||
|
||||
for (var i=0; i<scn.particles.length; i++) {
|
||||
var e = scn.particles[i];
|
||||
e.draw(mvMatrix, pMatrix, gl);
|
||||
}
|
||||
|
||||
scn.items.draw(mvMatrix, pMatrix, gl);
|
||||
|
||||
}
|
||||
|
||||
function sndUpdate(view) {
|
||||
var mulmat = mat4.create();
|
||||
mat4.scale(mulmat, mulmat, [1/1024, 1/1024, 1/1024]);
|
||||
var view = mat4.mul([], view, mulmat)
|
||||
|
||||
for (var i=0; i<scn.karts.length; i++) {
|
||||
var e = scn.karts[i];
|
||||
if (e.sndUpdate != null) e.sndUpdate(view);
|
||||
}
|
||||
|
||||
for (var i=0; i<scn.entities.length; i++) {
|
||||
var e = scn.entities[i];
|
||||
if (e.sndUpdate != null) e.sndUpdate(view);
|
||||
}
|
||||
}
|
||||
|
||||
function update() {
|
||||
var shadres = 0.25;
|
||||
var targ = vec3.transformMat4([], scn.camera.targetShadowPos, scn.lightMat);
|
||||
vec3.scale(targ, targ, 1/1024);
|
||||
mat4.mul(scn.shadMat, mat4.ortho(mat4.create(), targ[0]-shadres, targ[0]+shadres, targ[1]-shadres, targ[1]+shadres, -targ[2]-2.5, -targ[2]+2.5), scn.lightMat);
|
||||
|
||||
for (var i=0; i<scn.karts.length; i++) {
|
||||
var ent = scn.karts[i];
|
||||
if (ent.active) ent.update(scn);
|
||||
}
|
||||
|
||||
var entC = scn.entities.slice(0);
|
||||
for (var i=0; i<entC.length; i++) {
|
||||
var ent = entC[i];
|
||||
ent.update(scn);
|
||||
}
|
||||
|
||||
var prtC = scn.particles.slice(0);
|
||||
for (var i=0; i<prtC.length; i++) {
|
||||
var ent = prtC[i];
|
||||
ent.update(scn);
|
||||
}
|
||||
|
||||
scn.items.update(scn);
|
||||
|
||||
if (musicRestartTimer > -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<entsToRemove.length; i++) {
|
||||
scn.entities.splice(scn.entities.indexOf(entsToRemove[i]), 1);
|
||||
}
|
||||
entsToRemove = [];
|
||||
var mat = scn.camera.getView(scn, nitroRender.getViewWidth(), nitroRender.getViewHeight());
|
||||
frame++;
|
||||
}
|
||||
|
||||
function removeParticle(obj) {
|
||||
scn.particles.splice(scn.particles.indexOf(obj), 1);
|
||||
}
|
||||
|
||||
function removeEntity(obj) {
|
||||
entsToRemove.push(obj);
|
||||
}
|
||||
|
||||
function compilePaths() {
|
||||
var path = scn.nkm.sections["PATH"].entries;
|
||||
var pts = scn.nkm.sections["POIT"].entries;
|
||||
|
||||
var paths = [];
|
||||
var ind = 0;
|
||||
for (var i=0; i<path.length; i++) {
|
||||
var p = [];
|
||||
for (var j=0; j<path[i].numPts; j++) {
|
||||
p.push(pts[ind++]);
|
||||
}
|
||||
paths.push(p);
|
||||
}
|
||||
scn.paths = paths;
|
||||
}
|
||||
|
||||
function startCourse() {
|
||||
scn.lightMat = mat4.create();
|
||||
mat4.rotateX(scn.lightMat, scn.lightMat, Math.PI*(61/180));
|
||||
mat4.rotateY(scn.lightMat, scn.lightMat, Math.PI*(21/180));
|
||||
|
||||
mat4.mul(scn.farShadMat, mat4.ortho(mat4.create(), -5, 5, -5, 5, -5, 5), scn.lightMat);
|
||||
|
||||
compilePaths();
|
||||
|
||||
//chars format: {charN: int, kartN: int, controller: function, raceCam: bool, controlOptions: object}
|
||||
|
||||
var startSet = null;
|
||||
for (var i=0; i<startSetups.length; i++) {
|
||||
if (chars.length < startSetups[i].maxplayers) {
|
||||
startSet = startSetups[i];
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
var startpos = scn.nkm.sections["KTPS"].entries[0];
|
||||
|
||||
for (var i=0; i<chars.length; i++) {
|
||||
var c = chars[i];
|
||||
var kart = new Kart(vec3.add([], startpos.pos, startPosition(startSet.toAline, startSet.xspacing, startSet.yspacing, startSet.liney, startpos.angle[1], i)), (180-startpos.angle[1])*(Math.PI/180), 0, c.kartN, c.charN, new c.controller(scn.nkm, c.controlOptions), scn);
|
||||
scn.karts.push(kart);
|
||||
var spectator = false; //(prompt("Type y for spectator cam")=="y")
|
||||
if (c.raceCam) scn.camera = (spectator?(new cameraSpectator(kart, scn)):(new cameraIngame(kart, scn)));
|
||||
}
|
||||
|
||||
var obj = scn.nkm.sections["OBJI"].entries;
|
||||
for (var i=0; i<obj.length; i++) {
|
||||
var o = obj[i];
|
||||
var func = objDatabase.idToType[o.ID];
|
||||
if (func != null) {
|
||||
var ent = new func(o, scn);
|
||||
|
||||
if (scn.typeRes[o.ID] == null) loadRes(ent.requireRes(), o.ID)
|
||||
else ent.requireRes(); //some objects use this for determining their function.
|
||||
|
||||
ent.provideRes(scn.typeRes[o.ID]);
|
||||
scn.entities.push(ent);
|
||||
if (ent.collidable) scn.colEnt.push(ent);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function loadOrGet(res) {
|
||||
var ext = res.split(".").pop();
|
||||
if (scn.fileBank["$"+ext] == null) scn.fileBank["$"+ext] = {};
|
||||
var item = scn.fileBank["$"+ext]["$"+res];
|
||||
if (item != null) return item;
|
||||
|
||||
var func = loadFunc["$"+ext];
|
||||
if (func != null) {
|
||||
var test = mainNarc.getFile(res);
|
||||
if (test == null) test = gameRes.MapObj.getFile(res.split("/").pop())
|
||||
if (test == null) throw "COULD NOT FIND RESOURCE "+res+"!";
|
||||
if (res == "/MapObj/itembox.nsbmd") throwWhatever = true;
|
||||
var item = new func(test);
|
||||
scn.fileBank["$"+ext]["$"+res] = item;
|
||||
return item;
|
||||
}
|
||||
}
|
||||
|
||||
// the thresholds for different win sounds and music
|
||||
// thresh, goalsound, goalmusic, goalpostmusic
|
||||
var finishPercents = [
|
||||
[0, 66, 46, 58],
|
||||
[0.5, 66, 47, 56],
|
||||
[1.1, 67, 48, 57]
|
||||
]
|
||||
|
||||
function lapAdvance(kart) {
|
||||
//if the kart is us, play some sounds and show lakitu
|
||||
var winPercent = finishers.length/scn.karts.length;
|
||||
if (kart.local) {
|
||||
if (kart.lapNumber == 3) {
|
||||
//last lap
|
||||
musicRestartTimer = 0;
|
||||
nitroAudio.instaKill(scn.musicPlayer);
|
||||
scn.musicPlayer = nitroAudio.playSound(62, {volume:2}, null);
|
||||
}
|
||||
else if (kart.lapNumber == 4) {
|
||||
var finishTuple = [];
|
||||
for (var i=0; i<finishPercents.length; i++) {
|
||||
if (finishPercents[i][0] > 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<res.mdl.length; i++) {
|
||||
var inf = res.mdl[i];
|
||||
var bmd = loadOrGet("/MapObj/"+inf.nsbmd);
|
||||
var btx = (inf.nsbtx == null)?null:loadOrGet("/MapObj/"+inf.nsbtx);
|
||||
|
||||
var mdl = new nitroModel(bmd, btx);
|
||||
|
||||
models.push(mdl);
|
||||
}
|
||||
|
||||
var other = [];
|
||||
if (res.other != null) {
|
||||
for (var i=0; i<res.other.length; i++) {
|
||||
other.push(loadOrGet("/MapObj/"+res.other[i]));
|
||||
}
|
||||
}
|
||||
|
||||
scn.typeRes[id] = {mdl:models, other: other};
|
||||
}
|
||||
|
||||
function updateMode(mode) {
|
||||
// updates the game mode...
|
||||
|
||||
// {
|
||||
// id = (0:pregame, 1:countdown, 2:race, 3:postgame)
|
||||
// time = (elapsed time in seconds)
|
||||
// frameDiv = (0-60)
|
||||
// }
|
||||
var lastid = scn.mode.id;
|
||||
if (lastid != mode.id) {
|
||||
//mode switch
|
||||
switch (mode.id) {
|
||||
case 0:
|
||||
//race init. fade scene in and play init music.
|
||||
nitroAudio.playSound(11, {volume:2}, null); //7:race (gp), 11:race2 (vs), 12:battle
|
||||
break;
|
||||
case 1:
|
||||
//spawn lakitu and countdown animation. allow pre-acceleration.
|
||||
//generally happens at least 2 seconds after init
|
||||
scn.entities.push(new Race3DUI(scn, "count", -30));
|
||||
break;
|
||||
case 2:
|
||||
//enable all racers and start music
|
||||
for (var i=0; i<scn.karts.length; i++) {
|
||||
scn.karts[i].preboost = false;
|
||||
}
|
||||
nitroAudio.playSound(40, {volume:2, bpmMultiplier:16}, 0);
|
||||
scn.entities.push(new Race3DUI(scn, "start"));
|
||||
break;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
if (scn.mode.time != mode.time) {
|
||||
switch (mode.id) {
|
||||
case 0:
|
||||
break;
|
||||
case 1:
|
||||
if (mode.time > 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;
|
||||
}
|
||||
}
|
||||
@@ -1,132 +0,0 @@
|
||||
//
|
||||
// sceneDrawer.js
|
||||
//--------------------
|
||||
// Provides functions to draw scenes in various ways.
|
||||
// by RHY3756547
|
||||
//
|
||||
|
||||
window.sceneDrawer = new function() {
|
||||
var gl, shadowTarg;
|
||||
|
||||
var shadowRes = 2048;
|
||||
|
||||
this.init = function(gl) {
|
||||
gl = gl;
|
||||
shadowTarg = createRenderTarget(gl, shadowRes, shadowRes, true);
|
||||
}
|
||||
|
||||
this.drawWithShadow = function(gl, scn, x, y, width, height) {
|
||||
if (scn.lastWidth != width || scn.lastHeight != height) {
|
||||
scn.lastWidth = width;
|
||||
scn.lastHeight = height;
|
||||
scn.renderTarg = createRenderTarget(gl, width, height, true);
|
||||
}
|
||||
|
||||
var view = scn.camera.getView(scn, width, height);
|
||||
var viewProj = mat4.mul(view.p, view.p, view.mv);
|
||||
|
||||
var shadMat = scn.shadMat;
|
||||
|
||||
if (scn.farShad == null) {
|
||||
scn.farShad = createRenderTarget(gl, shadowRes*2, shadowRes*2, true);
|
||||
gl.viewport(0, 0, shadowRes*2, shadowRes*2);
|
||||
gl.bindFramebuffer(gl.FRAMEBUFFER, scn.farShad.fb);
|
||||
gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT | gl.STENCIL_BUFFER_BIT);
|
||||
gl.colorMask(false, false, false, false);
|
||||
scn.draw(gl, scn.farShadMat, true);
|
||||
}
|
||||
|
||||
gl.viewport(0, 0, shadowRes, shadowRes);
|
||||
gl.bindFramebuffer(gl.FRAMEBUFFER, shadowTarg.fb);
|
||||
gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT | gl.STENCIL_BUFFER_BIT);
|
||||
gl.colorMask(false, false, false, false);
|
||||
scn.draw(gl, shadMat, true);
|
||||
|
||||
gl.viewport(0, 0, width, height);
|
||||
gl.bindFramebuffer(gl.FRAMEBUFFER, scn.renderTarg.fb);
|
||||
gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT | gl.STENCIL_BUFFER_BIT);
|
||||
gl.colorMask(true, true, true, true);
|
||||
scn.draw(gl, viewProj, false);
|
||||
|
||||
scn.sndUpdate(view.mv);
|
||||
|
||||
gl.bindFramebuffer(gl.FRAMEBUFFER, null);
|
||||
|
||||
gl.viewport(x, y, width, height);
|
||||
shadowRender.drawShadowed(scn.renderTarg.color, scn.renderTarg.depth, shadowTarg.depth, scn.farShad.depth, viewProj, shadMat, scn.farShadMat)
|
||||
}
|
||||
|
||||
this.drawTest = function(gl, scn, x, y, width, height) {
|
||||
|
||||
var view = scn.camera.view; //scn.camera.getView(scn, width, height);
|
||||
|
||||
var viewProj = mat4.mul(mat4.create(), view.p, view.mv);
|
||||
view = {p: viewProj, mv: view.mv};
|
||||
|
||||
var shadMat = scn.shadMat;
|
||||
|
||||
nitroRender.unsetShadowMode();
|
||||
nitroRender.flagShadow = true;
|
||||
nitroRender.updateBillboards(scn.lightMat);
|
||||
|
||||
if (scn.farShad == null) {
|
||||
scn.farShad = createRenderTarget(gl, shadowRes*2, shadowRes*2, true);
|
||||
gl.viewport(0, 0, shadowRes*2, shadowRes*2);
|
||||
gl.bindFramebuffer(gl.FRAMEBUFFER, scn.farShad.fb);
|
||||
gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT | gl.STENCIL_BUFFER_BIT);
|
||||
gl.colorMask(false, false, false, false);
|
||||
scn.draw(gl, scn.farShadMat, true);
|
||||
}
|
||||
|
||||
gl.viewport(0, 0, shadowRes, shadowRes);
|
||||
gl.bindFramebuffer(gl.FRAMEBUFFER, shadowTarg.fb);
|
||||
gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT | gl.STENCIL_BUFFER_BIT);
|
||||
gl.colorMask(false, false, false, false);
|
||||
scn.draw(gl, shadMat, true);
|
||||
|
||||
nitroRender.setShadowMode(shadowTarg.depth, scn.farShad.depth, shadMat, scn.farShadMat);
|
||||
nitroRender.flagShadow = false;
|
||||
|
||||
nitroRender.updateBillboards(view.mv);
|
||||
gl.viewport(x, y, width, height);
|
||||
gl.bindFramebuffer(gl.FRAMEBUFFER, null);
|
||||
gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT | gl.STENCIL_BUFFER_BIT);
|
||||
gl.colorMask(true, true, true, true);
|
||||
scn.draw(gl, viewProj, false);
|
||||
|
||||
scn.sndUpdate(view.mv);
|
||||
|
||||
}
|
||||
|
||||
function createRenderTarget(gl, xsize, ysize, depth) {
|
||||
var depthTextureExt = gl.getExtension("WEBGL_depth_texture");
|
||||
if (!depthTextureExt) alert("depth texture not supported! we're DOOMED! jk we'll just have to add a fallback for people with potato gfx");
|
||||
|
||||
var colorTexture = gl.createTexture();
|
||||
gl.bindTexture(gl.TEXTURE_2D, colorTexture);
|
||||
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.NEAREST);
|
||||
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.NEAREST);
|
||||
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE);
|
||||
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE);
|
||||
gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, xsize, ysize, 0, gl.RGBA, gl.UNSIGNED_BYTE, null);
|
||||
|
||||
var depthTexture = gl.createTexture();
|
||||
gl.bindTexture(gl.TEXTURE_2D, depthTexture);
|
||||
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.NEAREST);
|
||||
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.NEAREST);
|
||||
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE);
|
||||
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE);
|
||||
gl.texImage2D(gl.TEXTURE_2D, 0, gl.DEPTH_COMPONENT, xsize, ysize, 0, gl.DEPTH_COMPONENT, gl.UNSIGNED_SHORT, null);
|
||||
|
||||
var framebuffer = gl.createFramebuffer();
|
||||
gl.bindFramebuffer(gl.FRAMEBUFFER, framebuffer);
|
||||
gl.framebufferTexture2D(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.TEXTURE_2D, colorTexture, 0);
|
||||
gl.framebufferTexture2D(gl.FRAMEBUFFER, gl.DEPTH_ATTACHMENT, gl.TEXTURE_2D, depthTexture, 0);
|
||||
|
||||
return {
|
||||
color: colorTexture,
|
||||
depth: depthTexture,
|
||||
fb: framebuffer
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,86 +0,0 @@
|
||||
//
|
||||
// singleScene.js
|
||||
//--------------------
|
||||
// Drives the course scene when not connected to a server. Simulates responses expected from a server.
|
||||
// by RHY3756547
|
||||
//
|
||||
|
||||
window.singleScene = function(course, wsInstance, res) {
|
||||
var res = res; //gameRes
|
||||
var t = this;
|
||||
|
||||
t.mode = -1;
|
||||
t.activeScene = null;
|
||||
t.myKart = null;
|
||||
|
||||
var mchar = Math.floor(Math.random()*12);
|
||||
var mkart = Math.floor(Math.random()*0x24);
|
||||
|
||||
this.update = function() {
|
||||
if (t.activeScene != null) {
|
||||
t.activeScene.update();
|
||||
//simulate what a server would do
|
||||
updateServer();
|
||||
}
|
||||
}
|
||||
|
||||
var advanceTimes = [3,4,-1,-1]
|
||||
|
||||
function updateServer() {
|
||||
var m = t.mode;
|
||||
m.frameDiv++;
|
||||
if (m.frameDiv == 60) {
|
||||
m.frameDiv -= 60;
|
||||
m.time++;
|
||||
var timeAd = advanceTimes[m.id];
|
||||
if (timeAd != -1 && m.time >= timeAd) {
|
||||
m.id++;
|
||||
m.time = 0;
|
||||
}
|
||||
}
|
||||
|
||||
t.activeScene.updateMode(JSON.parse(JSON.stringify(t.mode)));
|
||||
}
|
||||
|
||||
this.render = function() {
|
||||
if (t.activeScene != null) sceneDrawer.drawTest(gl, t.activeScene, 0, 0, gl.viewportWidth, gl.viewportHeight)
|
||||
}
|
||||
|
||||
begin(course);
|
||||
|
||||
function begin(course) {
|
||||
var mainNarc, texNarc
|
||||
if (course.substr(0, 5) == "mkds/") {
|
||||
var cnum = Number(course.substr(5));
|
||||
var music = MKDSCONST.COURSE_MUSIC[cnum];
|
||||
var cDir = MKDSCONST.COURSEDIR+MKDSCONST.COURSES[cnum];
|
||||
var mainNarc = new narc(lz77.decompress(gameROM.getFile(cDir+".carc")));
|
||||
var texNarc = new narc(lz77.decompress(gameROM.getFile(cDir+"Tex.carc")));
|
||||
setUpCourse(mainNarc, texNarc, music)
|
||||
} else throw "custom tracks are not implemented yet!"
|
||||
}
|
||||
|
||||
|
||||
function setUpCourse(mainNarc, texNarc, music) {
|
||||
var chars = [];
|
||||
chars.push({charN:mchar, kartN:mkart, controller:((window.prompt("press y for cpu controlled") == "y")?controlRaceCPU:controlDefault), raceCam:true, extraParams:[{k:"name", v:"single"}, {k:"active", v:true}]});
|
||||
|
||||
for (var i=0; i<7; i++) {
|
||||
var tchar = Math.floor(Math.random()*12);
|
||||
var tkart = Math.floor(Math.random()*0x24);
|
||||
|
||||
chars.push({charN:tchar, kartN:tkart, controller:controlRaceCPU, raceCam:false, extraParams:[{k:"name", v:"no"}, {k:"active", v:true}]});
|
||||
}
|
||||
|
||||
t.activeScene = new courseScene(mainNarc, texNarc, music, chars, {}, res);
|
||||
|
||||
t.myKart = t.activeScene.karts[0];
|
||||
t.mode = {
|
||||
id:0,
|
||||
time:0,
|
||||
frameDiv:0,
|
||||
}
|
||||
t.activeScene.updateMode(t.mode);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,83 +0,0 @@
|
||||
window.fileStore = new (function(){
|
||||
var db;
|
||||
var indexedDB;
|
||||
|
||||
this.requestGameFiles = requestGameFiles;
|
||||
|
||||
function requestGameFiles(callback) {
|
||||
indexedDB = window.indexedDB
|
||||
|| window.webkitIndexedDB
|
||||
|| window.mozIndexedDB
|
||||
|| window.shimIndexedDB;
|
||||
|
||||
var request = indexedDB.open("MKJS_DB", 1);
|
||||
request.onerror = window.onerror;
|
||||
|
||||
request.onsuccess = function(event) {
|
||||
db = event.target.result;
|
||||
loadGameFiles(callback);
|
||||
}
|
||||
|
||||
request.onupgradeneeded = function(event) {
|
||||
db = event.target.result;
|
||||
var objectStore = db.createObjectStore("files", { keyPath: "filename" });
|
||||
objectStore.transaction.oncomplete = function(event) {
|
||||
loadGameFiles(callback);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function loadGameFiles(callback) {
|
||||
var transaction = db.transaction(["files"]);
|
||||
var objectStore = transaction.objectStore("files");
|
||||
var request = objectStore.get("mkds.nds");
|
||||
request.onerror = function(event) {
|
||||
alert("Fatal database error!");
|
||||
};
|
||||
request.onsuccess = function(event) {
|
||||
if (request.result == null) downloadGame("Mario Kart DS.nds", callback);
|
||||
else callback(request.result.data);
|
||||
};
|
||||
}
|
||||
|
||||
function downloadGame(url, callback) {
|
||||
if (typeof url == "string") {
|
||||
var xml = new XMLHttpRequest();
|
||||
xml.open("GET", url, true);
|
||||
xml.responseType = "arraybuffer";
|
||||
xml.onload = function() {
|
||||
storeGame(xml.response, callback);
|
||||
}
|
||||
xml.send();
|
||||
} else {
|
||||
alert("You need to supply MKJS with a Mario Kart DS ROM to function. Click anywhere on the page to load a file.")
|
||||
fileCallback = callback;
|
||||
document.getElementById("fileIn").onchange = fileInChange;
|
||||
waitForROM = true;
|
||||
}
|
||||
}
|
||||
|
||||
function fileInChange(e) {
|
||||
var bFile = e.target.files[0];
|
||||
var bReader = new FileReader();
|
||||
bReader.onload = function(e) {
|
||||
waitForROM = false; //todo: verify
|
||||
storeGame(e.target.result, fileCallback);
|
||||
};
|
||||
bReader.readAsArrayBuffer(bFile);
|
||||
}
|
||||
|
||||
function storeGame(dat, callback) {
|
||||
var transaction = db.transaction(["files"], "readwrite");
|
||||
var objectStore = transaction.objectStore("files");
|
||||
var request = objectStore.put({filename:"mkds.nds", data:dat});
|
||||
|
||||
request.onerror = function(event) {
|
||||
alert("Failed to store game locally!");
|
||||
callback(dat);
|
||||
};
|
||||
request.onsuccess = function(event) {
|
||||
callback(dat);
|
||||
};
|
||||
}
|
||||
})();
|
||||
Reference in new issue
Block a user