[Pages] Make directory structure lowercase.
This commit is contained in:
1 parent
3b47a86756
commit
65ca7d7455
96 files changed
+20116
No files matched your search
@@ -0,0 +1,196 @@
|
||||
//
|
||||
// bowserPlatforms.js
|
||||
//--------------------
|
||||
// Provides platforms for Bowser's Castle
|
||||
// by RHY3756547
|
||||
//
|
||||
// includes:
|
||||
// render stuff idk
|
||||
//
|
||||
|
||||
window.ObjRotaryRoom = function(obji, scene) {
|
||||
var obji = obji;
|
||||
var res = [];
|
||||
|
||||
var t = this;
|
||||
|
||||
t.collidable = true;
|
||||
t.colMode = 0;
|
||||
t.colRad = 512;
|
||||
t.getCollision = getCollision;
|
||||
t.moveWith = moveWith;
|
||||
|
||||
t.pos = vec3.clone(obji.pos);
|
||||
//t.angle = vec3.clone(obji.angle);
|
||||
t.scale = vec3.clone(obji.scale);
|
||||
|
||||
t.requireRes = requireRes;
|
||||
t.provideRes = provideRes;
|
||||
t.update = update;
|
||||
t.draw = draw;
|
||||
|
||||
t.speed = (obji.setting1&0xFFFF)/8192;
|
||||
t.angle = 0;
|
||||
|
||||
var dirVel = 0;
|
||||
|
||||
function update(scene) {
|
||||
dirVel = t.speed;
|
||||
t.angle += dirVel;
|
||||
}
|
||||
|
||||
function draw(view, pMatrix) {
|
||||
var mat = mat4.translate(mat4.create(), view, t.pos);
|
||||
|
||||
mat4.scale(mat, mat, vec3.scale([], t.scale, 16));
|
||||
|
||||
mat4.rotateY(mat, mat, t.angle);
|
||||
res.mdl[0].draw(mat, pMatrix);
|
||||
}
|
||||
|
||||
function requireRes() { //scene asks what resources to load
|
||||
return {mdl:[{nsbmd:"rotary_room.nsbmd"}]};
|
||||
}
|
||||
|
||||
function provideRes(r) {
|
||||
res = r; //...and gives them to us. :)
|
||||
}
|
||||
|
||||
function getCollision() {
|
||||
var obj = {};
|
||||
var inf = res.mdl[0].getCollisionModel(0, 0);
|
||||
obj.tris = inf.dat;
|
||||
|
||||
var mat = mat4.translate([], mat4.create(), t.pos);
|
||||
mat4.scale(mat, mat, vec3.mul([], [16*inf.scale, 16*inf.scale, 16*inf.scale], t.scale));
|
||||
mat4.rotateY(mat, mat, t.angle);
|
||||
|
||||
obj.mat = mat;
|
||||
return obj;
|
||||
}
|
||||
|
||||
function moveWith(obj) { //used for collidable objects that move.
|
||||
var p = vec3.sub([], obj.pos, t.pos);
|
||||
vec3.transformMat4(p, p, mat4.rotateY([], mat4.create(), dirVel));
|
||||
vec3.add(obj.pos, t.pos, p);
|
||||
obj.physicalDir -= dirVel;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
window.ObjRoutePlatform = function(obji, scene) {
|
||||
var obji = obji;
|
||||
var res = [];
|
||||
var genCol;
|
||||
|
||||
var t = this;
|
||||
|
||||
t.collidable = true;
|
||||
t.colMode = 0;
|
||||
t.colRad = 512;
|
||||
t.getCollision = getCollision;
|
||||
t.moveWith = moveWith;
|
||||
|
||||
t.pos = vec3.clone(obji.pos);
|
||||
//t.angle = vec3.clone(obji.angle);
|
||||
t.scale = vec3.clone(obji.scale);
|
||||
|
||||
t.requireRes = requireRes;
|
||||
t.provideRes = provideRes;
|
||||
t.update = update;
|
||||
t.draw = draw;
|
||||
|
||||
generateCol();
|
||||
|
||||
t.statDur = (obji.setting1&0xFFFF);
|
||||
t.route = scene.paths[obji.routeID];
|
||||
t.routeSpeed = 1/6;
|
||||
t.routePos = 0;
|
||||
t.nextNode = t.route[t.routePos];
|
||||
t.prevPos = t.pos;
|
||||
t.elapsedTime = 0;
|
||||
|
||||
t.mode = 0;
|
||||
|
||||
var movVel;
|
||||
|
||||
//t.speed = (obji.setting1&0xFFFF)/8192;
|
||||
|
||||
function update(scene) {
|
||||
if (t.mode == 0) {
|
||||
t.elapsedTime += t.routeSpeed;
|
||||
movVel = vec3.sub([], t.nextNode.pos, t.prevPos);
|
||||
//vec3.normalize(movVel, movVel);
|
||||
vec3.scale(movVel, movVel, t.routeSpeed/t.nextNode.duration);
|
||||
vec3.add(t.pos, t.pos, movVel);
|
||||
if (t.elapsedTime >= t.nextNode.duration) {
|
||||
t.elapsedTime = 0;
|
||||
t.prevPos = t.nextNode.pos;
|
||||
t.routePos = (t.routePos+1)%t.route.length;
|
||||
t.nextNode = t.route[t.routePos];
|
||||
t.mode = 1;
|
||||
}
|
||||
} else {
|
||||
t.elapsedTime += 1;
|
||||
movVel = [0, 0, 0];
|
||||
if (t.elapsedTime > t.statDur) {
|
||||
t.mode = 0;
|
||||
t.elapsedTime = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function draw(view, pMatrix) {
|
||||
var mat = mat4.translate(mat4.create(), view, t.pos);
|
||||
|
||||
mat4.scale(mat, mat, vec3.scale([], t.scale, 16));
|
||||
|
||||
res.mdl[0].draw(mat, pMatrix);
|
||||
}
|
||||
|
||||
function requireRes() { //scene asks what resources to load
|
||||
return {mdl:[{nsbmd:"koopa_block.nsbmd"}]}; //25x, 11y
|
||||
}
|
||||
|
||||
function provideRes(r) {
|
||||
res = r; //...and gives them to us. :)
|
||||
}
|
||||
|
||||
function generateCol() {
|
||||
genCol = {dat: [
|
||||
{
|
||||
Vertex1: [25, 0, 11],
|
||||
Vertex2: [25, 0, -11],
|
||||
Vertex3: [-25, 0, -11],
|
||||
Normal: [0, 1, 0]
|
||||
},
|
||||
{
|
||||
Vertex1: [-25, 0, -11],
|
||||
Vertex2: [-25, 0, 11],
|
||||
Vertex3: [25, 0, 11],
|
||||
Normal: [0, 1, 0]
|
||||
},
|
||||
], scale: 1};
|
||||
}
|
||||
|
||||
function getCollision() {
|
||||
var obj = {};
|
||||
var inf = genCol;//res.mdl[0].getCollisionModel(0, 0);
|
||||
obj.tris = inf.dat;
|
||||
|
||||
var mat = mat4.translate([], mat4.create(), t.pos);
|
||||
mat4.scale(mat, mat, vec3.mul([], [16*inf.scale, 16*inf.scale, 16*inf.scale], t.scale));
|
||||
|
||||
obj.mat = mat;
|
||||
return obj;
|
||||
}
|
||||
|
||||
function moveWith(obj) { //used for collidable objects that move.
|
||||
/*var p = vec3.sub([], obj.pos, t.pos);
|
||||
vec3.transformMat4(p, p, mat4.rotateY([], mat4.create(), dirVel));
|
||||
vec3.add(obj.pos, t.pos, p);
|
||||
obj.physicalDir -= dirVel;*/
|
||||
vec3.add(obj.pos, obj.pos, movVel);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,273 @@
|
||||
//
|
||||
// decorations.js
|
||||
//--------------------
|
||||
// Provides decoration objects.
|
||||
// by RHY3756547
|
||||
//
|
||||
// includes:
|
||||
// render stuff idk
|
||||
//
|
||||
|
||||
window.ObjDecor = function(obji, scene) {
|
||||
var forceBill;
|
||||
var obji = obji;
|
||||
var res = [];
|
||||
|
||||
var t = this;
|
||||
|
||||
t.pos = vec3.clone(obji.pos);
|
||||
t.angle = vec3.clone(obji.angle);
|
||||
t.scale = vec3.clone(obji.scale);
|
||||
|
||||
t.requireRes = requireRes;
|
||||
t.provideRes = provideRes;
|
||||
t.update = update;
|
||||
t.draw = draw;
|
||||
|
||||
var mat = mat4.create();
|
||||
var frame = 0;
|
||||
var anim = null;
|
||||
var animFrame = 0;
|
||||
var animMat = null;
|
||||
|
||||
function draw(view, pMatrix) {
|
||||
mat4.translate(mat, view, t.pos);
|
||||
|
||||
if (t.angle[2] != 0) mat4.rotateZ(mat, mat, t.angle[2]*(Math.PI/180));
|
||||
if (t.angle[1] != 0) mat4.rotateY(mat, mat, t.angle[1]*(Math.PI/180));
|
||||
if (t.angle[0] != 0) mat4.rotateX(mat, mat, t.angle[0]*(Math.PI/180));
|
||||
|
||||
if (anim != null) {
|
||||
animMat = anim.setFrame(0, 0, animFrame++);
|
||||
}
|
||||
|
||||
mat4.scale(mat, mat, vec3.scale([], t.scale, 16));
|
||||
res.mdl[0].draw(mat, pMatrix, animMat);
|
||||
}
|
||||
|
||||
function update() {
|
||||
|
||||
}
|
||||
|
||||
function requireRes() { //scene asks what resources to load
|
||||
forceBill = true;
|
||||
switch (obji.ID) {
|
||||
case 0x012D:
|
||||
return {mdl:[{nsbmd:"BeachTree1.nsbmd"}]}; //non solid
|
||||
case 0x012E:
|
||||
return {mdl:[{nsbmd:"BeachTree1.nsbmd"}]};
|
||||
case 0x012F:
|
||||
return {mdl:[{nsbmd:"earthen_pipe1.nsbmd"}]}; //why is there an earthen pipe 2
|
||||
|
||||
case 0x0130:
|
||||
return {mdl:[{nsbmd:"opa_tree1.nsbmd"}]};
|
||||
case 0x0131:
|
||||
return {mdl:[{nsbmd:"OlgPipe1.nsbmd"}]};
|
||||
case 0x0132:
|
||||
return {mdl:[{nsbmd:"OlgMush1.nsbmd"}]};
|
||||
case 0x0133:
|
||||
return {mdl:[{nsbmd:"of6yoshi1.nsbmd"}]};
|
||||
case 0x0134:
|
||||
return {mdl:[{nsbmd:"cow.nsbmd"}], other:[null, null, "cow.nsbtp"]}; //has animation, cow.nsbtp
|
||||
case 0x0135:
|
||||
forceBill = false;
|
||||
return {mdl:[{nsbmd:"NsKiller1.nsbmd"}, {nsbmd:"NsKiller2.nsbmd"}, {nsbmd:"NsKiller2_s.nsbmd"}]}; //probably animates
|
||||
case 0x0138:
|
||||
return {mdl:[{nsbmd:"GardenTree1.nsbmd"}]};
|
||||
case 0x0139:
|
||||
return {mdl:[{nsbmd:"kamome.nsbmd"}], other:[null, null, "kamone.nsbtp"]}; //animates using nsbtp, and uses route to move
|
||||
|
||||
case 0x013A:
|
||||
return {mdl:[{nsbmd:"CrossTree1.nsbmd"}]};
|
||||
|
||||
//0x013C is big cheep cheep
|
||||
case 0x013C:
|
||||
forceBill = false;
|
||||
return {mdl:[{nsbmd:"bakubaku.nsbmd"}]};
|
||||
|
||||
//0x013D is spooky ghost
|
||||
case 0x013D:
|
||||
forceBill = false;
|
||||
return {mdl:[{nsbmd:"teresa.nsbmd"}], other:[null, null, "teresa.nsbtp"]};
|
||||
|
||||
case 0x013E:
|
||||
return {mdl:[{nsbmd:"Bank_Tree1.nsbmd"}]};
|
||||
case 0x013F:
|
||||
return {mdl:[{nsbmd:"GardenTree1.nsbmd"}]}; //non solid
|
||||
|
||||
case 0x0140:
|
||||
return {mdl:[{nsbmd:"chandelier.nsbmd"}], other:[null, "chandelier.nsbca"]};
|
||||
case 0x0142:
|
||||
return {mdl:[{nsbmd:"MarioTree3.nsbmd"}]};
|
||||
case 0x0145:
|
||||
return {mdl:[{nsbmd:"TownTree1.nsbmd"}]};
|
||||
case 0x0146:
|
||||
//solid
|
||||
return {mdl:[{nsbmd:"Snow_Tree1.nsbmd"}]};
|
||||
case 0x0148:
|
||||
return {mdl:[{nsbmd:"DeTree1.nsbmd"}]};
|
||||
case 0x0149:
|
||||
return {mdl:[{nsbmd:"BankEgg1.nsbmd"}]};
|
||||
|
||||
case 0x014B:
|
||||
return {mdl:[{nsbmd:"KinoHouse1.nsbmd"}]};
|
||||
case 0x014C:
|
||||
return {mdl:[{nsbmd:"KinoHouse2.nsbmd"}]};
|
||||
case 0x014D:
|
||||
return {mdl:[{nsbmd:"KinoMount1.nsbmd"}]};
|
||||
case 0x014E:
|
||||
return {mdl:[{nsbmd:"KinoMount2.nsbmd"}]};
|
||||
|
||||
|
||||
case 0x014F:
|
||||
return {mdl:[{nsbmd:"olaTree1c.nsbmd"}]};
|
||||
|
||||
case 0x0150:
|
||||
return {mdl:[{nsbmd:"osaTree1c.nsbmd"}]};
|
||||
case 0x0151:
|
||||
forceBill = false;
|
||||
return {mdl:[{nsbmd:"picture1.nsbmd"}], other:[null, "picture1.nsbca"]};
|
||||
case 0x0152:
|
||||
forceBill = false;
|
||||
return {mdl:[{nsbmd:"picture2.nsbmd"}], other:[null, "picture2.nsbca"]};
|
||||
case 0x0153:
|
||||
return {mdl:[{nsbmd:"om6Tree1.nsbmd"}]};
|
||||
|
||||
//0x0154 is rainbow road rotating star
|
||||
case 0x0154:
|
||||
forceBill = false;
|
||||
return {mdl:[{nsbmd:"RainStar.nsbmd"}], other:["RainStar.nsbta"]};
|
||||
|
||||
case 0x0155:
|
||||
return {mdl:[{nsbmd:"Of6Tree1.nsbmd"}]};
|
||||
case 0x0156:
|
||||
return {mdl:[{nsbmd:"Of6Tree1.nsbmd"}]};
|
||||
case 0x0157:
|
||||
return {mdl:[{nsbmd:"TownMonte.nsbmd"}], other:[null, null, "TownMonte.nsbtp"]}; //pianta!
|
||||
|
||||
//debug pianta bridge
|
||||
case 0x00CC:
|
||||
forceBill = false;
|
||||
return {mdl:[{nsbmd:"bridge.nsbmd"}], other:[null, "bridge.nsbca"]};
|
||||
//debug puddle
|
||||
case 0x000D:
|
||||
forceBill = false;
|
||||
return {mdl:[{nsbmd:"puddle.nsbmd"}]};
|
||||
//debug airship
|
||||
case 0x0158:
|
||||
forceBill = false;
|
||||
return {mdl:[{nsbmd:"airship.nsbmd"}]};
|
||||
|
||||
//need version for 3d objects?
|
||||
|
||||
//DEBUG ENEMIES - remove here when implemented.
|
||||
|
||||
case 0x0191: //goomba
|
||||
return {mdl:[{nsbmd:"kuribo.nsbmd"}], other:[null, null, "kuribo.nsbtp"]}; //has nsbtp, route
|
||||
case 0x0192: //rock
|
||||
forceBill = false;
|
||||
return {mdl:[{nsbmd:"rock.nsbmd"}, {nsbmd:"rock_shadow.nsbmd"}]}; //has route
|
||||
case 0x0193: //thwomp
|
||||
forceBill = false;
|
||||
return {mdl:[{nsbmd:"dossun.nsbmd"}, {nsbmd:"dossun_shadow.nsbmd"}]}; //has route
|
||||
case 0x0196: //chain chomp
|
||||
forceBill = false;
|
||||
return {mdl:[{nsbmd:"wanwan.nsbmd"}, {nsbmd:"wanwan_chain.nsbmd"}, {nsbmd:"wanwan_kui.nsbmd"}, {nsbmd:"rock_shadow.nsbmd"}]};
|
||||
case 0x0198: //bowser castle GBA fireball
|
||||
return {mdl:[{nsbmd:"mkd_ef_bubble.nsbmd"}]};
|
||||
case 0x0199: //peach gardens monty
|
||||
forceBill = false;
|
||||
return {mdl:[{nsbmd:"choropu.nsbmd"}], other:[null, null, "choropu.nsbtp"]}; //has nsbtp
|
||||
case 0x019B: //cheep cheep (bouncing)
|
||||
return {mdl:[{nsbmd:"pukupuku.nsbmd"}], other:[null, null, "pukupuku.nsbtp"]}; //has nsbtp
|
||||
case 0x019D: //snowman
|
||||
return {mdl:[{nsbmd:"sman_top.nsbmd"}, {nsbmd:"sman_bottom.nsbmd"}]};
|
||||
case 0x019E: //trunk with bats
|
||||
forceBill = false;
|
||||
return {mdl:[{nsbmd:"kanoke_64.nsbmd"}, {nsbmd:"basabasa.nsbmd"}], other:[null, "kanoke_64.nsbca"]}; //basa has nsbtp
|
||||
case 0x01A0: //bat
|
||||
return {mdl:[{nsbmd:"basabasa.nsbmd"}], other:[null, null, "basabasa.nsbtp"]}; //has nsbtp
|
||||
case 0x01A1: //as fortress cannon
|
||||
forceBill = false;
|
||||
return {mdl:[{nsbmd:"NsCannon1.nsbmd"}]};
|
||||
case 0x01A3: //mansion moving tree
|
||||
forceBill = false;
|
||||
return {mdl:[{nsbmd:"move_tree.nsbmd"}], other:[null, "move_tree.nsbca"]}; //has route
|
||||
case 0x01A4: //flame
|
||||
forceBill = false;
|
||||
return {mdl:[{nsbmd:"mkd_ef_burner.nsbmd"}], other:["mkd_ef_burner.nsbta", null]};
|
||||
case 0x01A5: //chain chomp no base
|
||||
forceBill = false;
|
||||
return {mdl:[{nsbmd:"wanwan.nsbmd"}, {nsbmd:"wanwan_chain.nsbmd"}, {nsbmd:"rock_shadow.nsbmd"}]};
|
||||
|
||||
case 0x01A6: //plant
|
||||
return {mdl:[{nsbmd:"ob_pakkun_sf.nsbmd"}], other:[null, null, "ob_pakkun_sf.nsbtp"]}; //has nsbtp
|
||||
|
||||
case 0x01A7: //monty airship
|
||||
forceBill = false;
|
||||
return {mdl:[{nsbmd:"poo.nsbmd"}, {nsbmd:"cover.nsbmd"}, {nsbmd:"hole.nsbmd"}], other:[null, null, "poo.nsbtp"]}; //poo has nsbtp
|
||||
|
||||
case 0x01A8: //bound
|
||||
forceBill = false;
|
||||
return {mdl:[{nsbmd:"bound.nsbmd"}], other:[null, null, "bound.nsbtp"]}; //has nsbtp
|
||||
case 0x01A9: //flipper
|
||||
forceBill = false;
|
||||
return {mdl:[{nsbmd:"flipper.nsbmd"}], other:["flipper.nsbta", null, "flipper.nsbtp"]}; //has nsbtp
|
||||
|
||||
case 0x01AA: //3d fire plant
|
||||
forceBill = false;
|
||||
//note... what exactly is PakkunZHead...
|
||||
return {mdl:[{nsbmd:"PakkunMouth.nsbmd"}, {nsbmd:"PakkunBody.nsbmd"}, {nsbmd:"FireBall.nsbmd"}], other:[null, "PakkunMouth.nsbca"]};
|
||||
case 0x01AC: //crab
|
||||
forceBill = false;
|
||||
return {mdl:[{nsbmd:"crab.nsbmd"}, {nsbmd:"crab_hand.nsbmd"}], other:[null, null, "crab.nsbtp"]}; //both have nsbtp
|
||||
|
||||
case 0x01AD: //desert hills sun
|
||||
forceBill = false;
|
||||
return {mdl:[{nsbmd:"sun.nsbmd"}, {nsbmd:"sun_LOD.nsbmd"}]/*, other:[null, "sun.nsbca"]*/}; //exesun animation does not load
|
||||
|
||||
case 0x01B0: //routed iron ball
|
||||
return {mdl:[{nsbmd:"IronBall.nsbmd"}]};
|
||||
case 0x01B1: //routed choco mountain rock
|
||||
forceBill = false;
|
||||
return {mdl:[{nsbmd:"rock2.nsbmd"}]};
|
||||
case 0x01B2: //sanbo... whatever that is (pokey?) routed
|
||||
return {mdl:[{nsbmd:"sanbo_h.nsbmd"}, {nsbmd:"sanbo_b.nsbmd"}]};
|
||||
case 0x01B3: //iron ball
|
||||
return {mdl:[{nsbmd:"IronBall.nsbmd"}]};
|
||||
|
||||
case 0x01B4: //cream
|
||||
forceBill = false;
|
||||
return {mdl:[{nsbmd:"cream.nsbmd"}, {nsbmd:"cream_effect.nsbmd"}]};
|
||||
case 0x01B5: //berry
|
||||
forceBill = false;
|
||||
return {mdl:[{nsbmd:"berry.nsbmd"}, {nsbmd:"cream_effect.nsbmd"}]};
|
||||
}
|
||||
}
|
||||
|
||||
function provideRes(r) {
|
||||
res = r; //...and gives them to us. :)
|
||||
|
||||
if (forceBill) {
|
||||
t.angle[1] = 0;
|
||||
var bmd = r.mdl[0].bmd;
|
||||
bmd.hasBillboards = true;
|
||||
var models = bmd.modelData.objectData;
|
||||
for (var i=0; i<models.length; i++) {
|
||||
var objs = models[i].objects.objectData;
|
||||
for (var j=0; j<objs.length; j++) {
|
||||
objs[i].billboardMode = 2;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (r.other != null) {
|
||||
if (r.other.length > 0 && r.other[0] != null) {
|
||||
res.mdl[0].loadTexAnim(r.other[0]);
|
||||
}
|
||||
if (r.other.length > 1 && r.other[1] != null)
|
||||
anim = new nitroAnimator(r.mdl[0].bmd, r.other[1]);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,120 @@
|
||||
//
|
||||
// itembox.js
|
||||
//--------------------
|
||||
// Drives and animates itembox entity.
|
||||
// by RHY3756547
|
||||
//
|
||||
|
||||
window.ItemBox = function(obji, scene) {
|
||||
var obji = obji;
|
||||
var res = [];
|
||||
|
||||
var t = this;
|
||||
|
||||
var anim = 0;
|
||||
var animFrame = 0;
|
||||
var animMat;
|
||||
var frames = 0;
|
||||
|
||||
t.soundProps = {};
|
||||
t.pos = vec3.clone(obji.pos);
|
||||
//t.angle = vec3.clone(obji.angle);
|
||||
t.scale = vec3.clone(obji.scale);
|
||||
|
||||
t.sndUpdate = sndUpdate;
|
||||
t.requireRes = requireRes;
|
||||
t.provideRes = provideRes;
|
||||
t.update = update;
|
||||
t.draw = draw;
|
||||
|
||||
t.mode = 0;
|
||||
t.time = 0;
|
||||
|
||||
var test = 0;
|
||||
|
||||
|
||||
function update(scene) {
|
||||
switch (t.mode) {
|
||||
case 0: //alive
|
||||
for (var i=0; i<scene.karts.length; i++) {
|
||||
var ok = scene.karts[i];
|
||||
var dist = vec3.dist(vec3.add([], t.pos, [0,1,0]), ok.pos);
|
||||
if (dist < 24) {
|
||||
var breakSound = nitroAudio.playSound(212, {}, 0, t);
|
||||
breakSound.gainN.gain.value = 4;
|
||||
for (var j=0; j<10; j++) {
|
||||
scene.particles.push(new ItemShard(scene, ok, res.mdl[2]));
|
||||
}
|
||||
t.mode = 1;
|
||||
t.time = 0;
|
||||
break;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case 1: //dead
|
||||
if (t.time++ > 30) {
|
||||
t.mode = 2;
|
||||
t.time = 0;
|
||||
}
|
||||
break;
|
||||
case 2: //respawning
|
||||
if (t.time++ > 30) {
|
||||
t.mode = 0;
|
||||
t.time = 0;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
animMat = anim.setFrame(0, 0, animFrame);
|
||||
animFrame = (animFrame+1)%frames;
|
||||
}
|
||||
|
||||
function draw(view, pMatrix, gl) {
|
||||
if (t.mode == 0 || t.mode == 2) {
|
||||
if (t.mode == 2) nitroRender.setColMult([1, 1, 1, t.time/30]);
|
||||
var mat = mat4.translate(mat4.create(), view, t.pos);
|
||||
|
||||
mat4.scale(mat, mat, vec3.scale([], t.scale, 16));
|
||||
|
||||
//res.mdl[2].draw(mat, pMatrix);
|
||||
|
||||
mat4.translate(mat, mat, [0, 1, 0])
|
||||
|
||||
gl.enable(gl.CULL_FACE); //box part
|
||||
//gl.depthMask(false);
|
||||
res.mdl[0].drawPoly(mat, pMatrix, 0, 1, animMat);
|
||||
//gl.depthMask(true);
|
||||
gl.disable(gl.CULL_FACE);
|
||||
|
||||
//question mark part
|
||||
gl.depthRange(0, 0.99); //hack to push question mark forward in z buffer, causes a few issues with far away boxes though
|
||||
res.mdl[0].drawPoly(mat, pMatrix, 0, 0, animMat);
|
||||
gl.depthRange(0, 1);
|
||||
|
||||
if (t.mode == 2) nitroRender.setColMult([1, 1, 1, 1]);
|
||||
}
|
||||
}
|
||||
|
||||
function sndUpdate(view) {
|
||||
t.soundProps.pos = vec3.transformMat4([], t.pos, view);
|
||||
if (t.soundProps.lastPos != null) t.soundProps.vel = vec3.sub([], t.soundProps.pos, t.soundProps.lastPos);
|
||||
else t.soundProps.vel = [0, 0, 0];
|
||||
t.soundProps.lastPos = t.soundProps.pos;
|
||||
|
||||
t.soundProps.refDistance = 192/1024;
|
||||
t.soundProps.rolloffFactor = 1;
|
||||
}
|
||||
|
||||
function requireRes() { //scene asks what resources to load
|
||||
return {mdl:[{nsbmd:"itembox.nsbmd"}, {nsbmd:"obj_shadow.nsbmd"}, {nsbmd:"itembox_hahen.nsbmd"}], other:["itembox.nsbca"]};
|
||||
}
|
||||
|
||||
function provideRes(r) {
|
||||
res = r; //...and gives them to us. :)
|
||||
anim = new nitroAnimator(r.mdl[0].bmd, r.other[0]);
|
||||
frames = r.other[0].animData.objectData[0].frames;
|
||||
animFrame = Math.floor(Math.random()*frames);
|
||||
animMat = anim.setFrame(0, 0, animFrame);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,890 @@
|
||||
//
|
||||
// kart.js
|
||||
//--------------------
|
||||
// Entity type for karts.
|
||||
// by RHY3756547
|
||||
//
|
||||
// includes: gl-matrix.js (glMatrix 2.0)
|
||||
// /formats/kcl.js
|
||||
//
|
||||
|
||||
window.Kart = function(pos, angle, speed, kartN, charN, controller, scene) {
|
||||
var k = this;
|
||||
var minimumMove = 0.05;
|
||||
var MAXSPEED = 24;
|
||||
var BOOSTTIME = 90;
|
||||
|
||||
var kartSoundBase = 170;
|
||||
|
||||
var COLBOUNCE_TIME = 20;
|
||||
var COLBOUNCE_STRENGTH = 1;
|
||||
|
||||
var params = scene.gameRes.kartPhys.karts[kartN];
|
||||
var offsets = scene.gameRes.kartOff.karts[kartN];
|
||||
|
||||
this.local = controller.local;
|
||||
this.active = true;
|
||||
this.preboost = true;
|
||||
|
||||
this.soundProps = {};
|
||||
this.pos = pos;
|
||||
this.angle = angle;
|
||||
this.vel = vec3.create();
|
||||
this.weight = params.weight;
|
||||
this.params = params;
|
||||
this.kartBounce = kartBounce;
|
||||
|
||||
this.speed = speed;
|
||||
this.drifting = false;
|
||||
this.driftMode = 0; //1 left, 2 right, 0 undecided
|
||||
this.driftLanded = false; //if we haven't landed then apply a constant turn.
|
||||
|
||||
//powerslide info: to advance to the next mode you need to hold the same button for 10 or more frames. Mode 0 starts facing drift direction, 1 is other way, 2 is returning (mini spark), 3 is other way, 4 is returning (turbo spark)
|
||||
this.driftPSTick = 0;
|
||||
this.driftPSMode = 0;
|
||||
|
||||
this.kartTargetNormal = [0, 1, 0];
|
||||
this.kartNormal = [0, 1, 0];
|
||||
this.airTime = 0;
|
||||
this.controller = controller;
|
||||
|
||||
this.driftOff = 0;
|
||||
this.physicalDir = angle;
|
||||
this.mat = mat4.create();
|
||||
this.basis = mat4.create();
|
||||
this.ylock = 0;
|
||||
|
||||
this.cannon = null;
|
||||
|
||||
this.gravity = [0, -0.17, 0]; //100% confirmed by me messing around with the gravity value in mkds. for sticky surface and loop should modify to face plane until in air
|
||||
|
||||
this.update = update;
|
||||
this.sndUpdate = sndUpdate;
|
||||
this.draw = draw;
|
||||
|
||||
this.drawKart = drawKart;
|
||||
this.drawWheels = drawWheels;
|
||||
this.drawChar = drawChar;
|
||||
|
||||
this.trackAttach = null; //a normal for the kart to attach to (loop)
|
||||
this.boostMT = 0;
|
||||
this.boostNorm = 0;
|
||||
|
||||
this.kartColVel = vec3.create();
|
||||
this.kartColTimer = 0;
|
||||
|
||||
var charRes = scene.gameRes.getChar(charN);
|
||||
var kartRes = scene.gameRes.getKart(kartN);
|
||||
var kartPolys = [];
|
||||
|
||||
var kObj = kartRes.bmd.modelData.objectData[0];
|
||||
|
||||
for (var i=0; i<kObj.polys.objectData.length; i++) {
|
||||
if (kObj.materials.names[kObj.polys.objectData[i].mat] != "kart_tire\0\0\0\0\0\0\0") kartPolys.push(i)
|
||||
}
|
||||
|
||||
var tireRes = scene.gameRes.tireRes;
|
||||
|
||||
this.anim = new nitroAnimator(charRes.model.bmd, charRes.driveA);
|
||||
this.charRes = charRes;
|
||||
this.animMode = "drive";
|
||||
this.driveAnimF = 14; //29 frames in total, 14 is mid
|
||||
this.animFrame = 0; //only used for non drive anim
|
||||
this.animMat = null;
|
||||
|
||||
this.lastInput = null;
|
||||
|
||||
//race statistics
|
||||
this.lapNumber = 0;
|
||||
this.passedKTP2 = false;
|
||||
this.checkPointNumber = 0;
|
||||
var nkm = scene.nkm;
|
||||
var startLine = nkm.sections["KTPS"].entries[0];
|
||||
var passLine = nkm.sections["KTP2"].entries[0];
|
||||
var checkpoints = nkm.sections["CPOI"].entries;
|
||||
var respawns = nkm.sections["CPOI"].entries;
|
||||
var futureChecks = [1];
|
||||
|
||||
var hitGroundAnim = [ //length 13, on y axis
|
||||
1.070,
|
||||
1.130,
|
||||
1.170,
|
||||
1.190,
|
||||
1.2,
|
||||
1.190,
|
||||
1.170,
|
||||
1.130,
|
||||
1.070,
|
||||
1,
|
||||
0.950,
|
||||
0.920,
|
||||
0.950,
|
||||
]
|
||||
|
||||
var charGroundAnim = [ //length 13, on y axis
|
||||
1,
|
||||
1,
|
||||
1,
|
||||
1,
|
||||
1,
|
||||
1.080,
|
||||
1.140,
|
||||
1.180,
|
||||
1.140,
|
||||
1.060,
|
||||
0.970,
|
||||
0.960,
|
||||
0.980,
|
||||
]
|
||||
|
||||
var lastCollided = -1;
|
||||
var lastBE = -1;
|
||||
var lastColSounds = {};
|
||||
var ylvel = 0;
|
||||
var wheelTurn = 0;
|
||||
var onGround;
|
||||
|
||||
var kartAnim = 0;
|
||||
var groundAnim = -1;
|
||||
var stuckTo = null;
|
||||
|
||||
var updateMat = true;
|
||||
|
||||
var drawMat = {
|
||||
kart: mat4.create(),
|
||||
wheels: [mat4.create(), mat4.create(), mat4.create(), mat4.create()],
|
||||
character: mat4.create()
|
||||
}
|
||||
|
||||
controller.setKart(k);
|
||||
|
||||
var soundMode = -1;
|
||||
var sounds = { //sounds that can be simultaneous
|
||||
kart: null,
|
||||
drift: null,
|
||||
lastTerrain: -1,
|
||||
lastBE: -1,
|
||||
drive: null,
|
||||
boost: null,
|
||||
powerslide: null,
|
||||
boostSoundTrig: true, //true if a new boost sound can be played
|
||||
transpose: 0
|
||||
}
|
||||
updateKartSound(0, {turn:0});
|
||||
|
||||
function recalcMat(view) {
|
||||
var mat = mat4.mul([], view, k.mat);
|
||||
var xscale = 1+Math.cos((kartAnim/4)*Math.PI)*0.015;
|
||||
var yscale = 1+Math.cos(((kartAnim+4)/4)*Math.PI)*0.015;
|
||||
|
||||
if (groundAnim != -1) yscale *= hitGroundAnim[groundAnim];
|
||||
|
||||
mat4.translate(mat, mat, [0, -params.colRadius, 0]); //main part
|
||||
var kmat = mat4.scale(drawMat.kart, mat, [16*xscale, 16*yscale, 16]);
|
||||
|
||||
//wheels
|
||||
for (var i=0; i<4; i++) {
|
||||
var scale = 16*((i<2)?offsets.frontTireSize:1);
|
||||
var wmat = mat4.translate(drawMat.wheels[i], mat, [0, 0, 0]);
|
||||
|
||||
if (groundAnim != -1) mat4.scale(wmat, wmat, [1, hitGroundAnim[groundAnim], 1]);
|
||||
|
||||
mat4.translate(wmat, wmat, offsets.wheels[i]);
|
||||
mat4.scale(wmat, wmat, [scale, scale, scale]);
|
||||
if (i<2) mat4.rotateY(wmat, wmat, ((k.driveAnimF-14)/14)*Math.PI/6);
|
||||
mat4.rotateX(wmat, wmat, wheelTurn);
|
||||
}
|
||||
|
||||
var scale = 16;
|
||||
var pos = vec3.clone(offsets.chars[charN]);
|
||||
|
||||
if (groundAnim != -1) pos[1] *= charGroundAnim[groundAnim];
|
||||
|
||||
var cmat = mat4.translate(drawMat.character, mat, vec3.scale([], pos, 16))
|
||||
mat4.scale(cmat, cmat, [scale, scale, scale]);
|
||||
|
||||
if (k.animMode == "drive") k.animMat = k.anim.setFrame(0, 0, k.driveAnimF);
|
||||
else k.animMat = k.anim.setFrame(0, 0, k.animFrame++);
|
||||
|
||||
updateMat = false;
|
||||
}
|
||||
|
||||
function drawChar(view, pMatrix) {
|
||||
charRes.model.draw(drawMat.character, pMatrix, k.animMat);
|
||||
}
|
||||
|
||||
function drawKart(view, pMatrix, gl) {
|
||||
if (updateMat) recalcMat(view);
|
||||
//if we're in simple shadows mode, draw the kart's stencil shadow.
|
||||
|
||||
if (false) {
|
||||
//gl.enable(gl.CULL_FACE); //culling is fun!
|
||||
gl.clear(gl.STENCIL_BUFFER_BIT);
|
||||
//gl.cullFace(gl.FRONT);
|
||||
gl.colorMask(false, false, false, false);
|
||||
gl.depthMask(false);
|
||||
|
||||
gl.enable(gl.STENCIL_TEST);
|
||||
gl.stencilMask(0xFF);
|
||||
gl.stencilFunc(gl.ALWAYS, 1, 0xFF);
|
||||
gl.stencilOp(gl.KEEP, gl.INCR, gl.KEEP);
|
||||
|
||||
kartRes.shadVol.draw(drawMat.kart, pMatrix, simpleMatStack);
|
||||
|
||||
gl.colorMask(true, true, true, true)
|
||||
//gl.cullFace(gl.BACK);
|
||||
gl.stencilFunc(gl.LESS , 0, 0xFF);
|
||||
gl.stencilOp(gl.KEEP, gl.KEEP, gl.KEEP);
|
||||
|
||||
kartRes.shadVol.draw(drawMat.kart, pMatrix, simpleMatStack);
|
||||
gl.disable(gl.STENCIL_TEST);
|
||||
//gl.disable(gl.CULL_FACE);
|
||||
gl.depthMask(true);
|
||||
|
||||
}
|
||||
|
||||
for (var i=0; i<kartPolys.length; i++) {
|
||||
kartRes.drawPoly(drawMat.kart, pMatrix, 0, kartPolys[i], simpleMatStack);
|
||||
}
|
||||
}
|
||||
|
||||
function drawWheels(view, pMatrix) {
|
||||
if (updateMat) recalcMat(view);
|
||||
var wheelMod = tireRes[offsets.name];
|
||||
for (var i=0; i<4; i++) {
|
||||
wheelMod.draw(drawMat.wheels[i], pMatrix, simpleMatStack);
|
||||
}
|
||||
}
|
||||
|
||||
function draw(view, pMatrix) {
|
||||
drawWheels(view, pMatrix);
|
||||
drawKart(view, pMatrix);
|
||||
drawChar(view, pMatrix);
|
||||
}
|
||||
|
||||
function update(scene) {
|
||||
var lastPos = vec3.clone(k.pos);
|
||||
updateMat = true;
|
||||
|
||||
if (groundAnim != -1) {
|
||||
if (++groundAnim >= hitGroundAnim.length) groundAnim = -1;
|
||||
}
|
||||
|
||||
onGround = (k.airTime < 5);
|
||||
|
||||
kartAnim = (kartAnim+1)%8;
|
||||
var input = k.controller.fetchInput();
|
||||
k.lastInput = input;
|
||||
|
||||
if (input.turn > 0.3) {
|
||||
if (k.driveAnimF < 28) k.driveAnimF++;
|
||||
} else if (input.turn < -0.3) {
|
||||
if (k.driveAnimF > 0) k.driveAnimF--;
|
||||
} else {
|
||||
if (k.driveAnimF > 14) k.driveAnimF--;
|
||||
else if (k.driveAnimF < 14) k.driveAnimF++;
|
||||
}
|
||||
|
||||
//update sounds
|
||||
|
||||
var newSoundMode = soundMode;
|
||||
if (input.accel) {
|
||||
if (soundMode == 0 || soundMode == 6) newSoundMode = 2;
|
||||
if (soundMode == 4) newSoundMode = 3;
|
||||
} else {
|
||||
if (soundMode != 0) {
|
||||
if (soundMode == 2 || soundMode == 3) newSoundMode = 4;
|
||||
if (newSoundMode == 4 && k.speed < 0.5) newSoundMode = 0;
|
||||
}
|
||||
}
|
||||
|
||||
if (k.boostMT+k.boostNorm > 0) {
|
||||
if (k.boostNorm == BOOSTTIME || k.boostMT == params.miniTurbo) {
|
||||
if (sounds.boostSoundTrig) {
|
||||
if (sounds.boost != null) nitroAudio.instaKill(sounds.boost);
|
||||
sounds.boost = nitroAudio.playSound(160, {}, 0, k);
|
||||
sounds.boost.gainN.gain.value = 2;
|
||||
sounds.boostSoundTrig = false;
|
||||
}
|
||||
} else {
|
||||
sounds.boostSoundTrig = true;
|
||||
}
|
||||
} else if (sounds.boost != null) {
|
||||
nitroAudio.kill(sounds.boost);
|
||||
sounds.boost = null;
|
||||
}
|
||||
|
||||
if (onGround && k.speed > 0.5) {
|
||||
if (lastCollided != sounds.lastTerrain || lastBE != sounds.lastBE || sounds.drive == null) {
|
||||
if (sounds.drive != null) nitroAudio.kill(sounds.drive);
|
||||
if (lastColSounds.drive != null) {
|
||||
sounds.drive = nitroAudio.playSound(lastColSounds.drive, {}, 0, k);
|
||||
sounds.drive.gainN.gain.value = 2;
|
||||
}
|
||||
}
|
||||
|
||||
if (k.drifting && k.driftLanded) {
|
||||
if (lastCollided != sounds.lastTerrain || lastBE != sounds.lastBE || sounds.drift == null) {
|
||||
if (sounds.drift != null) nitroAudio.kill(sounds.drift);
|
||||
if (lastColSounds.drift != null) {
|
||||
sounds.drift = nitroAudio.playSound(lastColSounds.drift, {}, 0, k);
|
||||
}
|
||||
}
|
||||
} else if (sounds.drift != null) { nitroAudio.kill(sounds.drift); sounds.drift = null; }
|
||||
|
||||
sounds.lastTerrain = lastCollided;
|
||||
sounds.lastBE = lastBE;
|
||||
} else {
|
||||
if (sounds.drift != null) { nitroAudio.kill(sounds.drift); sounds.drift = null; }
|
||||
if (sounds.drive != null) { nitroAudio.kill(sounds.drive); sounds.drive = null; }
|
||||
}
|
||||
|
||||
//end sound update
|
||||
|
||||
if (k.preboost) {
|
||||
|
||||
} else if (k.cannon != null) { //when cannon is active, we fly forward at max move speed until we get to the cannon point.
|
||||
var c = scene.nkm.sections["KTPC"].entries[k.cannon];
|
||||
|
||||
var mat = mat4.create();
|
||||
mat4.rotateY(mat, mat, c.angle[1]*(Math.PI/180));
|
||||
mat4.rotateX(mat, mat, c.angle[0]*(-Math.PI/180));
|
||||
|
||||
var forward = [0, 0, 1];
|
||||
var up = [0, 1, 0];
|
||||
|
||||
k.vel = vec3.scale([], vec3.transformMat4(forward, forward, mat), MAXSPEED);
|
||||
k.speed = MAXSPEED;
|
||||
vec3.add(k.pos, k.pos, k.vel);
|
||||
k.physicalDir = (180-c.angle[1])*(Math.PI/180);
|
||||
k.angle = k.physicalDir;
|
||||
k.kartTargetNormal = vec3.transformMat4(up, up, mat);
|
||||
|
||||
var planeConst = -vec3.dot(c.pos, forward);
|
||||
var cannonDist = vec3.dot(k.pos, forward) + planeConst;
|
||||
if (cannonDist > 0) k.cannon = null;
|
||||
} else { //default kart mode
|
||||
|
||||
var groundEffect = 0;
|
||||
if (lastCollided != -1) {
|
||||
groundEffect = MKDS_COLTYPE.PHYS_MAP[lastCollided];
|
||||
if (groundEffect == null) groundEffect = 0;
|
||||
}
|
||||
|
||||
var effect = params.colParam[groundEffect];
|
||||
var top = params.topSpeed*effect.topSpeedMul; //if you let go of accel, drift ends anyway, so always accel in drift.
|
||||
|
||||
var boosting = (k.boostNorm + k.boostMT)>0;
|
||||
|
||||
if (boosting) {
|
||||
var top2
|
||||
if (k.boostNorm>0){
|
||||
top2 = params.topSpeed*1.3;
|
||||
k.boostNorm--;
|
||||
} else {
|
||||
top2 = params.topSpeed*((effect.topSpeedMul >= 1)?1.3:effect.topSpeedMul);
|
||||
}
|
||||
|
||||
if (k.boostMT>0) {
|
||||
k.boostMT--;
|
||||
}
|
||||
|
||||
if (k.speed <= top2) {
|
||||
k.speed += 1;
|
||||
if (k.speed > top2) k.speed = top2;
|
||||
} else {
|
||||
k.speed *= 0.95;
|
||||
}
|
||||
}
|
||||
|
||||
//kart controls
|
||||
if (k.drifting) {
|
||||
if ((onGround) && !(input.accel && input.drift && (k.speed > 2 || !k.driftLanded))) {
|
||||
//end drift, execute miniturbo
|
||||
k.drifting = false;
|
||||
if (sounds.powerslide != null) {
|
||||
nitroAudio.instaKill(sounds.powerslide);
|
||||
sounds.powerslide = null;
|
||||
}
|
||||
if (k.driftPSMode == 3) {
|
||||
k.boostMT = params.miniTurbo;
|
||||
}
|
||||
k.driftPSMode = 0;
|
||||
k.driftPSTick = 0;
|
||||
}
|
||||
|
||||
if (k.driftMode == 0) {
|
||||
if (input.turn > 0.30) {
|
||||
k.driftMode = 2;
|
||||
} else if (input.turn < -0.30) {
|
||||
k.driftMode = 1;
|
||||
}
|
||||
} else {
|
||||
if (k.driftLanded) {
|
||||
var change = (((k.driftMode-1.5)*Math.PI/1.5)-k.driftOff)*0.05;
|
||||
k.driftOff += change;
|
||||
k.physicalDir -= change;
|
||||
}
|
||||
|
||||
//if we're above the initial y position, add a constant turn with a period of 180 frames.
|
||||
if (!k.driftLanded && k.ylock>=0) {
|
||||
k.physicalDir += (Math.PI*2/180)*(k.driftMode*2-3);
|
||||
}
|
||||
}
|
||||
|
||||
if (onGround) {
|
||||
if (!k.driftLanded) {
|
||||
if (k.driftMode == 0) k.drifting = false;
|
||||
else {
|
||||
k.driftPSMode = 0;
|
||||
k.driftPSTick = 0;
|
||||
k.driftLanded = true;
|
||||
}
|
||||
}
|
||||
if (k.drifting) {
|
||||
|
||||
if (!boosting) {
|
||||
if (k.speed <= top) {
|
||||
k.speed += (k.speed/top > params.driftAccelSwitch)?params.driftAccel2:params.driftAccel1;
|
||||
if (k.speed > top) k.speed = top;
|
||||
} else {
|
||||
k.speed *= 0.95;
|
||||
}
|
||||
}
|
||||
|
||||
var turn = ((k.driftMode == 1)?(input.turn-1):(input.turn+1))/2;
|
||||
|
||||
k.physicalDir += params.driftTurnRate*turn+((k.driftMode == 1)?-1:1)*(50/32768)*Math.PI; //what is this mystery number i hear you ask? well my friend, this is the turn rate for outward drift.
|
||||
|
||||
//miniturbo code
|
||||
if (input.turn != 0) {
|
||||
var inward = ((input.turn>0) == k.driftMode-1); //if we're turning
|
||||
|
||||
switch (k.driftPSMode) {
|
||||
case 0: //dpad away from direction for 10 frames
|
||||
if (!inward) k.driftPSTick++;
|
||||
else if (k.driftPSTick > 9) {
|
||||
k.driftPSMode++;
|
||||
k.driftPSTick = 1;
|
||||
|
||||
//play blue spark sound
|
||||
var blue = nitroAudio.playSound(210, {}, 0, k);
|
||||
blue.gainN.gain.value = 2;
|
||||
|
||||
} else k.driftPSTick = 0;
|
||||
break;
|
||||
case 1: //dpad toward direction for 10 frames
|
||||
if (inward) k.driftPSTick++;
|
||||
else if (k.driftPSTick > 9) {
|
||||
k.driftPSMode++;
|
||||
k.driftPSTick = 1;
|
||||
|
||||
} else k.driftPSTick = 0;
|
||||
break;
|
||||
case 2: //dpad away from direction for 10 frames
|
||||
if (!inward) k.driftPSTick++;
|
||||
else if (k.driftPSTick > 9) {
|
||||
k.driftPSMode++;
|
||||
k.driftPSTick = 1;
|
||||
//play red sparks sound, full MT!
|
||||
sounds.powerslide = nitroAudio.playSound(209, {}, 0, k);
|
||||
sounds.powerslide.gainN.gain.value = 2;
|
||||
} else k.driftPSTick = 0;
|
||||
break;
|
||||
case 3: //turbo charged
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!k.drifting) {
|
||||
if (onGround) {
|
||||
var effect = params.colParam[groundEffect];
|
||||
if (!boosting) {
|
||||
if (input.accel) {
|
||||
if (k.speed <= top) {
|
||||
k.speed += (k.speed/top > params.accelSwitch)?params.accel2:params.accel1;
|
||||
if (k.speed > top) k.speed = top;
|
||||
} else {
|
||||
k.speed *= 0.95;
|
||||
}
|
||||
} else {
|
||||
k.speed *= params.decel;
|
||||
}
|
||||
}
|
||||
|
||||
if ((input.accel && k.speed >= 0) || (k.speed > 0.1)) {
|
||||
k.physicalDir += params.turnRate*input.turn;
|
||||
} else if ( k.speed < -0.1) {
|
||||
k.physicalDir -= params.turnRate*input.turn;
|
||||
}
|
||||
|
||||
if (input.drift) {
|
||||
ylvel = 1.25;
|
||||
k.vel[1] += 1.25;
|
||||
k.airTime = 4;
|
||||
k.drifting = true;
|
||||
k.driftLanded = false;
|
||||
k.driftMode = 0;
|
||||
k.ylock = 0;
|
||||
|
||||
var boing = nitroAudio.playSound(207, {transpose: -4}, 0, k);
|
||||
boing.gainN.gain.value = 2;
|
||||
}
|
||||
} else {
|
||||
if (input.drift) {
|
||||
ylvel = 0;
|
||||
k.drifting = true;
|
||||
k.driftLanded = false;
|
||||
k.driftMode = 0;
|
||||
k.ylock = -0.001;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
k.physicalDir = fixDir(k.physicalDir);
|
||||
|
||||
if (k.driftOff != 0 && (!k.drifting || !k.driftLanded)) {
|
||||
if (k.driftOff > 0) {
|
||||
k.physicalDir += params.driftOffRestore;
|
||||
k.driftOff -= params.driftOffRestore;
|
||||
if (k.driftOff < 0) k.driftOff = 0;
|
||||
} else {
|
||||
k.physicalDir -= params.driftOffRestore;
|
||||
k.driftOff += params.driftOffRestore;
|
||||
if (k.driftOff > 0) k.driftOff = 0;
|
||||
}
|
||||
}
|
||||
|
||||
checkKartCollision(scene);
|
||||
|
||||
if (!onGround) {
|
||||
this.kartTargetNormal = [0, 1, 0];
|
||||
vec3.add(k.vel, k.vel, k.gravity)
|
||||
if (k.ylock >= 0) {
|
||||
ylvel += k.gravity[1];
|
||||
k.ylock += ylvel;
|
||||
}
|
||||
|
||||
if (k.kartColTimer == COLBOUNCE_TIME) {
|
||||
vec3.add(k.vel, k.vel, k.kartColVel);
|
||||
}
|
||||
} else {
|
||||
k.angle += dirDiff(k.physicalDir, k.angle)*effect.handling/2;
|
||||
k.angle = fixDir(k.physicalDir);
|
||||
|
||||
k.vel[1] += k.gravity[1];
|
||||
k.vel = [Math.sin(k.angle)*k.speed, k.vel[1], -Math.cos(k.angle)*k.speed]
|
||||
|
||||
if (k.kartColTimer > 0) {
|
||||
vec3.add(k.vel, k.vel, vec3.scale([], k.kartColVel, k.kartColTimer/10))
|
||||
}
|
||||
}
|
||||
|
||||
if (k.kartColTimer > 0) k.kartColTimer--;
|
||||
|
||||
wheelTurn += k.speed/16;
|
||||
wheelTurn = fixDir(wheelTurn);
|
||||
k.airTime++;
|
||||
//end kart controls
|
||||
|
||||
//move kart on moving platforms (no collision, will be corrected by next step)
|
||||
if (stuckTo != null) {
|
||||
if (stuckTo.moveWith != null) stuckTo.moveWith(k);
|
||||
stuckTo = null;
|
||||
}
|
||||
|
||||
//move kart.
|
||||
|
||||
|
||||
|
||||
var steps = 0;
|
||||
var remainingT = 1;
|
||||
var velSeg = vec3.clone(k.vel);
|
||||
var posSeg = vec3.clone(k.pos);
|
||||
var ignoreList = [];
|
||||
while (steps++ < 10 && remainingT > 0.01) {
|
||||
var result = lsc.sweepEllipse(posSeg, velSeg, scene, [params.colRadius, params.colRadius, params.colRadius], ignoreList);
|
||||
if (result != null) {
|
||||
colResponse(posSeg, velSeg, result, ignoreList)
|
||||
remainingT -= result.t;
|
||||
if (remainingT > 0.01) {
|
||||
velSeg = vec3.scale(vec3.create(), k.vel, remainingT);
|
||||
}
|
||||
} else {
|
||||
vec3.add(posSeg, posSeg, velSeg);
|
||||
remainingT = 0;
|
||||
}
|
||||
}
|
||||
k.pos = posSeg;
|
||||
}
|
||||
|
||||
//interpolate visual normal roughly to target
|
||||
var rate = onGround?0.15:0.025;
|
||||
k.kartNormal[0] += (k.kartTargetNormal[0]-k.kartNormal[0])*rate;
|
||||
k.kartNormal[1] += (k.kartTargetNormal[1]-k.kartNormal[1])*rate;
|
||||
k.kartNormal[2] += (k.kartTargetNormal[2]-k.kartNormal[2])*rate;
|
||||
vec3.normalize(k.kartNormal, k.kartNormal);
|
||||
|
||||
k.basis = buildBasis();
|
||||
|
||||
var mat = mat4.create();
|
||||
mat4.translate(mat, mat, k.pos);
|
||||
k.mat = mat4.mul(mat, mat, k.basis);
|
||||
|
||||
if (input.item) {
|
||||
scene.items.addItem(0, scene.karts.indexOf(k), {})
|
||||
}
|
||||
|
||||
updateKartSound(newSoundMode, input);
|
||||
positionChanged(lastPos, k.pos);
|
||||
}
|
||||
|
||||
function genFutureChecks() {
|
||||
//all future points that
|
||||
var chosen = {}
|
||||
var current = checkpoints[k.checkPointNumber];
|
||||
var expectedSection = current.nextSection;
|
||||
futureChecks = [];
|
||||
for (var i=k.checkPointNumber+1; i<checkpoints.length; i++) {
|
||||
var check = checkpoints[i];
|
||||
if (expectedSection != -1 && check.currentSection != expectedSection) continue;
|
||||
|
||||
if (chosen[check.currentSection] != true) {
|
||||
futureChecks.push(i);
|
||||
chosen[check.currentSection] = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function positionChanged(oldPos, pos) {
|
||||
//crossed into new checkpoint?
|
||||
for (var i=0; i<futureChecks.length; i++) {
|
||||
var check = checkpoints[futureChecks[i]];
|
||||
var distOld = vec2.sub([], [check.x1, check.z1], [oldPos[0], oldPos[2]]);
|
||||
var dist = vec2.sub([], [check.x1, check.z1], [pos[0], pos[2]]);
|
||||
var dot = vec2.dot(dist, [check.sinus, check.cosinus]);
|
||||
var dotOld = vec2.dot(distOld, [check.sinus, check.cosinus]);
|
||||
|
||||
var lineCheck = vec2.sub([], [check.x1, check.z1], [check.x2, check.z2]);
|
||||
var lineDot = vec2.dot(dist, lineCheck);
|
||||
|
||||
if (lineDot > 0 && lineDot < vec2.sqrLen(lineCheck) && dot < 0 && dotOld >= 0) {
|
||||
k.checkPointNumber = futureChecks[i];
|
||||
genFutureChecks();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!k.passedKTP2 && forwardCrossedKTP(passLine, oldPos, pos)) k.passedKTP2 = true;
|
||||
if (k.passedKTP2 && futureChecks.length == 0) {
|
||||
//we can finish the lap
|
||||
if (forwardCrossedKTP(startLine, oldPos, pos)) {
|
||||
k.lapNumber++;
|
||||
k.checkPointNumber = 0;
|
||||
k.passedKTP2 = 0;
|
||||
scene.lapAdvance(k);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function forwardCrossedKTP(ktp, oldPos, pos) {
|
||||
var distOld = vec2.sub([], [ktp.pos[0], ktp.pos[2]], [oldPos[0], oldPos[2]]);
|
||||
var dist = vec2.sub([], [ktp.pos[0], ktp.pos[2]], [pos[0], pos[2]]);
|
||||
|
||||
var ang = (ktp.angle[1]/180)*Math.PI;
|
||||
|
||||
var sinus = Math.sin(ang);
|
||||
var cosinus = Math.cos(ang);
|
||||
|
||||
var dot = vec2.dot(dist, [sinus, cosinus]);
|
||||
var dotOld = vec2.dot(distOld, [sinus, cosinus]);
|
||||
|
||||
return (dot < 0 && dotOld >= 0);
|
||||
}
|
||||
|
||||
function checkKartCollision(scene) { //check collision with other karts. Really simple.
|
||||
for (var i=0; i<scene.karts.length; i++) {
|
||||
var ok = scene.karts[i];
|
||||
if (!ok.active) continue;
|
||||
if (k != ok) {
|
||||
var dist = vec3.dist(k.pos, ok.pos);
|
||||
if (dist < 16) {
|
||||
|
||||
kartBounce(ok);
|
||||
ok.kartBounce(k);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
function kartBounce(ok) {
|
||||
k.kartColTimer = COLBOUNCE_TIME;
|
||||
var weightMul = COLBOUNCE_STRENGTH*(1+(ok.weight-k.weight))*((ok.boostNorm>0 || ok.boostMT>0)?2:1)*((k.boostNorm>0 || k.boostMT>0)?0.5:1);
|
||||
|
||||
//as well as side bounce also add velocity difference if other vel > mine.
|
||||
|
||||
vec3.sub(k.kartColVel, k.pos, ok.pos);
|
||||
k.kartColVel[1] = 0;
|
||||
vec3.normalize(k.kartColVel, k.kartColVel);
|
||||
vec3.scale(k.kartColVel, k.kartColVel, weightMul);
|
||||
|
||||
if (vec3.length(k.vel) < vec3.length(ok.vel)) vec3.add(k.kartColVel, k.kartColVel, vec3.sub([], ok.vel, k.vel));
|
||||
|
||||
k.kartColVel[1] = 0;
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
function updateKartSound(mode, input) {
|
||||
var turn = (onGround && !k.drifting)?(1-Math.abs(input.turn)/11):1;
|
||||
var transpose = (mode == 0)?0:(22*turn*k.speed/params.topSpeed);
|
||||
|
||||
sounds.transpose += (transpose-sounds.transpose)/15;
|
||||
if (mode != soundMode) {
|
||||
soundMode = mode;
|
||||
if (sounds.kart != null) nitroAudio.instaKill(sounds.kart);
|
||||
sounds.kart = nitroAudio.playSound(kartSoundBase+soundMode, {transpose:sounds.transpose, volume:1}, 0, k);
|
||||
//if (mode == 3) sounds.kart.gainN.gain.value = 0.5;
|
||||
} else {
|
||||
sounds.kart.seq.setTranspose(sounds.transpose);
|
||||
}
|
||||
}
|
||||
|
||||
function buildBasis() {
|
||||
//order y, x, z
|
||||
var dir = k.physicalDir+k.driftOff+(Math.sin((COLBOUNCE_TIME-k.kartColTimer)/3)*(Math.PI/6)*(k.kartColTimer/COLBOUNCE_TIME));
|
||||
var basis = gramShmidt(k.kartNormal, [Math.cos(dir), 0, Math.sin(dir)], [Math.sin(dir), 0, -Math.cos(dir)]);
|
||||
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 sndUpdate(view) {
|
||||
k.soundProps.pos = vec3.transformMat4([], k.pos, view);
|
||||
if (k.soundProps.lastPos != null) k.soundProps.vel = vec3.sub([], k.soundProps.pos, k.soundProps.lastPos);
|
||||
else k.soundProps.vel = [0, 0, 0];
|
||||
k.soundProps.lastPos = k.soundProps.pos;
|
||||
|
||||
k.soundProps.refDistance = 192/1024;
|
||||
k.soundProps.rolloffFactor = 1;
|
||||
|
||||
var calcVol = (k.soundProps.refDistance / (k.soundProps.refDistance + k.soundProps.rolloffFactor * (Math.sqrt(vec3.dot(k.soundProps.pos, k.soundProps.pos)) - k.soundProps.refDistance)));
|
||||
}
|
||||
|
||||
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 colSound(collision, effect) {
|
||||
if (MKDS_COLTYPE.SOUNDMAP[collision] == null) return {};
|
||||
return MKDS_COLTYPE.SOUNDMAP[collision][effect] || {};
|
||||
}
|
||||
|
||||
function project(u, v) {
|
||||
return vec3.scale([], u, (vec3.dot(u, v)/vec3.dot(u, u)))
|
||||
}
|
||||
|
||||
function colResponse(pos, pvel, dat, ignoreList) {
|
||||
|
||||
var plane = dat.plane;
|
||||
var colType = (plane.CollisionType>>8)&31;
|
||||
var colBE = (plane.CollisionType>>5)&7;
|
||||
|
||||
lastCollided = colType;
|
||||
lastBE = colBE;
|
||||
lastColSounds = colSound(lastCollided, colBE);
|
||||
|
||||
var n = vec3.normalize([], dat.normal);
|
||||
var gravS = Math.sqrt(vec3.dot(k.gravity, k.gravity));
|
||||
var angle = Math.acos(vec3.dot(vec3.scale(vec3.create(), k.gravity, -1/gravS), n));
|
||||
var adjustPos = true;
|
||||
|
||||
if (MKDS_COLTYPE.GROUP_WALL.indexOf(colType) != -1) { //wall
|
||||
//sliding plane, except normal is transformed to be entirely on the xz plane (cannot ride on top of wall, treated as vertical)
|
||||
var xz = Math.sqrt(n[0]*n[0]+n[2]*n[2])
|
||||
var adjN = [n[0]/xz, 0, n[2]/xz]
|
||||
var proj = vec3.dot(k.vel, adjN);
|
||||
|
||||
if (proj < -1) {
|
||||
if (lastColSounds.hit != null) nitroAudio.playSound(lastColSounds.hit, {volume:1}, 0, k)
|
||||
}
|
||||
vec3.sub(k.vel, k.vel, vec3.scale(vec3.create(), adjN, proj));
|
||||
|
||||
//convert back to angle + speed to keep change to kart vel
|
||||
|
||||
var v = k.vel;
|
||||
k.speed = Math.sqrt(v[0]*v[0]+v[2]*v[2]);
|
||||
k.angle = Math.atan2(v[0], -v[2]);
|
||||
} else if (MKDS_COLTYPE.GROUP_ROAD.indexOf(colType) != -1) {
|
||||
//sliding plane
|
||||
if (MKDS_COLTYPE.GROUP_BOOST.indexOf(colType) != -1) {
|
||||
k.boostNorm = BOOSTTIME;
|
||||
}
|
||||
|
||||
if (k.vel[1] > 0) k.vel[1] = 0;
|
||||
var proj = vec3.dot(k.vel, n);
|
||||
if (proj < -4 && k.vel[1] < -2) { proj -= 1.5; }
|
||||
vec3.sub(k.vel, k.vel, vec3.scale(vec3.create(), n, proj));
|
||||
k.kartTargetNormal = dat.pNormal;
|
||||
if (!onGround) {
|
||||
console.log("ground: "+colType+", "+colBE);
|
||||
groundAnim = 0;
|
||||
if (lastColSounds.land != null) nitroAudio.playSound(lastColSounds.land, {volume:1}, 0, k)
|
||||
}
|
||||
k.airTime = 0;
|
||||
stuckTo = dat.object;
|
||||
} else if (colType == MKDS_COLTYPE.CANNON) {
|
||||
//cannon!!
|
||||
k.cannon = colBE;
|
||||
} else {
|
||||
adjustPos = false;
|
||||
ignoreList.push(plane);
|
||||
}
|
||||
|
||||
//vec3.add(pos, pos, vec3.scale(vec3.create(), n, minimumMove)); //move away from plane slightly
|
||||
|
||||
if (adjustPos) { //move back from plane slightly
|
||||
//vec3.add(pos, pos, vec3.scale(vec3.create(), n, minimumMove));
|
||||
vec3.add(pos, pos, vec3.scale(vec3.create(), pvel, dat.t));
|
||||
vec3.add(pos, vec3.scale([], n, params.colRadius+minimumMove), dat.colPoint);
|
||||
/*if (dat.embedded) {
|
||||
|
||||
} else {
|
||||
var velMag = Math.sqrt(vec3.dot(pvel, pvel));
|
||||
if (velMag*dat.t > minimumMove) {
|
||||
vec3.add(pos, pos, vec3.scale(vec3.create(), pvel, dat.t-(minimumMove/velMag)));
|
||||
} else {
|
||||
//do not move, too close
|
||||
}
|
||||
}*/
|
||||
} else {
|
||||
vec3.add(pos, pos, vec3.scale(vec3.create(), pvel, dat.t));
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,119 @@
|
||||
//
|
||||
// objDatabase.js
|
||||
//--------------------
|
||||
// Links object IDs to specific entity types. Must be initialized after all js files are loaded!
|
||||
// by RHY3756547
|
||||
//
|
||||
// includes:
|
||||
// entities/*
|
||||
//
|
||||
|
||||
window.objDatabase = new (function(){
|
||||
|
||||
this.init = function() {
|
||||
this.idToType = [];
|
||||
|
||||
var t = this.idToType;
|
||||
t[0x0001] = ObjWater;
|
||||
t[0x0003] = ObjWater;
|
||||
t[0x0006] = ObjWater;
|
||||
t[0x0008] = ObjSoundMaker;
|
||||
t[0x0009] = ObjWater;
|
||||
t[0x000C] = ObjWater;
|
||||
|
||||
t[0x0065] = ItemBox;
|
||||
|
||||
t[0x00CA] = ObjRoutePlatform;
|
||||
t[0x00CB] = ObjGear;
|
||||
t[0x00CE] = ObjGear; //test_cylinder, tick tock clock end
|
||||
t[0x00D0] = ObjRotaryRoom;
|
||||
t[0x00D1] = ObjGear; //rotary bridge
|
||||
|
||||
t[0x012D] = ObjDecor;
|
||||
t[0x012E] = ObjDecor;
|
||||
t[0x012F] = ObjDecor;
|
||||
|
||||
t[0x0130] = ObjDecor;
|
||||
t[0x0131] = ObjDecor;
|
||||
t[0x0132] = ObjDecor;
|
||||
t[0x0133] = ObjDecor;
|
||||
t[0x0134] = ObjDecor;
|
||||
t[0x0135] = ObjDecor;
|
||||
t[0x0138] = ObjDecor;
|
||||
t[0x0139] = ObjDecor;
|
||||
t[0x013C] = ObjDecor; //DEBUG: cheep cheep (routed)
|
||||
t[0x013D] = ObjDecor; //DEBUG: ghost
|
||||
|
||||
t[0x013A] = ObjDecor; //figure 8 tree
|
||||
t[0x013C] = ObjDecor;
|
||||
t[0x013F] = ObjDecor;
|
||||
|
||||
t[0x0140] = ObjDecor;
|
||||
t[0x0142] = ObjDecor; //more trees
|
||||
t[0x0145] = ObjDecor;
|
||||
t[0x0146] = ObjDecor;
|
||||
t[0x0148] = ObjDecor;
|
||||
t[0x0149] = ObjDecor; //yoshi falls egg
|
||||
|
||||
t[0x014B] = ObjDecor;
|
||||
t[0x014C] = ObjDecor;
|
||||
t[0x014D] = ObjDecor;
|
||||
t[0x014E] = ObjDecor;
|
||||
t[0x014F] = ObjDecor;
|
||||
|
||||
t[0x0150] = ObjDecor;
|
||||
t[0x0151] = ObjDecor;
|
||||
t[0x0152] = ObjDecor;
|
||||
t[0x0153] = ObjDecor;
|
||||
t[0x0154] = ObjDecor; //rainbow star
|
||||
t[0x0155] = ObjDecor;
|
||||
t[0x0156] = ObjDecor;
|
||||
t[0x0157] = ObjDecor;
|
||||
|
||||
t[0x019C] = ObjTruck;
|
||||
t[0x019A] = ObjCar;
|
||||
t[0x0195] = ObjBus;
|
||||
|
||||
|
||||
t[0x00CC] = ObjDecor; //DEBUG: pianta bridge
|
||||
t[0x000D] = ObjDecor; //DEBUG: puddle
|
||||
|
||||
t[0x0158] = ObjDecor; //DEBUG: airship (routed)
|
||||
|
||||
//DEBUG ENEMIES AS DECOR: switch as implemented:
|
||||
|
||||
t[0x0191] = ObjDecor;
|
||||
t[0x0192] = ObjDecor;
|
||||
t[0x0193] = ObjDecor;
|
||||
t[0x0196] = ObjDecor;
|
||||
t[0x0198] = ObjDecor;
|
||||
t[0x0199] = ObjDecor;
|
||||
//truck
|
||||
t[0x019B] = ObjDecor;
|
||||
t[0x019D] = ObjDecor;
|
||||
t[0x019E] = ObjDecor;
|
||||
|
||||
t[0x01A0] = ObjDecor;
|
||||
t[0x01A1] = ObjDecor;
|
||||
t[0x01A3] = ObjDecor;
|
||||
t[0x01A4] = ObjDecor;
|
||||
t[0x01A5] = ObjDecor;
|
||||
t[0x01A6] = ObjDecor;
|
||||
t[0x01A7] = ObjDecor;
|
||||
t[0x01A8] = ObjDecor;
|
||||
t[0x01A9] = ObjDecor;
|
||||
|
||||
t[0x01AA] = ObjDecor;
|
||||
t[0x01AC] = ObjDecor;
|
||||
t[0x01AD] = ObjDecor;
|
||||
//rotating fireballs
|
||||
|
||||
t[0x01B0] = ObjDecor;
|
||||
t[0x01B1] = ObjDecor;
|
||||
t[0x01B2] = ObjDecor;
|
||||
t[0x01B3] = ObjDecor;
|
||||
t[0x01B4] = ObjDecor;
|
||||
t[0x01B5] = ObjDecor;
|
||||
}
|
||||
|
||||
})();
|
||||
@@ -0,0 +1,161 @@
|
||||
//
|
||||
// rotatingGear.js
|
||||
//--------------------
|
||||
// Provides rotating gear objects for tick tock clock
|
||||
// by RHY3756547
|
||||
//
|
||||
// includes:
|
||||
// render stuff idk
|
||||
//
|
||||
|
||||
window.ObjGear = function(obji, scene) {
|
||||
var obji = obji;
|
||||
var res = [];
|
||||
|
||||
var t = this;
|
||||
|
||||
t.collidable = true;
|
||||
t.colMode = 0;
|
||||
t.colRad = 512;
|
||||
t.getCollision = getCollision;
|
||||
t.moveWith = moveWith;
|
||||
|
||||
t.pos = vec3.clone(obji.pos);
|
||||
//t.angle = vec3.clone(obji.angle);
|
||||
t.scale = vec3.clone(obji.scale);
|
||||
|
||||
t.requireRes = requireRes;
|
||||
t.provideRes = provideRes;
|
||||
t.update = update;
|
||||
t.draw = draw;
|
||||
|
||||
t.speed = (obji.setting1&0xFFFF)/8192;
|
||||
t.duration = obji.setting1>>16;
|
||||
t.rampDur = obji.setting2&0xFFFF;
|
||||
t.statDur = obji.setting2>>16;
|
||||
t.wB1 = obji.setting3&0xFFFF; //ONE of these flips direction, the other makes the gear use the black model. Not sure which is which, but for tick tock clock there is no need to get this right.
|
||||
t.wB2 = obji.setting3>>16;
|
||||
|
||||
t.time = 0;
|
||||
t.mode = 0; //0=rampup, 1=normal, 2=rampdown, 3=stationary
|
||||
t.angle = 0;
|
||||
t.dir = (t.wB1 == 0)
|
||||
|
||||
var dirVel = 0;
|
||||
|
||||
var prevMat;
|
||||
var curMat;
|
||||
setMat();
|
||||
prevMat = curMat;
|
||||
|
||||
function setMat() {
|
||||
prevMat = curMat;
|
||||
var mat = mat4.create();
|
||||
mat4.translate(mat, mat, t.pos);
|
||||
|
||||
mat4.scale(mat, mat, vec3.scale([], t.scale, 16));
|
||||
|
||||
mat4.rotateY(mat, mat, obji.angle[1]*(Math.PI/180));
|
||||
mat4.rotateX(mat, mat, obji.angle[0]*(Math.PI/180));
|
||||
|
||||
mat4.rotateY(mat, mat, t.angle);
|
||||
curMat = mat;
|
||||
}
|
||||
|
||||
function update(scene) {
|
||||
t.time++;
|
||||
switch (t.mode) {
|
||||
case 0:
|
||||
dirVel = t.speed*(t.time/t.rampDur)*((t.dir)?-1:1);
|
||||
if (t.time > t.rampDur) {
|
||||
t.time = 0; t.mode = 1;
|
||||
}
|
||||
break;
|
||||
case 1:
|
||||
dirVel = t.speed*((t.dir)?-1:1);
|
||||
if (t.time > t.duration) {
|
||||
t.time = 0; t.mode = 2;
|
||||
}
|
||||
break;
|
||||
case 2:
|
||||
dirVel = t.speed*(1-t.time/t.rampDur)*((t.dir)?-1:1);
|
||||
if (t.time > t.rampDur) {
|
||||
t.time = 0; t.mode = 3; t.dir = !t.dir;
|
||||
}
|
||||
break;
|
||||
case 3:
|
||||
dirVel = 0;
|
||||
if (t.time > t.statDur) {
|
||||
t.time = 0; t.mode = 0;
|
||||
}
|
||||
break;
|
||||
}
|
||||
t.angle += dirVel;
|
||||
setMat();
|
||||
}
|
||||
|
||||
function draw(view, pMatrix) {
|
||||
var mat = mat4.translate(mat4.create(), view, t.pos);
|
||||
|
||||
mat4.scale(mat, mat, vec3.scale([], t.scale, 16));
|
||||
|
||||
mat4.rotateY(mat, mat, obji.angle[1]*(Math.PI/180));
|
||||
mat4.rotateX(mat, mat, obji.angle[0]*(Math.PI/180));
|
||||
|
||||
mat4.rotateY(mat, mat, t.angle);
|
||||
|
||||
res.mdl[t.wB1].draw(mat, pMatrix);
|
||||
}
|
||||
|
||||
function requireRes() { //scene asks what resources to load
|
||||
switch (obji.ID) {
|
||||
case 0x00CB:
|
||||
return {mdl:[{nsbmd:"gear_white.nsbmd"}, {nsbmd:"gear_black.nsbmd"}]};
|
||||
case 0x00CE:
|
||||
return {mdl:[{nsbmd:"test_cylinder.nsbmd"}]};
|
||||
case 0x00D1:
|
||||
t.colRad = 4096;
|
||||
return {mdl:[{nsbmd:"rotary_bridge.nsbmd"}]};
|
||||
}
|
||||
}
|
||||
|
||||
function provideRes(r) {
|
||||
res = r; //...and gives them to us. :)
|
||||
}
|
||||
|
||||
function getCollision() {
|
||||
var obj = {};
|
||||
var inf = res.mdl[0].getCollisionModel(0, 0);
|
||||
obj.tris = inf.dat;
|
||||
|
||||
var mat = mat4.translate([], mat4.create(), t.pos);
|
||||
mat4.scale(mat, mat, vec3.mul([], [16*inf.scale, 16*inf.scale, 16*inf.scale], t.scale));
|
||||
|
||||
mat4.rotateY(mat, mat, obji.angle[1]*(Math.PI/180));
|
||||
mat4.rotateX(mat, mat, obji.angle[0]*(Math.PI/180));
|
||||
mat4.rotateY(mat, mat, t.angle);
|
||||
|
||||
obj.mat = mat;
|
||||
return obj;
|
||||
}
|
||||
|
||||
function moveWith(obj) { //used for collidable objects that move.
|
||||
|
||||
//the most general way to move something with an object is to multiply its position by the inverse mv matrix of that object, and then the new mv matrix.
|
||||
|
||||
vec3.transformMat4(obj.pos, obj.pos, mat4.invert([], prevMat))
|
||||
vec3.transformMat4(obj.pos, obj.pos, curMat)
|
||||
|
||||
/*var p = vec3.sub([], obj.pos, t.pos);
|
||||
|
||||
if (obji.ID == 0x00D1) { //todo: maybe something more general
|
||||
vec3.transformMat4(p, p, mat4.rotateX([], mat4.create(), dirVel));
|
||||
vec3.add(obj.pos, t.pos, p);
|
||||
} else {
|
||||
vec3.transformMat4(p, p, mat4.rotateY([], mat4.create(), dirVel));
|
||||
vec3.add(obj.pos, t.pos, p);
|
||||
obj.physicalDir -= dirVel;
|
||||
}*/
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,118 @@
|
||||
//
|
||||
// shell.js
|
||||
//--------------------
|
||||
// Entity type for shells. (green)
|
||||
// by RHY3756547
|
||||
//
|
||||
// includes: gl-matrix.js (glMatrix 2.0)
|
||||
// /formats/kcl.js
|
||||
//
|
||||
|
||||
window.GreenShell = function(scene, owner, time, itemID, cliID, params) {
|
||||
var t = this;
|
||||
var minimumMove = 0.01;
|
||||
|
||||
this.pos = vec3.transformMat4([], [0, (-owner.params.colRadius)+1, 16], owner.mat);
|
||||
this.vel = vec3.create();
|
||||
this.gravity = [0, -0.17, 0]; //100% confirmed by me messing around with the gravity value in mkds
|
||||
this.angle = owner.angle;
|
||||
this.speed = 10;
|
||||
this.yvel = 0;
|
||||
|
||||
this.update = update;
|
||||
this.draw = draw;
|
||||
|
||||
function update(scene) {
|
||||
t.vel = [Math.sin(t.angle)*t.speed, t.yvel, -Math.cos(t.angle)*t.speed]
|
||||
vec3.add(t.vel, t.vel, t.gravity);
|
||||
|
||||
//simple point move.
|
||||
|
||||
var steps = 0;
|
||||
var remainingT = 1;
|
||||
var velSeg = vec3.clone(t.vel);
|
||||
var posSeg = vec3.clone(t.pos);
|
||||
var ignoreList = [];
|
||||
while (steps++ < 10 && remainingT > 0.01) {
|
||||
var result = lsc.raycast(posSeg, velSeg, scene.kcl, 0.05, ignoreList);
|
||||
if (result != null) {
|
||||
colResponse(posSeg, velSeg, result, ignoreList)
|
||||
remainingT -= result.t;
|
||||
if (remainingT > 0.01) {
|
||||
velSeg = vec3.scale(vec3.create(), t.vel, remainingT);
|
||||
}
|
||||
} else {
|
||||
vec3.add(posSeg, posSeg, velSeg);
|
||||
remainingT = 0;
|
||||
}
|
||||
}
|
||||
t.pos = posSeg;
|
||||
|
||||
t.yvel = t.vel[1];
|
||||
}
|
||||
|
||||
function draw(mvMatrix, pMatrix) {
|
||||
var mat = mat4.translate(mat4.create(), mvMatrix, vec3.add(vec3.create(), t.pos, [0, 3, 0]));
|
||||
|
||||
spritify(mat);
|
||||
mat4.scale(mat, mat, [16, 16, 16]);
|
||||
|
||||
scene.gameRes.items.koura_g.draw(mat, pMatrix);
|
||||
}
|
||||
|
||||
var spritify = function(mat, scale) {
|
||||
var scale = (scale == null)?Math.sqrt(mat[0]*mat[0]+mat[1]*mat[1]+mat[2]*mat[2]):scale;
|
||||
|
||||
mat[0]=scale; mat[1]=0; mat[2]=0;
|
||||
mat[4]=0; mat[5]=scale; mat[6]=0;
|
||||
mat[8]=0; mat[9]=0; mat[10]=scale;
|
||||
}
|
||||
|
||||
function colResponse(pos, pvel, dat, ignoreList) {
|
||||
|
||||
var plane = dat.plane;
|
||||
var colType = (plane.CollisionType>>8)&31;
|
||||
vec3.add(pos, pos, vec3.scale(vec3.create(), pvel, dat.t));
|
||||
|
||||
var n = dat.normal;
|
||||
vec3.normalize(n, n);
|
||||
var gravS = Math.sqrt(vec3.dot(t.gravity, t.gravity));
|
||||
var angle = Math.acos(vec3.dot(vec3.scale(vec3.create(), t.gravity, -1/gravS), n));
|
||||
var adjustPos = true
|
||||
|
||||
if (MKDS_COLTYPE.GROUP_WALL.indexOf(colType) != -1) { //wall
|
||||
//shell reflection code - slide y vel across plane, bounce on xz
|
||||
vec3.add(t.vel, vec3.scale(vec3.create(), n, -2*(vec3.dot(t.vel, n)/vec3.dot(n,n))), t.vel);
|
||||
t.vel[1] = 0;
|
||||
|
||||
var v = t.vel;
|
||||
t.angle = Math.atan2(v[0], -v[2]);
|
||||
|
||||
} else if (MKDS_COLTYPE.GROUP_ROAD.indexOf(colType) != -1) {
|
||||
//sliding plane
|
||||
var proj = vec3.dot(t.vel, n);
|
||||
vec3.sub(t.vel, t.vel, vec3.scale(vec3.create(), n, proj));
|
||||
} else {
|
||||
adjustPos = false;
|
||||
ignoreList.push(plane);
|
||||
}
|
||||
|
||||
var rVelMag = Math.sqrt(vec3.dot(t.vel, t.vel));
|
||||
vec3.scale(t.vel, t.vel, t.speed/rVelMag); //force speed to shell speed for green shells.
|
||||
|
||||
//vec3.add(pos, pos, vec3.scale(vec3.create(), n, minimumMove)); //move away from plane slightly
|
||||
|
||||
if (adjustPos) { //move back from plane slightly
|
||||
vec3.add(pos, pos, vec3.scale(vec3.create(), n, minimumMove));
|
||||
/*
|
||||
var velMag = Math.sqrt(vec3.dot(pvel, pvel));
|
||||
if (velMag*dat.t > minimumMove) {
|
||||
vec3.sub(pos, pos, vec3.scale(vec3.create(), pvel, minimumMove/velMag)); //move back slightly after moving
|
||||
} else {
|
||||
vec3.sub(pos, pos, vec3.scale(vec3.create(), pvel, dat.t)); //if we're already too close undo the movement.
|
||||
}
|
||||
*/
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,77 @@
|
||||
//
|
||||
// soundMaker.js
|
||||
//--------------------
|
||||
// Provides env sound object, such as crowd for figure 8
|
||||
// by RHY3756547
|
||||
//
|
||||
|
||||
//0008
|
||||
|
||||
window.ObjSoundMaker = function(obji, scene) {
|
||||
var obji = obji;
|
||||
|
||||
var t = this;
|
||||
|
||||
t.pos = vec3.clone(obji.pos);
|
||||
|
||||
t.soundProps = {};
|
||||
t.sndUpdate = sndUpdate;
|
||||
t.requireRes = requireRes;
|
||||
t.provideRes = provideRes;
|
||||
t.update = update;
|
||||
t.draw = draw;
|
||||
|
||||
var mat = mat4.create();
|
||||
var frame = 0;
|
||||
|
||||
var sound = null;
|
||||
var sN = 0;
|
||||
var threshold = 0.2;
|
||||
var gain = 1;
|
||||
switch (obji.ID) {
|
||||
case 0x0008:
|
||||
sN = 259;
|
||||
gain = 2;
|
||||
threshold = 0.2;
|
||||
break;
|
||||
}
|
||||
|
||||
function draw(view, pMatrix) {
|
||||
|
||||
}
|
||||
|
||||
function update() {
|
||||
}
|
||||
|
||||
function sndUpdate(view) {
|
||||
t.soundProps.pos = vec3.transformMat4([], t.pos, view);
|
||||
t.soundProps.pos = [0, 0, Math.sqrt(vec3.dot(t.soundProps.pos, t.soundProps.pos))]
|
||||
//if (t.soundProps.lastPos != null) t.soundProps.vel = vec3.sub([], t.soundProps.pos, t.soundProps.lastPos);
|
||||
//else t.soundProps.vel = [0, 0, 0];
|
||||
//t.soundProps.lastPos = t.soundProps.pos;
|
||||
|
||||
t.soundProps.refDistance = 1024/1024;
|
||||
//t.soundProps.rolloffFactor = 1;
|
||||
|
||||
var calcVol = (t.soundProps.refDistance / (t.soundProps.refDistance + t.soundProps.rolloffFactor * (t.soundProps.pos[2] - t.soundProps.refDistance)));
|
||||
|
||||
if (calcVol<threshold) {
|
||||
if (sound != null) {
|
||||
nitroAudio.instaKill(sound);
|
||||
sound = null;
|
||||
}
|
||||
} else {
|
||||
if (sound == null) {
|
||||
sound = nitroAudio.playSound(sN, {}, 0, t);
|
||||
sound.gainN.gain.value = gain;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function requireRes() {
|
||||
return {mdl: []};
|
||||
}
|
||||
|
||||
function provideRes(r) { }
|
||||
|
||||
}
|
||||
@@ -0,0 +1,94 @@
|
||||
//
|
||||
// trafficCar.js
|
||||
//--------------------
|
||||
// Provides multiple types of traffic.
|
||||
// by RHY3756547
|
||||
//
|
||||
// includes:
|
||||
// render stuff idk
|
||||
//
|
||||
|
||||
window.ObjTruck = function(obji, scene) {
|
||||
var obji = obji;
|
||||
var res = [];
|
||||
|
||||
var t = this;
|
||||
|
||||
t.pos = vec3.clone(obji.pos);
|
||||
//t.angle = vec3.clone(obji.angle);
|
||||
t.scale = vec3.clone(obji.scale);
|
||||
|
||||
t.requireRes = requireRes;
|
||||
t.provideRes = provideRes;
|
||||
t.update = update;
|
||||
t.draw = draw;
|
||||
|
||||
t.route = scene.paths[obji.routeID];
|
||||
t.routeSpeed = (obji.setting1>>16)/100;
|
||||
t.routePos = (obji.setting1&0xFFFF)%t.route.length;
|
||||
t.nextNode = t.route[t.routePos];
|
||||
t.prevPos = t.pos;
|
||||
t.elapsedTime = 0;
|
||||
|
||||
var facingNormal = [0, 1, 0];
|
||||
var curNormal = [0, 1, 0];
|
||||
var floorNormal = [0, 1, 0];
|
||||
|
||||
function update(scene) {
|
||||
//simple behaviour, just follow the path! piece of cake.
|
||||
t.elapsedTime += t.routeSpeed;
|
||||
t.pos = vec3.lerp([], t.prevPos, t.nextNode.pos, t.elapsedTime/t.nextNode.duration);
|
||||
if (t.elapsedTime >= t.nextNode.duration) {
|
||||
t.elapsedTime = 0;
|
||||
t.prevPos = t.nextNode.pos;
|
||||
t.routePos = (t.routePos+1)%t.route.length;
|
||||
t.nextNode = t.route[t.routePos];
|
||||
}
|
||||
|
||||
facingNormal = vec3.sub([], t.prevPos, t.nextNode.pos)
|
||||
vec3.normalize(facingNormal, facingNormal);
|
||||
|
||||
var rate = 0.025
|
||||
curNormal[0] += (facingNormal[0]-curNormal[0])*rate;
|
||||
curNormal[1] += (facingNormal[1]-curNormal[1])*rate;
|
||||
curNormal[2] += (facingNormal[2]-curNormal[2])*rate;
|
||||
vec3.normalize(curNormal, curNormal);
|
||||
|
||||
var spos = vec3.clone(t.pos);
|
||||
spos[1] += 32;
|
||||
var result = lsc.raycast(spos, [0, -100, 0], scene.kcl, 0.05, []);
|
||||
if (result != null) {
|
||||
floorNormal = result.normal;
|
||||
} else {
|
||||
floorNormal = [0,1,0];
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
function draw(view, pMatrix) {
|
||||
var mat = mat4.translate(mat4.create(), view, t.pos);
|
||||
|
||||
mat4.scale(mat, mat, vec3.scale([], t.scale, 16));
|
||||
|
||||
mat4.mul(mat, mat, mat4.invert([], mat4.lookAt([], [0, 0, 0], curNormal, floorNormal)));
|
||||
res.mdl[0].draw(mat, pMatrix);
|
||||
}
|
||||
|
||||
function requireRes() { //scene asks what resources to load
|
||||
switch (obji.ID) {
|
||||
case 0x019A:
|
||||
return {mdl:[{nsbmd:"car_a.nsbmd"}]}; //one model, car
|
||||
case 0x019C:
|
||||
return {mdl:[{nsbmd:"truck_a.nsbmd"}]}; //one model, truck
|
||||
case 0x0195:
|
||||
return {mdl:[{nsbmd:"bus_a.nsbmd"}]}; //one model, bus
|
||||
}
|
||||
}
|
||||
|
||||
function provideRes(r) {
|
||||
res = r; //...and gives them to us. :)
|
||||
}
|
||||
}
|
||||
|
||||
window.ObjCar = ObjTruck;
|
||||
window.ObjBus = ObjTruck;
|
||||
@@ -0,0 +1,86 @@
|
||||
//
|
||||
// water.js
|
||||
//--------------------
|
||||
// Provides multiple types of traffic.
|
||||
// by RHY3756547
|
||||
//
|
||||
// includes:
|
||||
// render stuff idk
|
||||
//
|
||||
|
||||
window.ObjWater = function(obji, scene) {
|
||||
var obji = obji;
|
||||
var res = [];
|
||||
|
||||
var t = this;
|
||||
|
||||
t.pos = vec3.clone(obji.pos);
|
||||
//t.angle = vec3.clone(obji.angle);
|
||||
t.scale = vec3.clone(obji.scale);
|
||||
|
||||
t.requireRes = requireRes;
|
||||
t.provideRes = provideRes;
|
||||
t.update = update;
|
||||
t.draw = draw;
|
||||
var frame = 0;
|
||||
|
||||
function draw(view, pMatrix) {
|
||||
if (nitroRender.flagShadow) return;
|
||||
var waterM = mat4.create();
|
||||
|
||||
gl.enable(gl.STENCIL_TEST);
|
||||
gl.stencilMask(0xFF);
|
||||
|
||||
gl.stencilFunc(gl.ALWAYS, 1, 0xFF);
|
||||
gl.stencilOp(gl.KEEP, gl.KEEP, gl.REPLACE); //when depth test passes for water lower layer, pixel is already drawn, do not cover it with the white overlay (set stencil bit)
|
||||
|
||||
var height = (t.pos[1])+6.144+Math.sin(frame/150)*12.288 //0.106
|
||||
|
||||
mat4.translate(waterM, view, [Math.sin(frame/180)*96, height-3.072, Math.cos(frame/146)*96])
|
||||
nitroRender.setAlpha(0x0A/31);
|
||||
res.mdl[0].drawPoly(mat4.scale([], waterM, [16, 16, 16]), pMatrix, 0, 0); //water
|
||||
|
||||
if (res.mdl[1] != null) {
|
||||
mat4.translate(waterM, view, [-Math.sin((frame+30)/180)*96, height-3, Math.cos((frame+100)/146)*96])
|
||||
nitroRender.setAlpha(0x02/31);
|
||||
res.mdl[1].draw(mat4.scale([], waterM, [16, 16, 16]), pMatrix); //water white detail part. stencil should do nothing here, since it's in the same position as the above.
|
||||
}
|
||||
|
||||
gl.stencilFunc(gl.EQUAL, 0, 0xFF);
|
||||
gl.stencilOp(gl.KEEP, gl.KEEP, gl.KEEP);
|
||||
|
||||
if (!obji.ID == 9) {
|
||||
mat4.translate(waterM, view, [0, height, 0])
|
||||
nitroRender.setAlpha(0x10/31);
|
||||
res.mdl[0].drawPoly(mat4.scale([], waterM, [16, 16, 16]), pMatrix, 0, 1); //white shore wash part, water is stencil masked out
|
||||
}
|
||||
|
||||
gl.disable(gl.STENCIL_TEST);
|
||||
|
||||
nitroRender.setAlpha(1);
|
||||
}
|
||||
|
||||
function update() {
|
||||
frame = (frame+1)%197100; //it's a big number but yolo... we have the technology...
|
||||
}
|
||||
|
||||
function requireRes() { //scene asks what resources to load
|
||||
switch (obji.ID) {
|
||||
case 0x0001:
|
||||
return {mdl:[{nsbmd:"beach_waterC.nsbmd"}, {nsbmd:"beach_waterA.nsbmd"}]};
|
||||
case 0x0003:
|
||||
return {mdl:[{nsbmd:"town_waterC.nsbmd"}, {nsbmd:"town_waterA.nsbmd"}]};
|
||||
case 0x0006:
|
||||
return {mdl:[{nsbmd:"yoshi_waterC.nsbmd"}]};
|
||||
case 0x0009:
|
||||
return {mdl:[{nsbmd:"hyudoro_waterC.nsbmd"}, {nsbmd:"hyudoro_waterA.nsbmd"}]};
|
||||
case 0x000C:
|
||||
return {mdl:[{nsbmd:"mini_stage3_waterC.nsbmd"}, {nsbmd:"mini_stage3_waterA.nsbmd"}]};
|
||||
}
|
||||
}
|
||||
|
||||
function provideRes(r) {
|
||||
res = r; //...and gives them to us. :)
|
||||
}
|
||||
|
||||
}
|
||||
Reference in new issue
Block a user