+void Weapon::DoStuff(int i)
+{
+ //~ cout << position.x << "," << position.y << "," << position.z << "|" << tippoint.x << "," << tippoint.y << "," << tippoint.z << endl;
+ static int whichpatchx, whichpatchz, whichhit;
+ static XYZ start, end, colpoint, normalrot, footvel, footpoint;
+ static XYZ terrainnormal;
+ static XYZ vel;
+ static XYZ midp;
+ static XYZ newpoint1, newpoint2;
+ static float friction = 3.5;
+ static float elasticity = .4;
+ static XYZ bounceness;
+ static float frictionness;
+ static float closestdistance;
+ static float distance;
+ static XYZ point[3];
+ static XYZ closestpoint;
+ static XYZ closestswordpoint;
+ static XYZ extramove;
+ static float tempmult;
+
+ if (owner != -1) {
+ oldowner = owner;
+ }
+ if (damage >= 2 && type == staff && owner != -1) { // the staff breaks
+ emit_sound_at(staffbreaksound, tippoint);
+ XYZ tempvel;
+ for (int j = 0; j < 40; 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;
+ Sprite::MakeSprite(splintersprite, position + (tippoint - position) * ((float)j - 8) / 32, tempvel * .5, 115 / 255, 73 / 255, 12 / 255, .1, 1);
+ }
+ if (owner != -1) {
+ Person::players[owner]->weaponactive = -1;
+ Person::players[owner]->num_weapons--;
+ if (Person::players[owner]->num_weapons) {
+ Person::players[owner]->weaponids[0] = Person::players[owner]->weaponids[Person::players[owner]->num_weapons];
+ if (Person::players[owner]->weaponstuck == Person::players[owner]->num_weapons)
+ Person::players[owner]->weaponstuck = 0;
+ }
+ }
+ owner = -1;
+ hitsomething = 0;
+ missed = 1;
+ freetime = 0;
+ firstfree = 1;
+ position = 0;
+ physics = 0;
+ }
+ oldposition = position;
+ oldtippoint = tippoint;
+ if (owner == -1 && (velocity.x || velocity.y || velocity.z) && !physics) { // if the weapon is flying
+ position += velocity * multiplier;
+ tippoint += velocity * multiplier;
+ whichpatchx = position.x / (terrain.size / subdivision * terrain.scale);
+ whichpatchz = position.z / (terrain.size / subdivision * terrain.scale);
+ if (whichpatchx > 0 && whichpatchz > 0 && whichpatchx < subdivision && whichpatchz < subdivision) {
+ if (terrain.patchobjectnum[whichpatchx][whichpatchz]) { // if there are objects where the weapon is
+ for (int j = 0; j < terrain.patchobjectnum[whichpatchx][whichpatchz]; j++) { // check for collision
+ int k = terrain.patchobjects[whichpatchx][whichpatchz][j];
+ start = oldtippoint;
+ end = tippoint;
+ whichhit = objects.model[k].LineCheck(&start, &end, &colpoint, &objects.position[k], &objects.yaw[k]);
+ if (whichhit != -1) {
+ if (objects.type[k] == treetrunktype) {
+ objects.model[k].MakeDecal(breakdecal, DoRotation(colpoint - objects.position[k], 0, -objects.yaw[k], 0), .1, 1, Random() % 360);
+ normalrot = DoRotation(objects.model[k].facenormals[whichhit], 0, objects.yaw[k], 0);
+ velocity = 0;
+ if (type == knife)
+ position = colpoint - normalrot * .1;
+ else if (type == sword)
+ position = colpoint - normalrot * .2;
+ else if (type == staff)
+ position = colpoint - normalrot * .2;
+ XYZ temppoint1, temppoint2, tempforward;
+ float distance;
+
+ temppoint1 = 0;
+ temppoint2 = normalrot;
+ distance = findDistance(&temppoint1, &temppoint2);
+ rotation2 = asin((temppoint1.y - temppoint2.y) / distance);
+ rotation2 *= 360 / 6.28;
+ temppoint1.y = 0;
+ temppoint2.y = 0;
+ rotation1 = acos((temppoint1.z - temppoint2.z) / findDistance(&temppoint1, &temppoint2));
+ rotation1 *= 360 / 6.28;
+ if (temppoint1.x > temppoint2.x)
+ rotation1 = 360 - rotation1;
+
+ rotation3 = 0;
+ smallrotation = 90;
+ smallrotation2 = 0;
+ bigtilt = 0;
+ bigtilt2 = 0;
+ bigrotation = 0;
+
+ emit_sound_at(knifesheathesound, position, 128.);
+
+ bloody = 0;
+
+ Sprite::MakeSprite(cloudimpactsprite, position, velocity, 1, 1, 1, .8, .3);
+ } else {
+ physics = 1;
+ firstfree = 1;
+ position -= velocity * multiplier;
+ tippoint -= velocity * multiplier;
+ tipvelocity = velocity;
+ }
+ }
+ }
+ }
+ }
+
+ if (velocity.x || velocity.y || velocity.z) {
+ for (unsigned j = 0; j < Person::players.size(); j++) {
+ footvel = 0;
+ footpoint = DoRotation((Person::players[j]->jointPos(abdomen) + Person::players[j]->jointPos(neck)) / 2, 0, Person::players[j]->yaw, 0) * Person::players[j]->scale + Person::players[j]->coords;
+ if (owner == -1 && distsqflat(&position, &Person::players[j]->coords) < 1.5 &&
+ distsq(&position, &Person::players[j]->coords) < 4 && Person::players[j]->weaponstuck == -1 &&
+ !Person::players[j]->skeleton.free && (int(j) != oldowner)) {
+ if ((Person::players[j]->aitype != attacktypecutoff || abs(Random() % 6) == 0 || (Person::players[j]->animTarget != backhandspringanim && Person::players[j]->animTarget != rollanim && Person::players[j]->animTarget != flipanim && Random() % 2 == 0)) && !missed) {
+ if ( (Person::players[j]->creature == wolftype && Random() % 3 != 0 && Person::players[j]->weaponactive == -1 && (Person::players[j]->isIdle() || Person::players[j]->isRun() || Person::players[j]->animTarget == walkanim)) ||
+ (Person::players[j]->creature == rabbittype && Random() % 2 == 0 && Person::players[j]->aitype == attacktypecutoff && Person::players[j]->weaponactive == -1)) {
+ emit_sound_at(knifedrawsound, Person::players[j]->coords, 128.);
+
+ Person::players[j]->weaponactive = 0;
+ Person::players[j]->animTarget = removeknifeanim;
+ Person::players[j]->frameTarget = 1;
+ Person::players[j]->target = 1;
+ owner = Person::players[j]->id;
+ if (Person::players[j]->num_weapons > 0) {
+ Person::players[j]->weaponids[Person::players[j]->num_weapons] = Person::players[j]->weaponids[0];
+ }
+ Person::players[j]->num_weapons++;
+ Person::players[j]->weaponids[0] = i;
+
+ Person::players[j]->aitype = attacktypecutoff;
+ } else {
+ if (j != 0)
+ numthrowkill++;
+ Person::players[j]->num_weapons++;
+ Person::players[j]->weaponstuck = Person::players[j]->num_weapons - 1;
+ if (normaldotproduct(Person::players[j]->facing, velocity) > 0)
+ Person::players[j]->weaponstuckwhere = 1;
+ else
+ Person::players[j]->weaponstuckwhere = 0;
+
+ Person::players[j]->weaponids[Person::players[j]->num_weapons - 1] = i;
+
+ Person::players[j]->RagDoll(0);
+ Person::players[j]->jointVel(abdomen) += velocity * 2;
+ Person::players[j]->jointVel(neck) += velocity * 2;
+ Person::players[j]->jointVel(rightshoulder) += velocity * 2;
+ Person::players[j]->jointVel(leftshoulder) += velocity * 2;
+ if (bloodtoggle && tutoriallevel != 1)
+ Sprite::MakeSprite(cloudimpactsprite, footpoint, footvel, 1, 0, 0, .8, .3);
+ if (tutoriallevel == 1)
+ Sprite::MakeSprite(cloudimpactsprite, footpoint, footvel, 1, 1, 1, .8, .3);
+ footvel = tippoint - position;
+ Normalise(&footvel);
+ if (bloodtoggle && tutoriallevel != 1)
+ Sprite::MakeSprite(bloodflamesprite, footpoint, footvel * -1, 1, 0, 0, .6, 1);
+
+ if (tutoriallevel != 1) {
+ if (Person::players[j]->weaponstuckwhere == 0)
+ Person::players[j]->DoBloodBig(2, 205);
+ if (Person::players[j]->weaponstuckwhere == 1)
+ Person::players[j]->DoBloodBig(2, 200);
+ Person::players[j]->damage += 200 / Person::players[j]->armorhigh;
+ Person::players[j]->deathbleeding = 1;
+ Person::players[j]->bloodloss += (200 + abs((float)(Random() % 40)) - 20) / Person::players[j]->armorhigh;
+ owner = j;
+ bloody = 2;
+ blooddrip = 5;
+ }
+
+ emit_sound_at(fleshstabsound, position, 128.);
+
+ if (animation[Person::players[0]->animTarget].height == highheight)
+ award_bonus(0, ninja);
+ else
+ award_bonus(0, Bullseyebonus);
+ }
+ } else {
+ missed = 1;
+ }
+ }
+ }
+ }
+ if (position.y < terrain.getHeight(position.x, position.z)) {
+ if (terrain.getOpacity(position.x, position.z) < .2) {
+ velocity = 0;
+ if (terrain.lineTerrain(oldposition, position, &colpoint) != -1) {
+ position = colpoint * terrain.scale;
+ } else {
+ position.y = terrain.getHeight(position.x, position.z);
+ }
+
+ terrain.MakeDecal(shadowdecalpermanent, position, .06, .5, 0);
+ normalrot = terrain.getNormal(position.x, position.z) * -1;
+ velocity = 0;
+ glMatrixMode(GL_MODELVIEW);
+ glPushMatrix();
+ GLfloat M[16];
+ glLoadIdentity();
+ glRotatef(bigrotation, 0, 1, 0);
+ glRotatef(bigtilt2, 1, 0, 0);
+ glRotatef(bigtilt, 0, 0, 1);
+ glRotatef(-rotation1 + 90, 0, 1, 0);
+ glRotatef(-rotation2 + 90, 0, 0, 1);
+ glRotatef(-rotation3, 0, 1, 0);
+ glRotatef(smallrotation, 1, 0, 0);
+ glRotatef(smallrotation2, 0, 1, 0);
+ glTranslatef(0, 0, 1);
+ glGetFloatv(GL_MODELVIEW_MATRIX, M);
+ tippoint.x = M[12];
+ tippoint.y = M[13];
+ tippoint.z = M[14];
+ glPopMatrix();
+ position -= tippoint * .15;
+ XYZ temppoint1, temppoint2, tempforward;
+
+ rotation3 = 0;
+ smallrotation = 90;
+ smallrotation2 = 0;
+ bigtilt = 0;
+ bigtilt2 = 0;
+ bigrotation = 0;
+
+ emit_sound_at(knifesheathesound, position, 128.);
+
+ XYZ terrainlight;
+ terrainlight = terrain.getLighting(position.x, position.z);
+ if (environment == snowyenvironment) {
+ if (distsq(&position, &viewer) < viewdistance * viewdistance / 4)
+ Sprite::MakeSprite(cloudsprite, position, velocity, terrainlight.x, terrainlight.y, terrainlight.z, .5, .7);
+ } else if (environment == grassyenvironment) {
+ if (distsq(&position, &viewer) < viewdistance * viewdistance / 4)
+ Sprite::MakeSprite(cloudsprite, position, velocity, terrainlight.x * 90 / 255, terrainlight.y * 70 / 255, terrainlight.z * 8 / 255, .5, .5);
+ } else if (environment == desertenvironment) {
+ if (distsq(&position, &viewer) < viewdistance * viewdistance / 4)
+ Sprite::MakeSprite(cloudsprite, position, velocity, terrainlight.x * 190 / 255, terrainlight.y * 170 / 255, terrainlight.z * 108 / 255, .5, .7);
+ }
+
+ bloody = 0;
+ } else {
+ physics = 1;
+ firstfree = 1;
+ position -= velocity * multiplier;
+ tippoint -= velocity * multiplier;
+ tipvelocity = velocity;
+ }
+ }
+ if (velocity.x != 0 || velocity.z != 0 || velocity.y != 0) {
+ velocity.y += gravity * multiplier;
+
+ XYZ temppoint1, temppoint2, tempforward;
+ float distance;
+
+ temppoint1 = 0;
+ temppoint2 = velocity;
+ distance = findDistance(&temppoint1, &temppoint2);
+ rotation2 = asin((temppoint1.y - temppoint2.y) / distance);
+ rotation2 *= 360 / 6.28;
+ temppoint1.y = 0;
+ temppoint2.y = 0;
+ rotation1 = acos((temppoint1.z - temppoint2.z) / findDistance(&temppoint1, &temppoint2));
+ rotation1 *= 360 / 6.28;
+ rotation3 = 0;
+ smallrotation = 90;
+ smallrotation2 = 0;
+ bigtilt = 0;
+ bigtilt2 = 0;
+ bigrotation = 0;
+ if (temppoint1.x > temppoint2.x)
+ rotation1 = 360 - rotation1;
+ }
+
+ }
+
+ //Sword physics
+ XYZ mid;
+ XYZ oldmid;
+ XYZ oldmid2;
+
+ tempmult = multiplier;
+ multiplier /= 10;
+ for (int l = 0; l < 10; l++) {
+ if (owner == -1 && (velocity.x || velocity.y || velocity.z) && physics) {
+ //move
+ position += velocity * multiplier;
+ tippoint += tipvelocity * multiplier;
+
+ //Length constrain
+ midp = (position * mass + tippoint * tipmass) / (mass + tipmass);
+ vel = tippoint - midp;
+ Normalise(&vel);
+ newpoint1 = midp - vel * length * (tipmass / (mass + tipmass));
+ newpoint2 = midp + vel * length * (mass / (mass + tipmass));
+ if (!freeze) {
+ if (freetime > .04) {
+ velocity = velocity + (newpoint1 - position) / multiplier;
+ tipvelocity = tipvelocity + (newpoint2 - tippoint) / multiplier;
+ }
+ }
+ position = newpoint1;
+ tippoint = newpoint2;
+
+
+ //Object collisions
+ whichpatchx = (position.x) / (terrain.size / subdivision * terrain.scale);
+ whichpatchz = (position.z) / (terrain.size / subdivision * terrain.scale);
+ if (whichpatchx > 0 && whichpatchz > 0 && whichpatchx < subdivision && whichpatchz < subdivision)
+ if (terrain.patchobjectnum[whichpatchx][whichpatchz]) {
+ for (int j = 0; j < terrain.patchobjectnum[whichpatchx][whichpatchz]; j++) {
+ int k = terrain.patchobjects[whichpatchx][whichpatchz][j];
+
+ if (firstfree) {
+ if (type == staff) {
+ start = tippoint - (position - tippoint) / 5;
+ end = position + (position - tippoint) / 30;
+ whichhit = objects.model[k].LineCheck(&start, &end, &colpoint, &objects.position[k], &objects.yaw[k]);
+ if (whichhit != -1) {
+ XYZ diff;
+ diff = (colpoint - position);
+ Normalise(&diff);
+ hitsomething = 1;
+
+ tippoint += (colpoint - position) + diff * .05;
+ position = colpoint + diff * .05;
+ oldtippoint = tippoint;
+ oldposition = tippoint;
+ }
+ } else {
+ start = position - (tippoint - position) / 5;
+ end = tippoint + (tippoint - position) / 30;
+ whichhit = objects.model[k].LineCheck(&start, &end, &colpoint, &objects.position[k], &objects.yaw[k]);
+ if (whichhit != -1) {
+ XYZ diff;
+ diff = (colpoint - tippoint);
+ Normalise(&diff);
+ hitsomething = 1;
+
+ position += (colpoint - tippoint) + diff * .05;
+ tippoint = colpoint + diff * .05;
+ oldposition = position;
+ oldtippoint = tippoint;
+ }
+ }
+ }
+
+ start = oldposition;
+ end = position;
+ whichhit = objects.model[k].LineCheck(&start, &end, &colpoint, &objects.position[k], &objects.yaw[k]);
+ if (whichhit != -1) {
+ hitsomething = 1;
+ position = colpoint;
+ terrainnormal = DoRotation(objects.model[k].facenormals[whichhit], 0, objects.yaw[k], 0) * -1;
+ ReflectVector(&velocity, &terrainnormal);
+ position += terrainnormal * .002;
+
+ bounceness = terrainnormal * findLength(&velocity) * (abs(normaldotproduct(velocity, terrainnormal)));
+ if (findLengthfast(&velocity) < findLengthfast(&bounceness))
+ bounceness = 0;
+ frictionness = abs(normaldotproduct(velocity, terrainnormal));
+ velocity -= bounceness;
+ if (1 - friction * frictionness > 0)
+ velocity *= 1 - friction * frictionness;
+ else
+ velocity = 0;
+ velocity += bounceness * elasticity;
+
+ if (findLengthfast(&bounceness) > 1) {
+ int whichsound;
+ if (type == staff)
+ whichsound = footstepsound3 + abs(Random() % 2);
+ else
+ whichsound = clank1sound + abs(Random() % 4);
+ emit_sound_at(whichsound, position, 128 * findLengthfast(&bounceness));
+ }
+ }
+ start = oldtippoint;
+ end = tippoint;
+ whichhit = objects.model[k].LineCheck(&start, &end, &colpoint, &objects.position[k], &objects.yaw[k]);
+ if (whichhit != -1) {
+ hitsomething = 1;
+ tippoint = colpoint;
+ terrainnormal = DoRotation(objects.model[k].facenormals[whichhit], 0, objects.yaw[k], 0) * -1;
+ ReflectVector(&tipvelocity, &terrainnormal);
+ tippoint += terrainnormal * .002;
+
+ bounceness = terrainnormal * findLength(&tipvelocity) * (abs(normaldotproduct(tipvelocity, terrainnormal)));
+ if (findLengthfast(&tipvelocity) < findLengthfast(&bounceness))
+ bounceness = 0;
+ frictionness = abs(normaldotproduct(tipvelocity, terrainnormal));
+ tipvelocity -= bounceness;
+ if (1 - friction * frictionness > 0)
+ tipvelocity *= 1 - friction * frictionness;
+ else
+ tipvelocity = 0;
+ tipvelocity += bounceness * elasticity;
+
+ if (findLengthfast(&bounceness) > 1) {
+ int whichsound;
+ if (type == staff)
+ whichsound = footstepsound3 + abs(Random() % 2);
+ else
+ whichsound = clank1sound + abs(Random() % 4);
+ emit_sound_at(whichsound, position, 128 * findLengthfast(&bounceness));
+ }
+ }
+
+ if ((objects.type[k] != boxtype && objects.type[k] != platformtype && objects.type[k] != walltype && objects.type[k] != weirdtype) || objects.pitch[k] != 0)
+ for (int m = 0; m < 2; m++) {
+ mid = (position * (21 + (float)m * 10) + tippoint * (19 - (float)m * 10)) / 40;
+ oldmid2 = mid;
+ oldmid = (oldposition * (21 + (float)m * 10) + oldtippoint * (19 - (float)m * 10)) / 40;
+
+ start = oldmid;
+ end = mid;
+ whichhit = objects.model[k].LineCheck(&start, &end, &colpoint, &objects.position[k], &objects.yaw[k]);
+ if (whichhit != -1) {
+ hitsomething = 1;
+ mid = colpoint;
+ terrainnormal = DoRotation(objects.model[k].facenormals[whichhit], 0, objects.yaw[k], 0) * -1;
+ ReflectVector(&velocity, &terrainnormal);
+
+ bounceness = terrainnormal * findLength(&velocity) * (abs(normaldotproduct(velocity, terrainnormal)));
+ if (findLengthfast(&velocity) < findLengthfast(&bounceness))
+ bounceness = 0;
+ frictionness = abs(normaldotproduct(velocity, terrainnormal));
+ velocity -= bounceness;
+ if (1 - friction * frictionness > 0)
+ velocity *= 1 - friction * frictionness;
+ else
+ velocity = 0;
+ velocity += bounceness * elasticity;
+
+ if (findLengthfast(&bounceness) > 1) {
+ int whichsound;
+ if (type == staff)
+ whichsound = footstepsound3 + abs(Random() % 2);
+ else
+ whichsound = clank1sound + abs(Random() % 4);
+ emit_sound_at(whichsound, mid, 128 * findLengthfast(&bounceness));
+ }
+ position += (mid - oldmid2) * (20 / (1 + (float)m * 10));
+ }
+
+ mid = (position * (19 - (float)m * 10) + tippoint * (21 + (float)m * 10)) / 40;
+ oldmid2 = mid;
+ oldmid = (oldposition * (19 - (float)m * 10) + oldtippoint * (21 + (float)m * 10)) / 40;
+
+ start = oldmid;
+ end = mid;
+ whichhit = objects.model[k].LineCheck(&start, &end, &colpoint, &objects.position[k], &objects.yaw[k]);
+ if (whichhit != -1) {
+ hitsomething = 1;
+ mid = colpoint;
+ terrainnormal = DoRotation(objects.model[k].facenormals[whichhit], 0, objects.yaw[k], 0) * -1;
+ ReflectVector(&tipvelocity, &terrainnormal);
+
+ bounceness = terrainnormal * findLength(&tipvelocity) * (abs(normaldotproduct(tipvelocity, terrainnormal)));
+ if (findLengthfast(&tipvelocity) < findLengthfast(&bounceness))
+ bounceness = 0;
+ frictionness = abs(normaldotproduct(tipvelocity, terrainnormal));
+ tipvelocity -= bounceness;
+ if (1 - friction * frictionness > 0)
+ tipvelocity *= 1 - friction * frictionness;
+ else
+ tipvelocity = 0;
+ tipvelocity += bounceness * elasticity;
+
+ if (findLengthfast(&bounceness) > 1) {
+ int whichsound;
+ if (type == staff)
+ whichsound = footstepsound3 + abs(Random() % 2);
+ else
+ whichsound = clank1sound + abs(Random() % 4);
+ emit_sound_at(whichsound, mid, 128 * findLengthfast(&bounceness));
+ }
+ tippoint += (mid - oldmid2) * (20 / (1 + (float)m * 10));
+ }
+ }
+ else {
+ start = position;
+ end = tippoint;
+ whichhit = objects.model[k].LineCheck(&start, &end, &colpoint, &objects.position[k], &objects.yaw[k]);
+ if (whichhit != -1) {
+ hitsomething = 1;
+ closestdistance = -1;
+ closestswordpoint = colpoint; //(position+tippoint)/2;
+ point[0] = DoRotation(objects.model[k].vertex[objects.model[k].Triangles[whichhit].vertex[0]], 0, objects.yaw[k], 0) + objects.position[k];
+ point[1] = DoRotation(objects.model[k].vertex[objects.model[k].Triangles[whichhit].vertex[1]], 0, objects.yaw[k], 0) + objects.position[k];
+ point[2] = DoRotation(objects.model[k].vertex[objects.model[k].Triangles[whichhit].vertex[2]], 0, objects.yaw[k], 0) + objects.position[k];
+ if (DistancePointLine(&closestswordpoint, &point[0], &point[1], &distance, &colpoint )) {
+ if (distance < closestdistance || closestdistance == -1) {
+ closestpoint = colpoint;
+ closestdistance = distance;
+ }
+ }
+ if (DistancePointLine(&closestswordpoint, &point[1], &point[2], &distance, &colpoint )) {
+ if (distance < closestdistance || closestdistance == -1) {
+ closestpoint = colpoint;
+ closestdistance = distance;
+ }
+ }
+ if (DistancePointLine(&closestswordpoint, &point[2], &point[0], &distance, &colpoint )) {
+ if (distance < closestdistance || closestdistance == -1) {
+ closestpoint = colpoint;
+ closestdistance = distance;
+ }
+ }
+ if (closestdistance != -1 && isnormal(closestdistance)) {
+ if (DistancePointLine(&closestpoint, &position, &tippoint, &distance, &colpoint )) {
+ closestswordpoint = colpoint;
+ velocity += (closestpoint - closestswordpoint);
+ tipvelocity += (closestpoint - closestswordpoint);
+ position += (closestpoint - closestswordpoint);
+ tippoint += (closestpoint - closestswordpoint);
+ }
+ }
+ }
+ }
+ }
+ }
+ //Terrain collisions
+ whichhit = terrain.lineTerrain(oldposition, position, &colpoint);
+ if (whichhit != -1 || position.y < terrain.getHeight(position.x, position.z)) {
+ hitsomething = 1;
+ if (whichhit != -1)
+ position = colpoint * terrain.scale;
+ else
+ position.y = terrain.getHeight(position.x, position.z);
+
+ terrainnormal = terrain.getNormal(position.x, position.z);
+ ReflectVector(&velocity, &terrainnormal);
+ position += terrainnormal * .002;
+ bounceness = terrainnormal * findLength(&velocity) * (abs(normaldotproduct(velocity, terrainnormal)));
+ if (findLengthfast(&velocity) < findLengthfast(&bounceness))
+ bounceness = 0;
+ frictionness = abs(normaldotproduct(velocity, terrainnormal));
+ velocity -= bounceness;
+ if (1 - friction * frictionness > 0)
+ velocity *= 1 - friction * frictionness;
+ else
+ velocity = 0;
+ if (terrain.getOpacity(position.x, position.z) < .2)
+ velocity += bounceness * elasticity * .3;
+ else
+ velocity += bounceness * elasticity;
+
+ if (findLengthfast(&bounceness) > 1) {
+ int whichsound;
+ if (terrain.getOpacity(position.x, position.z) > .2) {
+ if (type == staff)
+ whichsound = footstepsound3 + abs(Random() % 2);
+ else
+ whichsound = clank1sound + abs(Random() % 4);
+ } else {
+ whichsound = footstepsound + abs(Random() % 2);
+ }
+ emit_sound_at(whichsound, position,
+ findLengthfast(&bounceness)
+ * (terrain.getOpacity(position.x, position.z) > .2 ? 128. : 32.));
+
+ if (terrain.getOpacity(position.x, position.z) < .2) {
+ XYZ terrainlight;
+ terrainlight = terrain.getLighting(position.x, position.z);
+ if (environment == snowyenvironment) {
+ if (distsq(&position, &viewer) < viewdistance * viewdistance / 4)
+ Sprite::MakeSprite(cloudsprite, position, velocity, terrainlight.x, terrainlight.y, terrainlight.z, .5, .7);
+ } else if (environment == grassyenvironment) {
+ if (distsq(&position, &viewer) < viewdistance * viewdistance / 4)
+ Sprite::MakeSprite(cloudsprite, position, velocity, terrainlight.x * 90 / 255, terrainlight.y * 70 / 255, terrainlight.z * 8 / 255, .5, .5);
+ } else if (environment == desertenvironment) {
+ if (distsq(&position, &viewer) < viewdistance * viewdistance / 4)
+ Sprite::MakeSprite(cloudsprite, position, velocity, terrainlight.x * 190 / 255, terrainlight.y * 170 / 255, terrainlight.z * 108 / 255, .5, .7);
+ }
+ }
+ }
+ }
+ whichhit = terrain.lineTerrain(oldtippoint, tippoint, &colpoint);
+ if (whichhit != -1 || tippoint.y < terrain.getHeight(tippoint.x, tippoint.z)) {
+ if (whichhit != -1)
+ tippoint = colpoint * terrain.scale;
+ else
+ tippoint.y = terrain.getHeight(tippoint.x, tippoint.z);
+
+ terrainnormal = terrain.getNormal(tippoint.x, tippoint.z);
+ ReflectVector(&tipvelocity, &terrainnormal);
+ tippoint += terrainnormal * .002;
+ bounceness = terrainnormal * findLength(&tipvelocity) * (abs(normaldotproduct(tipvelocity, terrainnormal)));
+ if (findLengthfast(&tipvelocity) < findLengthfast(&bounceness))
+ bounceness = 0;
+ frictionness = abs(normaldotproduct(tipvelocity, terrainnormal));
+ tipvelocity -= bounceness;
+ if (1 - friction * frictionness > 0)
+ tipvelocity *= 1 - friction * frictionness;
+ else
+ tipvelocity = 0;
+ if (terrain.getOpacity(tippoint.x, tippoint.z) < .2)
+ tipvelocity += bounceness * elasticity * .3;
+ else
+ tipvelocity += bounceness * elasticity;
+
+ if (findLengthfast(&bounceness) > 1) {
+ int whichsound;
+ if (terrain.getOpacity(tippoint.x, tippoint.z) > .2) {
+ if (type == staff)
+ whichsound = footstepsound3 + abs(Random() % 2);
+ else
+ whichsound = clank1sound + abs(Random() % 4);
+ } else {
+ whichsound = footstepsound + abs(Random() % 2);
+ }
+ emit_sound_at(whichsound, tippoint,
+ findLengthfast(&bounceness)
+ * (terrain.getOpacity(tippoint.x, tippoint.z) > .2 ? 128. : 32.));
+
+ if (terrain.getOpacity(tippoint.x, tippoint.z) < .2) {
+ XYZ terrainlight;
+ terrainlight = terrain.getLighting(tippoint.x, tippoint.z);
+ if (environment == snowyenvironment) {
+ if (distsq(&tippoint, &viewer) < viewdistance * viewdistance / 4)
+ Sprite::MakeSprite(cloudsprite, tippoint, tipvelocity, terrainlight.x, terrainlight.y, terrainlight.z, .5, .7);
+ } else if (environment == grassyenvironment) {
+ if (distsq(&tippoint, &viewer) < viewdistance * viewdistance / 4)
+ Sprite::MakeSprite(cloudsprite, tippoint, tipvelocity, terrainlight.x * 90 / 255, terrainlight.y * 70 / 255, terrainlight.z * 8 / 255, .5, .5);
+ } else if (environment == desertenvironment) {
+ if (distsq(&tippoint, &viewer) < viewdistance * viewdistance / 4)
+ Sprite::MakeSprite(cloudsprite, tippoint, tipvelocity, terrainlight.x * 190 / 255, terrainlight.y * 170 / 255, terrainlight.z * 108 / 255, .5, .7);
+ }
+ }
+ }
+ }
+
+ //Edges
+ mid = position + tippoint;
+ mid /= 2;
+ mid += (position - mid) / 20;
+ oldmid = mid;
+ if (mid.y < terrain.getHeight(mid.x, mid.z)) {
+ hitsomething = 1;
+ mid.y = terrain.getHeight(mid.x, mid.z);
+
+ terrainnormal = terrain.getNormal(mid.x, mid.z);
+ ReflectVector(&velocity, &terrainnormal);
+ //mid+=terrainnormal*.002;
+ bounceness = terrainnormal * findLength(&velocity) * (abs(normaldotproduct(velocity, terrainnormal)));
+ if (findLengthfast(&velocity) < findLengthfast(&bounceness))
+ bounceness = 0;
+ frictionness = abs(normaldotproduct(velocity, terrainnormal));
+ velocity -= bounceness;
+ if (1 - friction * frictionness > 0)
+ velocity *= 1 - friction * frictionness;
+ else
+ velocity = 0;
+ if (terrain.getOpacity(mid.x, mid.z) < .2)
+ velocity += bounceness * elasticity * .3;
+ else
+ velocity += bounceness * elasticity;
+
+ if (findLengthfast(&bounceness) > 1) {
+ int whichsound;
+ if (terrain.getOpacity(mid.x, mid.z) > .2) {
+ if (type == staff)
+ whichsound = footstepsound3 + abs(Random() % 2);
+ if (type != staff)
+ whichsound = clank1sound + abs(Random() % 4);
+ } else {
+ whichsound = footstepsound + abs(Random() % 2);
+ }
+ emit_sound_at(whichsound, mid,
+ findLengthfast(&bounceness)
+ * (terrain.getOpacity(position.x, position.z) > .2
+ ? 128.
+ : 32.));
+ }
+ position += (mid - oldmid) * 20;
+ }
+
+ mid = position + tippoint;
+ mid /= 2;
+ mid += (tippoint - mid) / 20;
+ oldmid = mid;
+ if (mid.y < terrain.getHeight(mid.x, mid.z)) {
+ hitsomething = 1;
+ mid.y = terrain.getHeight(mid.x, mid.z);
+
+ terrainnormal = terrain.getNormal(mid.x, mid.z);
+ ReflectVector(&tipvelocity, &terrainnormal);
+ //mid+=terrainnormal*.002;
+ bounceness = terrainnormal * findLength(&tipvelocity) * (abs(normaldotproduct(tipvelocity, terrainnormal)));
+ if (findLengthfast(&tipvelocity) < findLengthfast(&bounceness))
+ bounceness = 0;
+ frictionness = abs(normaldotproduct(tipvelocity, terrainnormal));
+ tipvelocity -= bounceness;
+ if (1 - friction * frictionness > 0)
+ tipvelocity *= 1 - friction * frictionness;
+ else
+ tipvelocity = 0;
+ if (terrain.getOpacity(mid.x, mid.z) < .2)
+ tipvelocity += bounceness * elasticity * .3;
+ else
+ tipvelocity += bounceness * elasticity;
+
+ if (findLengthfast(&bounceness) > 1) {
+ int whichsound;
+ if (terrain.getOpacity(mid.x, mid.z) > .2) {
+ if (type == staff)
+ whichsound = footstepsound3 + abs(Random() % 2);
+ if (type != staff)
+ whichsound = clank1sound + abs(Random() % 4);
+ } else {
+ whichsound = footstepsound + abs(Random() % 2);
+ }
+ emit_sound_at(whichsound, mid,
+ findLengthfast(&bounceness)
+ * (terrain.getOpacity(position.x, position.z) > .2
+ ? 128.
+ : 32.));
+ }
+ tippoint += (mid - oldmid) * 20;
+ }
+ //Gravity
+ velocity.y += gravity * multiplier;
+ tipvelocity.y += gravity * multiplier;
+
+ //Rotation
+ XYZ temppoint1, temppoint2, tempforward;
+ float distance;
+
+ temppoint1 = position;
+ temppoint2 = tippoint;
+ distance = findDistance(&temppoint1, &temppoint2);
+ rotation2 = asin((temppoint1.y - temppoint2.y) / distance);
+ rotation2 *= 360 / 6.28;
+ temppoint1.y = 0;
+ temppoint2.y = 0;
+ rotation1 = acos((temppoint1.z - temppoint2.z) / findDistance(&temppoint1, &temppoint2));
+ rotation1 *= 360 / 6.28;
+ rotation3 = 0;
+ smallrotation = 90;
+ smallrotation2 = 0;
+ bigtilt = 0;
+ bigtilt2 = 0;
+ bigrotation = 0;
+ if (temppoint1.x > temppoint2.x)
+ rotation1 = 360 - rotation1;
+
+ //Stop moving
+ if (findLengthfast(&velocity) < .3 && findLengthfast(&tipvelocity) < .3 && hitsomething) {
+ freetime += multiplier;
+ }
+
+ if (freetime > .4) {
+ velocity = 0;
+ tipvelocity = 0;
+ }
+ firstfree = 0;
+ }
+ }
+ multiplier = tempmult;
+ if (blooddrip && bloody) {
+ blooddripdelay -= blooddrip * multiplier / 2;
+ blooddrip -= multiplier;
+ if (blooddrip < 0)
+ blooddrip = 0;
+ if (blooddrip > 5)
+ blooddrip = 5;
+ if (blooddripdelay < 0 && bloodtoggle) {
+ blooddripdelay = 1;
+ XYZ bloodvel;
+ XYZ bloodloc;
+ bloodloc = position + (tippoint - position) * .7;
+ bloodloc.y -= .05;
+ if (bloodtoggle) {
+ bloodvel = 0;
+ Sprite::MakeSprite(bloodsprite, bloodloc, bloodvel, 1, 1, 1, .03, 1);
+ }
+ }
+ }
+ if (onfire) {
+ flamedelay -= multiplier;
+ if (onfire && flamedelay <= 0) {
+ flamedelay = .020;
+ flamedelay -= multiplier;
+ normalrot = 0;
+ if (owner != -1) {
+ normalrot = Person::players[owner]->velocity;
+ }
+ normalrot.y += 1;
+ if (owner != -1) {
+ if (Person::players[owner]->onterrain) {
+ normalrot.y = 1;
+ }
+ }
+ Sprite::MakeSprite(weaponflamesprite, position + tippoint * (((float)abs(Random() % 100)) / 600 + .05), normalrot, 1, 1, 1, (.6 + (float)abs(Random() % 100) / 200 - .25) * 1 / 3, 1);
+ Sprite::setLastSpriteSpeed(4);
+ Sprite::setLastSpriteAlivetime(.3);
+ }
+ }
+
+ if (!onfire && owner == -1 && type != staff) {
+ flamedelay -= multiplier;
+ if (flamedelay <= 0) {
+ flamedelay = .020;
+ flamedelay -= multiplier;
+ normalrot = 0;
+ if (Random() % 50 == 0 && distsq(&position, &viewer) > 80) {
+ XYZ shinepoint;
+ shinepoint = position + (tippoint - position) * (((float)abs(Random() % 100)) / 100);
+ Sprite::MakeSprite(weaponshinesprite, shinepoint, normalrot, 1, 1, 1, (.1 + (float)abs(Random() % 100) / 200 - .25) * 1 / 3 * fast_sqrt(findDistance(&shinepoint, &viewer)), 1);
+ Sprite::setLastSpriteSpeed(4);
+ Sprite::setLastSpriteAlivetime(.3);
+ }
+ }
+ }
+}
+
+void Weapons::DoStuff()