- static float friction=1.5;
- static float elasticity=.3;
- static XYZ bounceness;
- static XYZ oldpos[100];
- static int numrepeats=3;
- static float groundlevel=.15;
- static float soundvolume;
- static int i,j,k,l,m;
- static XYZ temp,start,end;
- static XYZ terrainnormal;
- static float r=.05;
- static float r2=.08;
- static int whichhit;
- //static int whichjointstart,whichjointend;
- static float distance;
- static float frictionness;
- static XYZ terrainlight;
- static int whichpatchx;
- static int whichpatchz;
- static float damage;
- static bool freely;
- static float tempmult;
- static bool breaking;
- breaking=0;
-
- damage=0;
-
- if(free){
- freetime+=multiplier;
-
- whichpatchx=coords->x/(terrain.size/subdivision*terrain.scale*terraindetail);
- whichpatchz=coords->z/(terrain.size/subdivision*terrain.scale*terraindetail);
-
- terrainlight=*coords;
- objects.SphereCheckPossible(&terrainlight, 1);
- /*
- for(i=0; i<num_joints; i++){
- oldpos[i]=joints[i].position;
- }*/
-
- //Add velocity
- for(i=0; i<num_joints; i++){
- //if(!isnormal(joints[i].velocity.x)||!isnormal(joints[i].velocity.y)||!isnormal(joints[i].velocity.z))joints[i].velocity=0;
- joints[i].position=joints[i].position+joints[i].velocity*multiplier;
- groundlevel=.15;
- if(joints[i].label==head)groundlevel=.8;
- if(joints[i].label==righthand||joints[i].label==rightwrist||joints[i].label==rightelbow)groundlevel=.2;
- if(joints[i].label==lefthand||joints[i].label==leftwrist||joints[i].label==leftelbow)groundlevel=.2;
- joints[i].position.y-=groundlevel;
- //if(!joints[i].locked&&!broken)joints[i].velocity+=joints[i].velchange*multiplier*10*(500-longdead)/500;
- joints[i].oldvelocity=joints[i].velocity;
- }
- tempmult=multiplier;
- //multiplier/=numrepeats;
- for(j=0; j<numrepeats; j++){
- if(!joints[jointlabels[rightknee]].locked&&!joints[jointlabels[righthip]].locked){
- temp=joints[jointlabels[rightknee]].position-(joints[jointlabels[righthip]].position+joints[jointlabels[rightankle]].position)/2;
- while(normaldotproduct(temp,lowforward)>-.1&&!sphere_line_intersection(&joints[jointlabels[righthip]].position,&joints[jointlabels[rightankle]].position,&joints[jointlabels[rightknee]].position,&r)){
- joints[jointlabels[rightknee]].position-=lowforward*.05;
- if(spinny)joints[jointlabels[rightknee]].velocity-=lowforward*.05/multiplier/4;
- else joints[jointlabels[rightknee]].velocity-=lowforward*.05;
- joints[jointlabels[rightankle]].position+=lowforward*.025;
- if(spinny)joints[jointlabels[rightankle]].velocity+=lowforward*.025/multiplier/4;
- else joints[jointlabels[rightankle]].velocity+=lowforward*.25;
- joints[jointlabels[righthip]].position+=lowforward*.025;
- if(spinny)joints[jointlabels[righthip]].velocity+=lowforward*.025/multiplier/4;
- else joints[jointlabels[righthip]].velocity+=lowforward*.025;
- temp=joints[jointlabels[rightknee]].position-(joints[jointlabels[righthip]].position+joints[jointlabels[rightankle]].position)/2;
- }
- }
- if(!joints[jointlabels[leftknee]].locked&&!joints[jointlabels[righthip]].locked){
- temp=joints[jointlabels[leftknee]].position-(joints[jointlabels[lefthip]].position+joints[jointlabels[leftankle]].position)/2;
- while(normaldotproduct(temp,lowforward)>-.1&&!sphere_line_intersection(&joints[jointlabels[lefthip]].position,&joints[jointlabels[leftankle]].position,&joints[jointlabels[leftknee]].position,&r)){
- joints[jointlabels[leftknee]].position-=lowforward*.05;
- if(spinny)joints[jointlabels[leftknee]].velocity-=lowforward*.05/multiplier/4;
- else joints[jointlabels[leftknee]].velocity-=lowforward*.05;
- joints[jointlabels[leftankle]].position+=lowforward*.025;
- if(spinny)joints[jointlabels[leftankle]].velocity+=lowforward*.025/multiplier/4;
- else joints[jointlabels[leftankle]].velocity+=lowforward*.25;
- joints[jointlabels[lefthip]].position+=lowforward*.025;
- if(spinny)joints[jointlabels[lefthip]].velocity+=lowforward*.025/multiplier/4;
- else joints[jointlabels[lefthip]].velocity+=lowforward*.025;
- temp=joints[jointlabels[leftknee]].position-(joints[jointlabels[lefthip]].position+joints[jointlabels[leftankle]].position)/2;
- }
- }
- /*
- if(terrain.patchobjectnum[whichpatchx][whichpatchz])
- for(m=0;m<terrain.patchobjectnum[whichpatchx][whichpatchz];m++){
- k=terrain.patchobjects[whichpatchx][whichpatchz][m];
- if(k<objects.numobjects&&k>=0)
- if(objects.possible[k]){
- temp=joints[jointlabels[head]].position*(*scale)+*coords;
- if(objects.model[k].SphereCheck(&temp, 0.06, &start, &objects.position[k], &objects.rotation[k])!=-1){
- //temp=(joints[jointlabels[head]].position*(*scale)+*coords)-start;
- //Normalise(&temp);
- //joints[jointlabels[head]].position=((temp*.2+start)-*coords)/(*scale);
- joints[jointlabels[head]].position=(temp-*coords)/(*scale);
- }
- }
- } */
-
-
- //Ears check
- /*XYZ startheadpos;
- startheadpos=joints[jointlabels[head]].position;
- XYZ headpos;
- headpos=joints[jointlabels[head]].position+(joints[jointlabels[head]].position-joints[jointlabels[neck]].position);
- if(terrain.patchobjectnum[whichpatchx][whichpatchz])
- for(m=0;m<terrain.patchobjectnum[whichpatchx][whichpatchz];m++){
- k=terrain.patchobjects[whichpatchx][whichpatchz][m];
- if(k<objects.numobjects&&k>=0)
- if(objects.possible[k]){
- friction=objects.friction[k];
- start=joints[jointlabels[head]].position*(*scale)+*coords;
- end=(headpos)*(*scale)+*coords;
- whichhit=objects.model[k].LineCheckPossible(&start,&end,&temp,&objects.position[k],&objects.rotation[k]);
- if(whichhit!=-1){
- if(joints[jointlabels[head]].label==groin&&!joints[jointlabels[head]].locked&&joints[jointlabels[head]].delay<=0){
- joints[jointlabels[head]].locked=1;
- joints[jointlabels[head]].delay=1;
- static float gLoc[3];
- static float vel[3];
- gLoc[0]=headpos.x*(*scale)+coords->x;
- gLoc[1]=headpos.y*(*scale)+coords->y;
- gLoc[2]=headpos.z*(*scale)+coords->z;
- vel[0]=joints[jointlabels[head]].velocity.x;
- vel[1]=joints[jointlabels[head]].velocity.y;
- vel[2]=joints[jointlabels[head]].velocity.z;
- PlaySoundEx( landsound1, samp[landsound1], NULL, true);
- OPENAL_3D_SetAttributes(channels[landsound1], gLoc, vel);
- OPENAL_SetVolume(channels[landsound1], 128);
- OPENAL_SetPaused(channels[landsound1], false);
-
- breaking=1;
- }
-
- if(joints[jointlabels[head]].label==head&&!joints[jointlabels[head]].locked&&joints[jointlabels[head]].delay<=0){
- joints[jointlabels[head]].locked=1;
- joints[jointlabels[head]].delay=1;
- static float gLoc[3];
- static float vel[3];
- gLoc[0]=headpos.x*(*scale)+coords->x;
- gLoc[1]=headpos.y*(*scale)+coords->y;
- gLoc[2]=headpos.z*(*scale)+coords->z;
- vel[0]=joints[jointlabels[head]].velocity.x;
- vel[1]=joints[jointlabels[head]].velocity.y;
- vel[2]=joints[jointlabels[head]].velocity.z;
- PlaySoundEx( landsound2, samp[landsound2], NULL, true);
- OPENAL_3D_SetAttributes(channels[landsound2], gLoc, vel);
- OPENAL_SetVolume(channels[landsound2], 128);
- OPENAL_SetPaused(channels[landsound2], false);
- }
-
- terrainnormal=DoRotation(objects.model[k].facenormals[whichhit],0,objects.rotation[k],0)*-1;
- if(terrainnormal.y>.8)freefall=0;
- bounceness=terrainnormal*findLength(&joints[jointlabels[head]].velocity)*(abs(normaldotproduct(joints[jointlabels[head]].velocity,terrainnormal)));
- if(findLengthfast(&joints[jointlabels[head]].velocity)>findLengthfast(&joints[jointlabels[head]].oldvelocity)){
- bounceness=0;
- joints[jointlabels[head]].velocity=joints[jointlabels[head]].oldvelocity;
- }
- if(findLengthfast(&bounceness)>4000&&breaking){
- objects.model[k].MakeDecal(breakdecal,DoRotation(temp-objects.position[k],0,-objects.rotation[k],0),.4,.5,Random()%360);
- Sprite::MakeSprite(cloudsprite, headpos*(*scale)+*coords,joints[jointlabels[head]].velocity*.06, 1,1,1, 4, .2);
- breaking=0;
- camerashake+=.6;
-
- static float gLoc[3];
- static float vel[3];
- gLoc[0]=headpos.x*(*scale)+coords->x;
- gLoc[1]=headpos.y*(*scale)+coords->y;
- gLoc[2]=headpos.z*(*scale)+coords->z;
- vel[0]=joints[jointlabels[head]].velocity.x;
- vel[1]=joints[jointlabels[head]].velocity.y;
- vel[2]=joints[jointlabels[head]].velocity.z;
- PlaySoundEx( breaksound2, samp[breaksound2], NULL, true);
- OPENAL_3D_SetAttributes(channels[breaksound2], gLoc, vel);
- OPENAL_SetVolume(channels[breaksound2], 300);
- OPENAL_SetPaused(channels[breaksound2], false);
-
- envsound[numenvsounds]=*coords;
- envsoundvol[numenvsounds]=64;
- envsoundlife[numenvsounds]=.4;
- numenvsounds++;
- }
- if(objects.type[k]==treetrunktype){
- objects.rotx[k]+=joints[jointlabels[head]].velocity.x*multiplier*.4;
- objects.roty[k]+=joints[jointlabels[head]].velocity.z*multiplier*.4;
- objects.rotx[k+1]+=joints[jointlabels[head]].velocity.x*multiplier*.4;
- objects.roty[k+1]+=joints[jointlabels[head]].velocity.z*multiplier*.4;
- }
- if(!joints[jointlabels[head]].locked)damage+=findLengthfast(&bounceness)/2500;
- ReflectVector(&joints[jointlabels[head]].velocity,&terrainnormal);
- frictionness=abs(normaldotproduct(joints[jointlabels[head]].velocity,terrainnormal));//findLength(&bounceness)/findLength(&joints[jointlabels[head]].velocity);
- joints[jointlabels[head]].velocity-=bounceness;
- if(1-friction*frictionness>0)joints[jointlabels[head]].velocity*=1-friction*frictionness;
- else joints[jointlabels[head]].velocity=0;
- if(findLengthfast(&bounceness)>2500){
- Normalise(&bounceness);
- bounceness=bounceness*50;
- }
- joints[jointlabels[head]].velocity+=bounceness*elasticity;
-
-
- if(!joints[jointlabels[head]].locked)
- if(findLengthfast(&joints[jointlabels[head]].velocity)<1){
- joints[jointlabels[head]].locked=1;
- //joints[jointlabels[head]].velocity*=3;
- }
- if(findLengthfast(&bounceness)>500)Sprite::MakeSprite(cloudsprite, headpos*(*scale)+*coords,joints[jointlabels[head]].velocity*.06, 1,1,1, .5, .2);
- joints[jointlabels[head]].position=(temp-*coords)/(*scale)+(startheadpos-headpos)+terrainnormal*.005;
- if(longdead>100)broken=1;
- }
- }
- }
- */
-
- for(i=0; i<num_joints; i++){
- //joints[i].delay-=multiplier/1.5;
- if(joints[i].locked)
- if(!spinny)if(findLengthfast(&joints[i].velocity)>320)joints[i].locked=0;
- if(spinny)if(findLengthfast(&joints[i].velocity)>600)joints[i].locked=0;
- if(joints[i].delay>0){
- freely=1;
- for(j=0;j<num_joints;j++){
- if(joints[j].locked)freely=0;
- }
- if(freely)joints[i].delay-=multiplier*3;
- }
- //if(joints[i].delay>0)
- //if(findLengthfast(&joints[i].velocity)>700&&joints[i].label!=head)joints[i].delay-=multiplier;
- }
-
- if(num_muscles)
- for(i=0; i<num_muscles; i++){
- //Length constraints
- //muscles[i].DoConstraint(broken);
- muscles[i].DoConstraint(spinny);
- }
-
- for(i=0; i<num_joints; i++){
- //joints[i].delay-=multiplier/1.5;
- //Length constraints
- //Ground constraint
- groundlevel=0;
- if(joints[i].position.y*(*scale)+coords->y<terrain.getHeight(joints[i].position.x*(*scale)+coords->x,joints[i].position.z*(*scale)+coords->z)+groundlevel){
- freefall=0;
- friction=1.5;
- if(joints[i].label==groin&&!joints[i].locked&&joints[i].delay<=0){
- joints[i].locked=1;
- joints[i].delay=1;
- if(tutoriallevel!=1||id==0){
- emit_sound_at(landsound1, joints[i].position*(*scale)+*coords, 128.);
- }
- breaking=1;
- }
-
- if(joints[i].label==head&&!joints[i].locked&&joints[i].delay<=0){
- joints[i].locked=1;
- joints[i].delay=1;
- if(tutoriallevel!=1||id==0){
- emit_sound_at(landsound2, joints[i].position*(*scale)+*coords, 128.);
- }
- }
-
- terrainnormal=terrain.getNormal(joints[i].position.x*(*scale)+coords->x,joints[i].position.z*(*scale)+coords->z);
- ReflectVector(&joints[i].velocity,&terrainnormal);
- bounceness=terrainnormal*findLength(&joints[i].velocity)*(abs(normaldotproduct(joints[i].velocity,terrainnormal)));
- if(!joints[i].locked)damage+=findLengthfast(&bounceness)/4000;
- if(findLengthfast(&joints[i].velocity)<findLengthfast(&bounceness))bounceness=0;
- frictionness=abs(normaldotproduct(joints[i].velocity,terrainnormal));//findLength(&bounceness)/findLength(&joints[i].velocity);
- joints[i].velocity-=bounceness;
- if(1-friction*frictionness>0)joints[i].velocity*=1-friction*frictionness;
- else joints[i].velocity=0;
-
- if(tutoriallevel!=1||id==0)
- if(findLengthfast(&bounceness)>8000&&breaking){
- objects.model[k].MakeDecal(breakdecal,DoRotation(temp-objects.position[k],0,-objects.rotation[k],0),.4,.5,Random()%360);
- Sprite::MakeSprite(cloudsprite, joints[i].position*(*scale)+*coords,joints[i].velocity*.06, 1,1,1, 4, .2);
- //Sprite::MakeSprite(cloudsprite, joints[i].position*(*scale)+*coords,joints[i].velocity*.06, 1,1,1, 1, .2);
- breaking=0;
- camerashake+=.6;
-
- emit_sound_at(breaksound2, joints[i].position*(*scale)+*coords);
-
- envsound[numenvsounds]=*coords;
- envsoundvol[numenvsounds]=64;
- envsoundlife[numenvsounds]=.4;
- numenvsounds++;
- }
-
- if(findLengthfast(&bounceness)>2500){
- Normalise(&bounceness);
- bounceness=bounceness*50;
- }
-
- joints[i].velocity+=bounceness*elasticity;
-
- if(findLengthfast(&joints[i].velocity)>findLengthfast(&joints[i].oldvelocity)){
- bounceness=0;
- joints[i].velocity=joints[i].oldvelocity;
- }
-
-
- if(joints[i].locked==0)
- if(findLengthfast(&joints[i].velocity)<1)joints[i].locked=1;
-
- if(environment==snowyenvironment&&findLengthfast(&bounceness)>500&&terrain.getOpacity(joints[i].position.x*(*scale)+coords->x,joints[i].position.z*(*scale)+coords->z)<.2){
- terrainlight=terrain.getLighting(joints[i].position.x*(*scale)+coords->x,joints[i].position.z*(*scale)+coords->z);
- Sprite::MakeSprite(cloudsprite, joints[i].position*(*scale)+*coords,joints[i].velocity*.06, terrainlight.x,terrainlight.y,terrainlight.z, .5, .7);
- if(detail==2)terrain.MakeDecal(bodyprintdecal, joints[i].position*(*scale)+*coords,.4,.4,0);
- }
- else if(environment==desertenvironment&&findLengthfast(&bounceness)>500&&terrain.getOpacity(joints[i].position.x*(*scale)+coords->x,joints[i].position.z*(*scale)+coords->z)<.2){
- terrainlight=terrain.getLighting(joints[i].position.x*(*scale)+coords->x,joints[i].position.z*(*scale)+coords->z);
- Sprite::MakeSprite(cloudsprite, joints[i].position*(*scale)+*coords,joints[i].velocity*.06, terrainlight.x*190/255,terrainlight.y*170/255,terrainlight.z*108/255, .5, .7);
- }
-
- else if(environment==grassyenvironment&&findLengthfast(&bounceness)>500&&terrain.getOpacity(joints[i].position.x*(*scale)+coords->x,joints[i].position.z*(*scale)+coords->z)<.2){
- terrainlight=terrain.getLighting(joints[i].position.x*(*scale)+coords->x,joints[i].position.z*(*scale)+coords->z);
- Sprite::MakeSprite(cloudsprite, joints[i].position*(*scale)+*coords,joints[i].velocity*.06, terrainlight.x*90/255,terrainlight.y*70/255,terrainlight.z*8/255, .5, .5);
- }
- else if(findLengthfast(&bounceness)>500)Sprite::MakeSprite(cloudsprite, joints[i].position*(*scale)+*coords,joints[i].velocity*.06, terrainlight.x,terrainlight.y,terrainlight.z, .5, .2);
-
-
- joints[i].position.y=(terrain.getHeight(joints[i].position.x*(*scale)+coords->x,joints[i].position.z*(*scale)+coords->z)+groundlevel-coords->y)/(*scale);
- if(longdead>100)broken=1;
- }
- if(terrain.patchobjectnum[whichpatchx][whichpatchz])
- for(m=0;m<terrain.patchobjectnum[whichpatchx][whichpatchz];m++){
- k=terrain.patchobjects[whichpatchx][whichpatchz][m];
- if(k<objects.numobjects&&k>=0)
- if(objects.possible[k]){
- friction=objects.friction[k];
- start=joints[i].realoldposition;
- end=joints[i].position*(*scale)+*coords;
- whichhit=objects.model[k].LineCheckPossible(&start,&end,&temp,&objects.position[k],&objects.rotation[k]);
- if(whichhit!=-1){
- if(joints[i].label==groin&&!joints[i].locked&&joints[i].delay<=0){
- joints[i].locked=1;
- joints[i].delay=1;
- if(tutoriallevel!=1||id==0){
- emit_sound_at(landsound1, joints[i].position*(*scale)+*coords, 128.);
- }
- breaking=1;
- }
-
- if(joints[i].label==head&&!joints[i].locked&&joints[i].delay<=0){
- joints[i].locked=1;
- joints[i].delay=1;
- if(tutoriallevel!=1||id==0){
- emit_sound_at(landsound2, joints[i].position*(*scale)+*coords, 128.);
- }
- }
-
- terrainnormal=DoRotation(objects.model[k].facenormals[whichhit],0,objects.rotation[k],0)*-1;
- if(terrainnormal.y>.8)freefall=0;
- bounceness=terrainnormal*findLength(&joints[i].velocity)*(abs(normaldotproduct(joints[i].velocity,terrainnormal)));
- if(findLengthfast(&joints[i].velocity)>findLengthfast(&joints[i].oldvelocity)){
- bounceness=0;
- joints[i].velocity=joints[i].oldvelocity;
- }
- if(tutoriallevel!=1||id==0)
- if(findLengthfast(&bounceness)>4000&&breaking){
- objects.model[k].MakeDecal(breakdecal,DoRotation(temp-objects.position[k],0,-objects.rotation[k],0),.4,.5,Random()%360);
- Sprite::MakeSprite(cloudsprite, joints[i].position*(*scale)+*coords,joints[i].velocity*.06, 1,1,1, 4, .2);
- breaking=0;
- camerashake+=.6;
-
- emit_sound_at(breaksound2, joints[i].position*(*scale)+*coords);
-
- envsound[numenvsounds]=*coords;
- envsoundvol[numenvsounds]=64;
- envsoundlife[numenvsounds]=.4;
- numenvsounds++;
- }
- if(objects.type[k]==treetrunktype){
- //if(objects.rotx[k]==0||objects.roty[k]==0){
- /*int howmany;
- XYZ tempvel;
- XYZ pos;
- if(environment==grassyenvironment)howmany=findLength(&joints[i].velocity)*4/10;
- if(environment==snowyenvironment)howmany=findLength(&joints[i].velocity)*1/10;
- if(environment!=desertenvironment)
- for(j=0;j<howmany;j++){
- tempvel.x=float(abs(Random()%100)-50)/20;
- tempvel.y=float(abs(Random()%100)-50)/20;
- tempvel.z=float(abs(Random()%100)-50)/20;
- pos=objects.position[k];
- pos.y+=objects.scale[k]*15;
- pos.x+=float(abs(Random()%100)-50)/100*objects.scale[k]*5;
- pos.y+=float(abs(Random()%100)-50)/100*objects.scale[k]*15;
- pos.z+=float(abs(Random()%100)-50)/100*objects.scale[k]*5;
- Sprite::MakeSprite(splintersprite, pos,tempvel*.5, 165/255+float(abs(Random()%100)-50)/400,0,0, .2+float(abs(Random()%100)-50)/1300, 1);
- Sprite::special[Sprite::numsprites-1]=1;
- }*/
- objects.rotx[k]+=joints[i].velocity.x*multiplier*.4;
- objects.roty[k]+=joints[i].velocity.z*multiplier*.4;
- objects.rotx[k+1]+=joints[i].velocity.x*multiplier*.4;
- objects.roty[k+1]+=joints[i].velocity.z*multiplier*.4;
- }
- if(!joints[i].locked)damage+=findLengthfast(&bounceness)/2500;
- ReflectVector(&joints[i].velocity,&terrainnormal);
- frictionness=abs(normaldotproduct(joints[i].velocity,terrainnormal));//findLength(&bounceness)/findLength(&joints[i].velocity);
- joints[i].velocity-=bounceness;
- if(1-friction*frictionness>0)joints[i].velocity*=1-friction*frictionness;
- else joints[i].velocity=0;
- if(findLengthfast(&bounceness)>2500){
- Normalise(&bounceness);
- bounceness=bounceness*50;
- }
- joints[i].velocity+=bounceness*elasticity;
-
-
- if(!joints[i].locked)
- if(findLengthfast(&joints[i].velocity)<1){
- joints[i].locked=1;
- //joints[i].velocity*=3;
- }
- if(findLengthfast(&bounceness)>500)Sprite::MakeSprite(cloudsprite, joints[i].position*(*scale)+*coords,joints[i].velocity*.06, 1,1,1, .5, .2);
- joints[i].position=(temp-*coords)/(*scale)+terrainnormal*.005;
- if(longdead>100)broken=1;
- }
- }
- }
- joints[i].realoldposition=joints[i].position*(*scale)+*coords;
- }
- }
- multiplier=tempmult;
-
-
- if(terrain.patchobjectnum[whichpatchx][whichpatchz])
- for(m=0;m<terrain.patchobjectnum[whichpatchx][whichpatchz];m++){
- k=terrain.patchobjects[whichpatchx][whichpatchz][m];
- if(objects.possible[k]){
- for(i=0;i<26;i++){
- //Make this less stupid
- start=joints[jointlabels[whichjointstartarray[i]]].position*(*scale)+*coords;
- end=joints[jointlabels[whichjointendarray[i]]].position*(*scale)+*coords;
- whichhit=objects.model[k].LineCheckSlidePossible(&start,&end,&temp,&objects.position[k],&objects.rotation[k]);
- if(whichhit!=-1){
- joints[jointlabels[whichjointendarray[i]]].position=(end-*coords)/(*scale);
- for(j=0; j<num_muscles; j++){
- if((muscles[j].parent1->label==whichjointstartarray[i]&&muscles[j].parent2->label==whichjointendarray[i])||(muscles[j].parent2->label==whichjointstartarray[i]&&muscles[j].parent1->label==whichjointendarray[i]))
- muscles[j].DoConstraint(spinny);
- }
- }
- }
- }
- }
-
- for(i=0; i<num_joints; i++){
- groundlevel=.15;
- if(joints[i].label==head)groundlevel=.8;
- if(joints[i].label==righthand||joints[i].label==rightwrist||joints[i].label==rightelbow)groundlevel=.2;
- if(joints[i].label==lefthand||joints[i].label==leftwrist||joints[i].label==leftelbow)groundlevel=.2;
- joints[i].position.y+=groundlevel;
- joints[i].mass=1;
- if(joints[i].label==lefthip||joints[i].label==leftknee||joints[i].label==leftankle||joints[i].label==righthip||joints[i].label==rightknee||joints[i].label==rightankle)joints[i].mass=2;
- if(joints[i].locked){
- joints[i].mass=4;
- }
- }
-
- return damage;
- }
- if(!free){
- for(i=0; i<num_muscles; i++){
- if(muscles[i].type==boneconnect)
- muscles[i].DoConstraint(0);
- }
- }
- return 0;
+ static float friction = 1.5;
+ static float elasticity = .3;
+ static XYZ bounceness;
+ static XYZ oldpos[100];
+ static int numrepeats = 3;
+ static float groundlevel = .15;
+ static float soundvolume;
+ static int i, j, k, l, m;
+ static XYZ temp, start, end;
+ static XYZ terrainnormal;
+ static float r = .05;
+ static float r2 = .08;
+ static int whichhit;
+ //static int whichjointstart,whichjointend;
+ static float distance;
+ static float frictionness;
+ static XYZ terrainlight;
+ static int whichpatchx;
+ static int whichpatchz;
+ static float damage;
+ static bool freely;
+ static float tempmult;
+ static bool breaking;
+ breaking = 0;
+
+ damage = 0;
+
+ if (free) {
+ freetime += multiplier;
+
+ whichpatchx = coords->x / (terrain.size / subdivision * terrain.scale);
+ whichpatchz = coords->z / (terrain.size / subdivision * terrain.scale);
+
+ terrainlight = *coords;
+ objects.SphereCheckPossible(&terrainlight, 1);
+ /*
+ for(i=0; i<num_joints; i++){
+ oldpos[i]=joints[i].position;
+ }*/
+
+ //Add velocity
+ for (i = 0; i < num_joints; i++) {
+ //if(!isnormal(joints[i].velocity.x)||!isnormal(joints[i].velocity.y)||!isnormal(joints[i].velocity.z))joints[i].velocity=0;
+ joints[i].position = joints[i].position + joints[i].velocity * multiplier;
+ groundlevel = .15;
+ if (joints[i].label == head)
+ groundlevel = .8;
+ if (joints[i].label == righthand || joints[i].label == rightwrist || joints[i].label == rightelbow)
+ groundlevel = .2;
+ if (joints[i].label == lefthand || joints[i].label == leftwrist || joints[i].label == leftelbow)
+ groundlevel = .2;
+ joints[i].position.y -= groundlevel;
+ //if(!joints[i].locked&&!broken)joints[i].velocity+=joints[i].velchange*multiplier*10*(500-longdead)/500;
+ joints[i].oldvelocity = joints[i].velocity;
+ }
+ tempmult = multiplier;
+ //multiplier/=numrepeats;
+ for (j = 0; j < numrepeats; j++) {
+ if (!joints[jointlabels[rightknee]].locked && !joints[jointlabels[righthip]].locked) {
+ temp = joints[jointlabels[rightknee]].position - (joints[jointlabels[righthip]].position + joints[jointlabels[rightankle]].position) / 2;
+ while (normaldotproduct(temp, lowforward) > -.1 && !sphere_line_intersection(&joints[jointlabels[righthip]].position, &joints[jointlabels[rightankle]].position, &joints[jointlabels[rightknee]].position, &r)) {
+ joints[jointlabels[rightknee]].position -= lowforward * .05;
+ if (spinny)
+ joints[jointlabels[rightknee]].velocity -= lowforward * .05 / multiplier / 4;
+ else
+ joints[jointlabels[rightknee]].velocity -= lowforward * .05;
+ joints[jointlabels[rightankle]].position += lowforward * .025;
+ if (spinny)
+ joints[jointlabels[rightankle]].velocity += lowforward * .025 / multiplier / 4;
+ else
+ joints[jointlabels[rightankle]].velocity += lowforward * .25;
+ joints[jointlabels[righthip]].position += lowforward * .025;
+ if (spinny)
+ joints[jointlabels[righthip]].velocity += lowforward * .025 / multiplier / 4;
+ else
+ joints[jointlabels[righthip]].velocity += lowforward * .025;
+ temp = joints[jointlabels[rightknee]].position - (joints[jointlabels[righthip]].position + joints[jointlabels[rightankle]].position) / 2;
+ }
+ }
+ if (!joints[jointlabels[leftknee]].locked && !joints[jointlabels[righthip]].locked) {
+ temp = joints[jointlabels[leftknee]].position - (joints[jointlabels[lefthip]].position + joints[jointlabels[leftankle]].position) / 2;
+ while (normaldotproduct(temp, lowforward) > -.1 && !sphere_line_intersection(&joints[jointlabels[lefthip]].position, &joints[jointlabels[leftankle]].position, &joints[jointlabels[leftknee]].position, &r)) {
+ joints[jointlabels[leftknee]].position -= lowforward * .05;
+ if (spinny)
+ joints[jointlabels[leftknee]].velocity -= lowforward * .05 / multiplier / 4;
+ else
+ joints[jointlabels[leftknee]].velocity -= lowforward * .05;
+ joints[jointlabels[leftankle]].position += lowforward * .025;
+ if (spinny)
+ joints[jointlabels[leftankle]].velocity += lowforward * .025 / multiplier / 4;
+ else
+ joints[jointlabels[leftankle]].velocity += lowforward * .25;
+ joints[jointlabels[lefthip]].position += lowforward * .025;
+ if (spinny)
+ joints[jointlabels[lefthip]].velocity += lowforward * .025 / multiplier / 4;
+ else
+ joints[jointlabels[lefthip]].velocity += lowforward * .025;
+ temp = joints[jointlabels[leftknee]].position - (joints[jointlabels[lefthip]].position + joints[jointlabels[leftankle]].position) / 2;
+ }
+ }
+
+ for (i = 0; i < num_joints; i++) {
+ //joints[i].delay-=multiplier/1.5;
+ if (joints[i].locked)
+ if (!spinny)
+ if (findLengthfast(&joints[i].velocity) > 320)
+ joints[i].locked = 0;
+ if (spinny)
+ if (findLengthfast(&joints[i].velocity) > 600)
+ joints[i].locked = 0;
+ if (joints[i].delay > 0) {
+ freely = 1;
+ for (j = 0; j < num_joints; j++) {
+ if (joints[j].locked)
+ freely = 0;
+ }
+ if (freely)
+ joints[i].delay -= multiplier * 3;
+ }
+ //if(joints[i].delay>0)
+ //if(findLengthfast(&joints[i].velocity)>700&&joints[i].label!=head)joints[i].delay-=multiplier;
+ }
+
+ if (num_muscles)
+ for (i = 0; i < num_muscles; i++) {
+ //Length constraints
+ //muscles[i].DoConstraint(broken);
+ muscles[i].DoConstraint(spinny);
+ }
+
+ for (i = 0; i < num_joints; i++) {
+ //joints[i].delay-=multiplier/1.5;
+ //Length constraints
+ //Ground constraint
+ groundlevel = 0;
+ if (joints[i].position.y * (*scale) + coords->y < terrain.getHeight(joints[i].position.x * (*scale) + coords->x, joints[i].position.z * (*scale) + coords->z) + groundlevel) {
+ freefall = 0;
+ friction = 1.5;
+ if (joints[i].label == groin && !joints[i].locked && joints[i].delay <= 0) {
+ joints[i].locked = 1;
+ joints[i].delay = 1;
+ if (tutoriallevel != 1 || id == 0) {
+ emit_sound_at(landsound1, joints[i].position * (*scale) + *coords, 128.);
+ }
+ breaking = 1;
+ }
+
+ if (joints[i].label == head && !joints[i].locked && joints[i].delay <= 0) {
+ joints[i].locked = 1;
+ joints[i].delay = 1;
+ if (tutoriallevel != 1 || id == 0) {
+ emit_sound_at(landsound2, joints[i].position * (*scale) + *coords, 128.);
+ }
+ }
+
+ terrainnormal = terrain.getNormal(joints[i].position.x * (*scale) + coords->x, joints[i].position.z * (*scale) + coords->z);
+ ReflectVector(&joints[i].velocity, &terrainnormal);
+ bounceness = terrainnormal * findLength(&joints[i].velocity) * (abs(normaldotproduct(joints[i].velocity, terrainnormal)));
+ if (!joints[i].locked)
+ damage += findLengthfast(&bounceness) / 4000;
+ if (findLengthfast(&joints[i].velocity) < findLengthfast(&bounceness))
+ bounceness = 0;
+ frictionness = abs(normaldotproduct(joints[i].velocity, terrainnormal)); //findLength(&bounceness)/findLength(&joints[i].velocity);
+ joints[i].velocity -= bounceness;
+ if (1 - friction * frictionness > 0)
+ joints[i].velocity *= 1 - friction * frictionness;
+ else
+ joints[i].velocity = 0;
+
+ if (tutoriallevel != 1 || id == 0)
+ if (findLengthfast(&bounceness) > 8000 && breaking) {
+ objects.model[k].MakeDecal(breakdecal, DoRotation(temp - objects.position[k], 0, -objects.yaw[k], 0), .4, .5, Random() % 360);
+ Sprite::MakeSprite(cloudsprite, joints[i].position * (*scale) + *coords, joints[i].velocity * .06, 1, 1, 1, 4, .2);
+ //Sprite::MakeSprite(cloudsprite, joints[i].position*(*scale)+*coords,joints[i].velocity*.06, 1,1,1, 1, .2);
+ breaking = 0;
+ camerashake += .6;
+
+ emit_sound_at(breaksound2, joints[i].position * (*scale) + *coords);
+
+ envsound[numenvsounds] = *coords;
+ envsoundvol[numenvsounds] = 64;
+ envsoundlife[numenvsounds] = .4;
+ numenvsounds++;
+ }
+
+ if (findLengthfast(&bounceness) > 2500) {
+ Normalise(&bounceness);
+ bounceness = bounceness * 50;
+ }
+
+ joints[i].velocity += bounceness * elasticity;
+
+ if (findLengthfast(&joints[i].velocity) > findLengthfast(&joints[i].oldvelocity)) {
+ bounceness = 0;
+ joints[i].velocity = joints[i].oldvelocity;
+ }
+
+
+ if (joints[i].locked == 0)
+ if (findLengthfast(&joints[i].velocity) < 1)
+ joints[i].locked = 1;
+
+ if (environment == snowyenvironment && findLengthfast(&bounceness) > 500 && terrain.getOpacity(joints[i].position.x * (*scale) + coords->x, joints[i].position.z * (*scale) + coords->z) < .2) {
+ terrainlight = terrain.getLighting(joints[i].position.x * (*scale) + coords->x, joints[i].position.z * (*scale) + coords->z);
+ Sprite::MakeSprite(cloudsprite, joints[i].position * (*scale) + *coords, joints[i].velocity * .06, terrainlight.x, terrainlight.y, terrainlight.z, .5, .7);
+ if (detail == 2)
+ terrain.MakeDecal(bodyprintdecal, joints[i].position * (*scale) + *coords, .4, .4, 0);
+ } else if (environment == desertenvironment && findLengthfast(&bounceness) > 500 && terrain.getOpacity(joints[i].position.x * (*scale) + coords->x, joints[i].position.z * (*scale) + coords->z) < .2) {
+ terrainlight = terrain.getLighting(joints[i].position.x * (*scale) + coords->x, joints[i].position.z * (*scale) + coords->z);
+ Sprite::MakeSprite(cloudsprite, joints[i].position * (*scale) + *coords, joints[i].velocity * .06, terrainlight.x * 190 / 255, terrainlight.y * 170 / 255, terrainlight.z * 108 / 255, .5, .7);
+ }
+
+ else if (environment == grassyenvironment && findLengthfast(&bounceness) > 500 && terrain.getOpacity(joints[i].position.x * (*scale) + coords->x, joints[i].position.z * (*scale) + coords->z) < .2) {
+ terrainlight = terrain.getLighting(joints[i].position.x * (*scale) + coords->x, joints[i].position.z * (*scale) + coords->z);
+ Sprite::MakeSprite(cloudsprite, joints[i].position * (*scale) + *coords, joints[i].velocity * .06, terrainlight.x * 90 / 255, terrainlight.y * 70 / 255, terrainlight.z * 8 / 255, .5, .5);
+ } else if (findLengthfast(&bounceness) > 500)
+ Sprite::MakeSprite(cloudsprite, joints[i].position * (*scale) + *coords, joints[i].velocity * .06, terrainlight.x, terrainlight.y, terrainlight.z, .5, .2);
+
+
+ joints[i].position.y = (terrain.getHeight(joints[i].position.x * (*scale) + coords->x, joints[i].position.z * (*scale) + coords->z) + groundlevel - coords->y) / (*scale);
+ if (longdead > 100)
+ broken = 1;
+ }
+ if (terrain.patchobjectnum[whichpatchx][whichpatchz])
+ for (m = 0; m < terrain.patchobjectnum[whichpatchx][whichpatchz]; m++) {
+ k = terrain.patchobjects[whichpatchx][whichpatchz][m];
+ if (k < objects.numobjects && k >= 0)
+ if (objects.possible[k]) {
+ friction = objects.friction[k];
+ start = joints[i].realoldposition;
+ end = joints[i].position * (*scale) + *coords;
+ whichhit = objects.model[k].LineCheckPossible(&start, &end, &temp, &objects.position[k], &objects.yaw[k]);
+ if (whichhit != -1) {
+ if (joints[i].label == groin && !joints[i].locked && joints[i].delay <= 0) {
+ joints[i].locked = 1;
+ joints[i].delay = 1;
+ if (tutoriallevel != 1 || id == 0) {
+ emit_sound_at(landsound1, joints[i].position * (*scale) + *coords, 128.);
+ }
+ breaking = 1;
+ }
+
+ if (joints[i].label == head && !joints[i].locked && joints[i].delay <= 0) {
+ joints[i].locked = 1;
+ joints[i].delay = 1;
+ if (tutoriallevel != 1 || id == 0) {
+ emit_sound_at(landsound2, joints[i].position * (*scale) + *coords, 128.);
+ }
+ }
+
+ terrainnormal = DoRotation(objects.model[k].facenormals[whichhit], 0, objects.yaw[k], 0) * -1;
+ if (terrainnormal.y > .8)
+ freefall = 0;
+ bounceness = terrainnormal * findLength(&joints[i].velocity) * (abs(normaldotproduct(joints[i].velocity, terrainnormal)));
+ if (findLengthfast(&joints[i].velocity) > findLengthfast(&joints[i].oldvelocity)) {
+ bounceness = 0;
+ joints[i].velocity = joints[i].oldvelocity;
+ }
+ if (tutoriallevel != 1 || id == 0)
+ if (findLengthfast(&bounceness) > 4000 && breaking) {
+ objects.model[k].MakeDecal(breakdecal, DoRotation(temp - objects.position[k], 0, -objects.yaw[k], 0), .4, .5, Random() % 360);
+ Sprite::MakeSprite(cloudsprite, joints[i].position * (*scale) + *coords, joints[i].velocity * .06, 1, 1, 1, 4, .2);
+ breaking = 0;
+ camerashake += .6;
+
+ emit_sound_at(breaksound2, joints[i].position * (*scale) + *coords);
+
+ envsound[numenvsounds] = *coords;
+ envsoundvol[numenvsounds] = 64;
+ envsoundlife[numenvsounds] = .4;
+ numenvsounds++;
+ }
+ if (objects.type[k] == treetrunktype) {
+ //if(objects.rotx[k]==0||objects.roty[k]==0){
+ /*int howmany;
+ XYZ tempvel;
+ XYZ pos;
+ if(environment==grassyenvironment)howmany=findLength(&joints[i].velocity)*4/10;
+ if(environment==snowyenvironment)howmany=findLength(&joints[i].velocity)*1/10;
+ if(environment!=desertenvironment)
+ for(j=0;j<howmany;j++){
+ tempvel.x=float(abs(Random()%100)-50)/20;
+ tempvel.y=float(abs(Random()%100)-50)/20;
+ tempvel.z=float(abs(Random()%100)-50)/20;
+ pos=objects.position[k];
+ pos.y+=objects.scale[k]*15;
+ pos.x+=float(abs(Random()%100)-50)/100*objects.scale[k]*5;
+ pos.y+=float(abs(Random()%100)-50)/100*objects.scale[k]*15;
+ pos.z+=float(abs(Random()%100)-50)/100*objects.scale[k]*5;
+ Sprite::MakeSprite(splintersprite, pos,tempvel*.5, 165/255+float(abs(Random()%100)-50)/400,0,0, .2+float(abs(Random()%100)-50)/1300, 1);
+ Sprite::special[Sprite::numsprites-1]=1;
+ }*/
+ objects.rotx[k] += joints[i].velocity.x * multiplier * .4;
+ objects.roty[k] += joints[i].velocity.z * multiplier * .4;
+ objects.rotx[k + 1] += joints[i].velocity.x * multiplier * .4;
+ objects.roty[k + 1] += joints[i].velocity.z * multiplier * .4;
+ }
+ if (!joints[i].locked)
+ damage += findLengthfast(&bounceness) / 2500;
+ ReflectVector(&joints[i].velocity, &terrainnormal);
+ frictionness = abs(normaldotproduct(joints[i].velocity, terrainnormal)); //findLength(&bounceness)/findLength(&joints[i].velocity);
+ joints[i].velocity -= bounceness;
+ if (1 - friction * frictionness > 0)
+ joints[i].velocity *= 1 - friction * frictionness;
+ else
+ joints[i].velocity = 0;
+ if (findLengthfast(&bounceness) > 2500) {
+ Normalise(&bounceness);
+ bounceness = bounceness * 50;
+ }
+ joints[i].velocity += bounceness * elasticity;
+
+
+ if (!joints[i].locked)
+ if (findLengthfast(&joints[i].velocity) < 1) {
+ joints[i].locked = 1;
+ //joints[i].velocity*=3;
+ }
+ if (findLengthfast(&bounceness) > 500)
+ Sprite::MakeSprite(cloudsprite, joints[i].position * (*scale) + *coords, joints[i].velocity * .06, 1, 1, 1, .5, .2);
+ joints[i].position = (temp - *coords) / (*scale) + terrainnormal * .005;
+ if (longdead > 100)
+ broken = 1;
+ }
+ }
+ }
+ joints[i].realoldposition = joints[i].position * (*scale) + *coords;
+ }
+ }
+ multiplier = tempmult;
+
+
+ if (terrain.patchobjectnum[whichpatchx][whichpatchz])
+ for (m = 0; m < terrain.patchobjectnum[whichpatchx][whichpatchz]; m++) {
+ k = terrain.patchobjects[whichpatchx][whichpatchz][m];
+ if (objects.possible[k]) {
+ for (i = 0; i < 26; i++) {
+ //Make this less stupid
+ start = joints[jointlabels[whichjointstartarray[i]]].position * (*scale) + *coords;
+ end = joints[jointlabels[whichjointendarray[i]]].position * (*scale) + *coords;
+ whichhit = objects.model[k].LineCheckSlidePossible(&start, &end, &temp, &objects.position[k], &objects.yaw[k]);
+ if (whichhit != -1) {
+ joints[jointlabels[whichjointendarray[i]]].position = (end - *coords) / (*scale);
+ for (j = 0; j < num_muscles; j++) {
+ if ((muscles[j].parent1->label == whichjointstartarray[i] && muscles[j].parent2->label == whichjointendarray[i]) || (muscles[j].parent2->label == whichjointstartarray[i] && muscles[j].parent1->label == whichjointendarray[i]))
+ muscles[j].DoConstraint(spinny);
+ }
+ }
+ }
+ }
+ }
+
+ for (i = 0; i < num_joints; i++) {
+ groundlevel = .15;
+ if (joints[i].label == head)
+ groundlevel = .8;
+ if (joints[i].label == righthand || joints[i].label == rightwrist || joints[i].label == rightelbow)
+ groundlevel = .2;
+ if (joints[i].label == lefthand || joints[i].label == leftwrist || joints[i].label == leftelbow)
+ groundlevel = .2;
+ joints[i].position.y += groundlevel;
+ joints[i].mass = 1;
+ if (joints[i].label == lefthip || joints[i].label == leftknee || joints[i].label == leftankle || joints[i].label == righthip || joints[i].label == rightknee || joints[i].label == rightankle)
+ joints[i].mass = 2;
+ if (joints[i].locked) {
+ joints[i].mass = 4;
+ }
+ }
+
+ return damage;
+ }
+ if (!free) {
+ for (i = 0; i < num_muscles; i++) {
+ if (muscles[i].type == boneconnect)
+ muscles[i].DoConstraint(0);
+ }
+ }
+ return 0;