2 Copyright (C) 2003, 2010 - Wolfire Games
4 This file is part of Lugaru.
6 Lugaru is free software; you can redistribute it and/or
7 modify it under the terms of the GNU General Public License
8 as published by the Free Software Foundation; either version 2
9 of the License, or (at your option) any later version.
11 This program is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
15 See the GNU General Public License for more details.
17 You should have received a copy of the GNU General Public License
18 along with this program; if not, write to the Free Software
19 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
22 /**> HEADER FILES <**/
24 #include "openal_wrapper.h"
25 #include "Animation.h"
30 extern float multiplier;
31 extern Terrain terrain;
33 extern int environment;
35 extern FRUSTUM frustum;
37 extern float realmultiplier;
39 extern float slomodelay;
40 extern bool cellophane;
41 extern float texdetail;
42 extern GLubyte bloodText[512 * 512 * 3];
43 extern int bloodtoggle;
44 extern Objects objects;
46 extern bool autoslomo;
47 extern float camerashake;
49 extern float viewdistance;
50 extern float blackout;
51 extern int difficulty;
53 extern int tutoriallevel;
54 extern int numthrowkill;
56 Model Weapon::throwingknifemodel;
57 Texture Weapon::knifetextureptr;
58 Texture Weapon::lightbloodknifetextureptr;
59 Texture Weapon::bloodknifetextureptr;
61 Model Weapon::swordmodel;
62 Texture Weapon::swordtextureptr;
63 Texture Weapon::lightbloodswordtextureptr;
64 Texture Weapon::bloodswordtextureptr;
66 Model Weapon::staffmodel;
67 Texture Weapon::stafftextureptr;
69 Weapon::Weapon(int t, int o) : owner(o)
82 void Weapon::setType(int t)
102 void Weapon::DoStuff(int i)
104 //~ cout << position.x << "," << position.y << "," << position.z << "|" << tippoint.x << "," << tippoint.y << "," << tippoint.z << endl;
105 static int whichpatchx, whichpatchz, whichhit;
106 static XYZ start, end, colpoint, normalrot, footvel, footpoint;
107 static XYZ terrainnormal;
110 static XYZ newpoint1, newpoint2;
111 static float friction = 3.5;
112 static float elasticity = .4;
113 static XYZ bounceness;
114 static float frictionness;
115 static float closestdistance;
116 static float distance;
118 static XYZ closestpoint;
119 static XYZ closestswordpoint;
120 static XYZ extramove;
121 static float tempmult;
126 if (damage >= 2 && type == staff && owner != -1) { // the staff breaks
127 emit_sound_at(staffbreaksound, tippoint);
129 for (int j = 0; j < 40; j++) {
130 tempvel.x = float(abs(Random() % 100) - 50) / 20;
131 tempvel.y = float(abs(Random() % 100) - 50) / 20;
132 tempvel.z = float(abs(Random() % 100) - 50) / 20;
133 Sprite::MakeSprite(splintersprite, position + (tippoint - position) * ((float)j - 8) / 32, tempvel * .5, 115 / 255, 73 / 255, 12 / 255, .1, 1);
136 Person::players[owner]->weaponactive = -1;
137 Person::players[owner]->num_weapons--;
138 if (Person::players[owner]->num_weapons) {
139 Person::players[owner]->weaponids[0] = Person::players[owner]->weaponids[Person::players[owner]->num_weapons];
140 if (Person::players[owner]->weaponstuck == Person::players[owner]->num_weapons)
141 Person::players[owner]->weaponstuck = 0;
152 oldposition = position;
153 oldtippoint = tippoint;
154 if (owner == -1 && (velocity.x || velocity.y || velocity.z) && !physics) { // if the weapon is flying
155 position += velocity * multiplier;
156 tippoint += velocity * multiplier;
157 whichpatchx = position.x / (terrain.size / subdivision * terrain.scale);
158 whichpatchz = position.z / (terrain.size / subdivision * terrain.scale);
159 if (whichpatchx > 0 && whichpatchz > 0 && whichpatchx < subdivision && whichpatchz < subdivision) {
160 if (terrain.patchobjectnum[whichpatchx][whichpatchz]) { // if there are objects where the weapon is
161 for (int j = 0; j < terrain.patchobjectnum[whichpatchx][whichpatchz]; j++) { // check for collision
162 int k = terrain.patchobjects[whichpatchx][whichpatchz][j];
165 whichhit = objects.model[k].LineCheck(&start, &end, &colpoint, &objects.position[k], &objects.yaw[k]);
166 if (whichhit != -1) {
167 if (objects.type[k] == treetrunktype) {
168 objects.model[k].MakeDecal(breakdecal, DoRotation(colpoint - objects.position[k], 0, -objects.yaw[k], 0), .1, 1, Random() % 360);
169 normalrot = DoRotation(objects.model[k].facenormals[whichhit], 0, objects.yaw[k], 0);
172 position = colpoint - normalrot * .1;
173 else if (type == sword)
174 position = colpoint - normalrot * .2;
175 else if (type == staff)
176 position = colpoint - normalrot * .2;
177 XYZ temppoint1, temppoint2, tempforward;
181 temppoint2 = normalrot;
182 distance = findDistance(&temppoint1, &temppoint2);
183 rotation2 = asin((temppoint1.y - temppoint2.y) / distance);
184 rotation2 *= 360 / 6.28;
187 rotation1 = acos((temppoint1.z - temppoint2.z) / findDistance(&temppoint1, &temppoint2));
188 rotation1 *= 360 / 6.28;
189 if (temppoint1.x > temppoint2.x)
190 rotation1 = 360 - rotation1;
199 emit_sound_at(knifesheathesound, position, 128.);
203 Sprite::MakeSprite(cloudimpactsprite, position, velocity, 1, 1, 1, .8, .3);
207 position -= velocity * multiplier;
208 tippoint -= velocity * multiplier;
209 tipvelocity = velocity;
216 if (velocity.x || velocity.y || velocity.z) {
217 for (int j = 0; j < Person::players.size(); j++) {
219 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;
220 if (owner == -1 && distsqflat(&position, &Person::players[j]->coords) < 1.5 &&
221 distsq(&position, &Person::players[j]->coords) < 4 && Person::players[j]->weaponstuck == -1 &&
222 !Person::players[j]->skeleton.free && j != oldowner) {
223 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) {
224 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)) ||
225 (Person::players[j]->creature == rabbittype && Random() % 2 == 0 && Person::players[j]->aitype == attacktypecutoff && Person::players[j]->weaponactive == -1)) {
226 emit_sound_at(knifedrawsound, Person::players[j]->coords, 128.);
228 Person::players[j]->weaponactive = 0;
229 Person::players[j]->animTarget = removeknifeanim;
230 Person::players[j]->frameTarget = 1;
231 Person::players[j]->target = 1;
232 owner = Person::players[j]->id;
233 if (Person::players[j]->num_weapons > 0) {
234 Person::players[j]->weaponids[Person::players[j]->num_weapons] = Person::players[j]->weaponids[0];
236 Person::players[j]->num_weapons++;
237 Person::players[j]->weaponids[0] = i;
239 Person::players[j]->aitype = attacktypecutoff;
243 Person::players[j]->num_weapons++;
244 Person::players[j]->weaponstuck = Person::players[j]->num_weapons - 1;
245 if (normaldotproduct(Person::players[j]->facing, velocity) > 0)
246 Person::players[j]->weaponstuckwhere = 1;
248 Person::players[j]->weaponstuckwhere = 0;
250 Person::players[j]->weaponids[Person::players[j]->num_weapons - 1] = i;
252 Person::players[j]->RagDoll(0);
253 Person::players[j]->jointVel(abdomen) += velocity * 2;
254 Person::players[j]->jointVel(neck) += velocity * 2;
255 Person::players[j]->jointVel(rightshoulder) += velocity * 2;
256 Person::players[j]->jointVel(leftshoulder) += velocity * 2;
257 if (bloodtoggle && tutoriallevel != 1)
258 Sprite::MakeSprite(cloudimpactsprite, footpoint, footvel, 1, 0, 0, .8, .3);
259 if (tutoriallevel == 1)
260 Sprite::MakeSprite(cloudimpactsprite, footpoint, footvel, 1, 1, 1, .8, .3);
261 footvel = tippoint - position;
263 if (bloodtoggle && tutoriallevel != 1)
264 Sprite::MakeSprite(bloodflamesprite, footpoint, footvel * -1, 1, 0, 0, .6, 1);
266 if (tutoriallevel != 1) {
267 if (Person::players[j]->weaponstuckwhere == 0)
268 Person::players[j]->DoBloodBig(2, 205);
269 if (Person::players[j]->weaponstuckwhere == 1)
270 Person::players[j]->DoBloodBig(2, 200);
271 Person::players[j]->damage += 200 / Person::players[j]->armorhigh;
272 Person::players[j]->deathbleeding = 1;
273 Person::players[j]->bloodloss += (200 + abs((float)(Random() % 40)) - 20) / Person::players[j]->armorhigh;
279 emit_sound_at(fleshstabsound, position, 128.);
281 if (animation[Person::players[0]->animTarget].height == highheight)
282 award_bonus(0, ninja);
284 award_bonus(0, Bullseyebonus);
292 if (position.y < terrain.getHeight(position.x, position.z)) {
293 if (terrain.getOpacity(position.x, position.z) < .2) {
295 if (terrain.lineTerrain(oldposition, position, &colpoint) != -1) {
296 position = colpoint * terrain.scale;
298 position.y = terrain.getHeight(position.x, position.z);
301 terrain.MakeDecal(shadowdecalpermanent, position, .06, .5, 0);
302 normalrot = terrain.getNormal(position.x, position.z) * -1;
304 glMatrixMode(GL_MODELVIEW);
308 glRotatef(bigrotation, 0, 1, 0);
309 glRotatef(bigtilt2, 1, 0, 0);
310 glRotatef(bigtilt, 0, 0, 1);
311 glRotatef(-rotation1 + 90, 0, 1, 0);
312 glRotatef(-rotation2 + 90, 0, 0, 1);
313 glRotatef(-rotation3, 0, 1, 0);
314 glRotatef(smallrotation, 1, 0, 0);
315 glRotatef(smallrotation2, 0, 1, 0);
316 glTranslatef(0, 0, 1);
317 glGetFloatv(GL_MODELVIEW_MATRIX, M);
322 position -= tippoint * .15;
323 XYZ temppoint1, temppoint2, tempforward;
332 emit_sound_at(knifesheathesound, position, 128.);
335 terrainlight = terrain.getLighting(position.x, position.z);
336 if (environment == snowyenvironment) {
337 if (distsq(&position, &viewer) < viewdistance * viewdistance / 4)
338 Sprite::MakeSprite(cloudsprite, position, velocity, terrainlight.x, terrainlight.y, terrainlight.z, .5, .7);
339 } else if (environment == grassyenvironment) {
340 if (distsq(&position, &viewer) < viewdistance * viewdistance / 4)
341 Sprite::MakeSprite(cloudsprite, position, velocity, terrainlight.x * 90 / 255, terrainlight.y * 70 / 255, terrainlight.z * 8 / 255, .5, .5);
342 } else if (environment == desertenvironment) {
343 if (distsq(&position, &viewer) < viewdistance * viewdistance / 4)
344 Sprite::MakeSprite(cloudsprite, position, velocity, terrainlight.x * 190 / 255, terrainlight.y * 170 / 255, terrainlight.z * 108 / 255, .5, .7);
351 position -= velocity * multiplier;
352 tippoint -= velocity * multiplier;
353 tipvelocity = velocity;
356 if (velocity.x != 0 || velocity.z != 0 || velocity.y != 0) {
357 velocity.y += gravity * multiplier;
359 XYZ temppoint1, temppoint2, tempforward;
363 temppoint2 = velocity;
364 distance = findDistance(&temppoint1, &temppoint2);
365 rotation2 = asin((temppoint1.y - temppoint2.y) / distance);
366 rotation2 *= 360 / 6.28;
369 rotation1 = acos((temppoint1.z - temppoint2.z) / findDistance(&temppoint1, &temppoint2));
370 rotation1 *= 360 / 6.28;
377 if (temppoint1.x > temppoint2.x)
378 rotation1 = 360 - rotation1;
388 tempmult = multiplier;
390 for (int l = 0; l < 10; l++) {
391 if (owner == -1 && (velocity.x || velocity.y || velocity.z) && physics) {
393 position += velocity * multiplier;
394 tippoint += tipvelocity * multiplier;
397 midp = (position * mass + tippoint * tipmass) / (mass + tipmass);
398 vel = tippoint - midp;
400 newpoint1 = midp - vel * length * (tipmass / (mass + tipmass));
401 newpoint2 = midp + vel * length * (mass / (mass + tipmass));
403 if (freetime > .04) {
404 velocity = velocity + (newpoint1 - position) / multiplier;
405 tipvelocity = tipvelocity + (newpoint2 - tippoint) / multiplier;
408 position = newpoint1;
409 tippoint = newpoint2;
413 whichpatchx = (position.x) / (terrain.size / subdivision * terrain.scale);
414 whichpatchz = (position.z) / (terrain.size / subdivision * terrain.scale);
415 if (whichpatchx > 0 && whichpatchz > 0 && whichpatchx < subdivision && whichpatchz < subdivision)
416 if (terrain.patchobjectnum[whichpatchx][whichpatchz]) {
417 for (int j = 0; j < terrain.patchobjectnum[whichpatchx][whichpatchz]; j++) {
418 int k = terrain.patchobjects[whichpatchx][whichpatchz][j];
422 start = tippoint - (position - tippoint) / 5;
423 end = position + (position - tippoint) / 30;
424 whichhit = objects.model[k].LineCheck(&start, &end, &colpoint, &objects.position[k], &objects.yaw[k]);
425 if (whichhit != -1) {
427 diff = (colpoint - position);
431 tippoint += (colpoint - position) + diff * .05;
432 position = colpoint + diff * .05;
433 oldtippoint = tippoint;
434 oldposition = tippoint;
437 start = position - (tippoint - position) / 5;
438 end = tippoint + (tippoint - position) / 30;
439 whichhit = objects.model[k].LineCheck(&start, &end, &colpoint, &objects.position[k], &objects.yaw[k]);
440 if (whichhit != -1) {
442 diff = (colpoint - tippoint);
446 position += (colpoint - tippoint) + diff * .05;
447 tippoint = colpoint + diff * .05;
448 oldposition = position;
449 oldtippoint = tippoint;
456 whichhit = objects.model[k].LineCheck(&start, &end, &colpoint, &objects.position[k], &objects.yaw[k]);
457 if (whichhit != -1) {
460 terrainnormal = DoRotation(objects.model[k].facenormals[whichhit], 0, objects.yaw[k], 0) * -1;
461 ReflectVector(&velocity, &terrainnormal);
462 position += terrainnormal * .002;
464 bounceness = terrainnormal * findLength(&velocity) * (abs(normaldotproduct(velocity, terrainnormal)));
465 if (findLengthfast(&velocity) < findLengthfast(&bounceness))
467 frictionness = abs(normaldotproduct(velocity, terrainnormal));
468 velocity -= bounceness;
469 if (1 - friction * frictionness > 0)
470 velocity *= 1 - friction * frictionness;
473 velocity += bounceness * elasticity;
475 if (findLengthfast(&bounceness) > 1) {
478 whichsound = footstepsound3 + abs(Random() % 2);
480 whichsound = clank1sound + abs(Random() % 4);
481 emit_sound_at(whichsound, position, 128 * findLengthfast(&bounceness));
486 whichhit = objects.model[k].LineCheck(&start, &end, &colpoint, &objects.position[k], &objects.yaw[k]);
487 if (whichhit != -1) {
490 terrainnormal = DoRotation(objects.model[k].facenormals[whichhit], 0, objects.yaw[k], 0) * -1;
491 ReflectVector(&tipvelocity, &terrainnormal);
492 tippoint += terrainnormal * .002;
494 bounceness = terrainnormal * findLength(&tipvelocity) * (abs(normaldotproduct(tipvelocity, terrainnormal)));
495 if (findLengthfast(&tipvelocity) < findLengthfast(&bounceness))
497 frictionness = abs(normaldotproduct(tipvelocity, terrainnormal));
498 tipvelocity -= bounceness;
499 if (1 - friction * frictionness > 0)
500 tipvelocity *= 1 - friction * frictionness;
503 tipvelocity += bounceness * elasticity;
505 if (findLengthfast(&bounceness) > 1) {
508 whichsound = footstepsound3 + abs(Random() % 2);
510 whichsound = clank1sound + abs(Random() % 4);
511 emit_sound_at(whichsound, position, 128 * findLengthfast(&bounceness));
515 if ((objects.type[k] != boxtype && objects.type[k] != platformtype && objects.type[k] != walltype && objects.type[k] != weirdtype) || objects.pitch[k] != 0)
516 for (int m = 0; m < 2; m++) {
517 mid = (position * (21 + (float)m * 10) + tippoint * (19 - (float)m * 10)) / 40;
519 oldmid = (oldposition * (21 + (float)m * 10) + oldtippoint * (19 - (float)m * 10)) / 40;
523 whichhit = objects.model[k].LineCheck(&start, &end, &colpoint, &objects.position[k], &objects.yaw[k]);
524 if (whichhit != -1) {
527 terrainnormal = DoRotation(objects.model[k].facenormals[whichhit], 0, objects.yaw[k], 0) * -1;
528 ReflectVector(&velocity, &terrainnormal);
530 bounceness = terrainnormal * findLength(&velocity) * (abs(normaldotproduct(velocity, terrainnormal)));
531 if (findLengthfast(&velocity) < findLengthfast(&bounceness))
533 frictionness = abs(normaldotproduct(velocity, terrainnormal));
534 velocity -= bounceness;
535 if (1 - friction * frictionness > 0)
536 velocity *= 1 - friction * frictionness;
539 velocity += bounceness * elasticity;
541 if (findLengthfast(&bounceness) > 1) {
544 whichsound = footstepsound3 + abs(Random() % 2);
546 whichsound = clank1sound + abs(Random() % 4);
547 emit_sound_at(whichsound, mid, 128 * findLengthfast(&bounceness));
549 position += (mid - oldmid2) * (20 / (1 + (float)m * 10));
552 mid = (position * (19 - (float)m * 10) + tippoint * (21 + (float)m * 10)) / 40;
554 oldmid = (oldposition * (19 - (float)m * 10) + oldtippoint * (21 + (float)m * 10)) / 40;
558 whichhit = objects.model[k].LineCheck(&start, &end, &colpoint, &objects.position[k], &objects.yaw[k]);
559 if (whichhit != -1) {
562 terrainnormal = DoRotation(objects.model[k].facenormals[whichhit], 0, objects.yaw[k], 0) * -1;
563 ReflectVector(&tipvelocity, &terrainnormal);
565 bounceness = terrainnormal * findLength(&tipvelocity) * (abs(normaldotproduct(tipvelocity, terrainnormal)));
566 if (findLengthfast(&tipvelocity) < findLengthfast(&bounceness))
568 frictionness = abs(normaldotproduct(tipvelocity, terrainnormal));
569 tipvelocity -= bounceness;
570 if (1 - friction * frictionness > 0)
571 tipvelocity *= 1 - friction * frictionness;
574 tipvelocity += bounceness * elasticity;
576 if (findLengthfast(&bounceness) > 1) {
579 whichsound = footstepsound3 + abs(Random() % 2);
581 whichsound = clank1sound + abs(Random() % 4);
582 emit_sound_at(whichsound, mid, 128 * findLengthfast(&bounceness));
584 tippoint += (mid - oldmid2) * (20 / (1 + (float)m * 10));
590 whichhit = objects.model[k].LineCheck(&start, &end, &colpoint, &objects.position[k], &objects.yaw[k]);
591 if (whichhit != -1) {
593 closestdistance = -1;
594 closestswordpoint = colpoint; //(position+tippoint)/2;
595 point[0] = DoRotation(objects.model[k].vertex[objects.model[k].Triangles[whichhit].vertex[0]], 0, objects.yaw[k], 0) + objects.position[k];
596 point[1] = DoRotation(objects.model[k].vertex[objects.model[k].Triangles[whichhit].vertex[1]], 0, objects.yaw[k], 0) + objects.position[k];
597 point[2] = DoRotation(objects.model[k].vertex[objects.model[k].Triangles[whichhit].vertex[2]], 0, objects.yaw[k], 0) + objects.position[k];
598 if (DistancePointLine(&closestswordpoint, &point[0], &point[1], &distance, &colpoint )) {
599 if (distance < closestdistance || closestdistance == -1) {
600 closestpoint = colpoint;
601 closestdistance = distance;
604 if (DistancePointLine(&closestswordpoint, &point[1], &point[2], &distance, &colpoint )) {
605 if (distance < closestdistance || closestdistance == -1) {
606 closestpoint = colpoint;
607 closestdistance = distance;
610 if (DistancePointLine(&closestswordpoint, &point[2], &point[0], &distance, &colpoint )) {
611 if (distance < closestdistance || closestdistance == -1) {
612 closestpoint = colpoint;
613 closestdistance = distance;
616 if (closestdistance != -1 && isnormal(closestdistance)) {
617 if (DistancePointLine(&closestpoint, &position, &tippoint, &distance, &colpoint )) {
618 closestswordpoint = colpoint;
619 velocity += (closestpoint - closestswordpoint);
620 tipvelocity += (closestpoint - closestswordpoint);
621 position += (closestpoint - closestswordpoint);
622 tippoint += (closestpoint - closestswordpoint);
630 whichhit = terrain.lineTerrain(oldposition, position, &colpoint);
631 if (whichhit != -1 || position.y < terrain.getHeight(position.x, position.z)) {
634 position = colpoint * terrain.scale;
636 position.y = terrain.getHeight(position.x, position.z);
638 terrainnormal = terrain.getNormal(position.x, position.z);
639 ReflectVector(&velocity, &terrainnormal);
640 position += terrainnormal * .002;
641 bounceness = terrainnormal * findLength(&velocity) * (abs(normaldotproduct(velocity, terrainnormal)));
642 if (findLengthfast(&velocity) < findLengthfast(&bounceness))
644 frictionness = abs(normaldotproduct(velocity, terrainnormal));
645 velocity -= bounceness;
646 if (1 - friction * frictionness > 0)
647 velocity *= 1 - friction * frictionness;
650 if (terrain.getOpacity(position.x, position.z) < .2)
651 velocity += bounceness * elasticity * .3;
653 velocity += bounceness * elasticity;
655 if (findLengthfast(&bounceness) > 1) {
657 if (terrain.getOpacity(position.x, position.z) > .2) {
659 whichsound = footstepsound3 + abs(Random() % 2);
661 whichsound = clank1sound + abs(Random() % 4);
663 whichsound = footstepsound + abs(Random() % 2);
665 emit_sound_at(whichsound, position,
666 findLengthfast(&bounceness)
667 * (terrain.getOpacity(position.x, position.z) > .2 ? 128. : 32.));
669 if (terrain.getOpacity(position.x, position.z) < .2) {
671 terrainlight = terrain.getLighting(position.x, position.z);
672 if (environment == snowyenvironment) {
673 if (distsq(&position, &viewer) < viewdistance * viewdistance / 4)
674 Sprite::MakeSprite(cloudsprite, position, velocity, terrainlight.x, terrainlight.y, terrainlight.z, .5, .7);
675 } else if (environment == grassyenvironment) {
676 if (distsq(&position, &viewer) < viewdistance * viewdistance / 4)
677 Sprite::MakeSprite(cloudsprite, position, velocity, terrainlight.x * 90 / 255, terrainlight.y * 70 / 255, terrainlight.z * 8 / 255, .5, .5);
678 } else if (environment == desertenvironment) {
679 if (distsq(&position, &viewer) < viewdistance * viewdistance / 4)
680 Sprite::MakeSprite(cloudsprite, position, velocity, terrainlight.x * 190 / 255, terrainlight.y * 170 / 255, terrainlight.z * 108 / 255, .5, .7);
685 whichhit = terrain.lineTerrain(oldtippoint, tippoint, &colpoint);
686 if (whichhit != -1 || tippoint.y < terrain.getHeight(tippoint.x, tippoint.z)) {
688 tippoint = colpoint * terrain.scale;
690 tippoint.y = terrain.getHeight(tippoint.x, tippoint.z);
692 terrainnormal = terrain.getNormal(tippoint.x, tippoint.z);
693 ReflectVector(&tipvelocity, &terrainnormal);
694 tippoint += terrainnormal * .002;
695 bounceness = terrainnormal * findLength(&tipvelocity) * (abs(normaldotproduct(tipvelocity, terrainnormal)));
696 if (findLengthfast(&tipvelocity) < findLengthfast(&bounceness))
698 frictionness = abs(normaldotproduct(tipvelocity, terrainnormal));
699 tipvelocity -= bounceness;
700 if (1 - friction * frictionness > 0)
701 tipvelocity *= 1 - friction * frictionness;
704 if (terrain.getOpacity(tippoint.x, tippoint.z) < .2)
705 tipvelocity += bounceness * elasticity * .3;
707 tipvelocity += bounceness * elasticity;
709 if (findLengthfast(&bounceness) > 1) {
711 if (terrain.getOpacity(tippoint.x, tippoint.z) > .2) {
713 whichsound = footstepsound3 + abs(Random() % 2);
715 whichsound = clank1sound + abs(Random() % 4);
717 whichsound = footstepsound + abs(Random() % 2);
719 emit_sound_at(whichsound, tippoint,
720 findLengthfast(&bounceness)
721 * (terrain.getOpacity(tippoint.x, tippoint.z) > .2 ? 128. : 32.));
723 if (terrain.getOpacity(tippoint.x, tippoint.z) < .2) {
725 terrainlight = terrain.getLighting(tippoint.x, tippoint.z);
726 if (environment == snowyenvironment) {
727 if (distsq(&tippoint, &viewer) < viewdistance * viewdistance / 4)
728 Sprite::MakeSprite(cloudsprite, tippoint, tipvelocity, terrainlight.x, terrainlight.y, terrainlight.z, .5, .7);
729 } else if (environment == grassyenvironment) {
730 if (distsq(&tippoint, &viewer) < viewdistance * viewdistance / 4)
731 Sprite::MakeSprite(cloudsprite, tippoint, tipvelocity, terrainlight.x * 90 / 255, terrainlight.y * 70 / 255, terrainlight.z * 8 / 255, .5, .5);
732 } else if (environment == desertenvironment) {
733 if (distsq(&tippoint, &viewer) < viewdistance * viewdistance / 4)
734 Sprite::MakeSprite(cloudsprite, tippoint, tipvelocity, terrainlight.x * 190 / 255, terrainlight.y * 170 / 255, terrainlight.z * 108 / 255, .5, .7);
741 mid = position + tippoint;
743 mid += (position - mid) / 20;
745 if (mid.y < terrain.getHeight(mid.x, mid.z)) {
747 mid.y = terrain.getHeight(mid.x, mid.z);
749 terrainnormal = terrain.getNormal(mid.x, mid.z);
750 ReflectVector(&velocity, &terrainnormal);
751 //mid+=terrainnormal*.002;
752 bounceness = terrainnormal * findLength(&velocity) * (abs(normaldotproduct(velocity, terrainnormal)));
753 if (findLengthfast(&velocity) < findLengthfast(&bounceness))
755 frictionness = abs(normaldotproduct(velocity, terrainnormal));
756 velocity -= bounceness;
757 if (1 - friction * frictionness > 0)
758 velocity *= 1 - friction * frictionness;
761 if (terrain.getOpacity(mid.x, mid.z) < .2)
762 velocity += bounceness * elasticity * .3;
764 velocity += bounceness * elasticity;
766 if (findLengthfast(&bounceness) > 1) {
768 if (terrain.getOpacity(mid.x, mid.z) > .2) {
770 whichsound = footstepsound3 + abs(Random() % 2);
772 whichsound = clank1sound + abs(Random() % 4);
774 whichsound = footstepsound + abs(Random() % 2);
776 emit_sound_at(whichsound, mid,
777 findLengthfast(&bounceness)
778 * (terrain.getOpacity(position.x, position.z) > .2
782 position += (mid - oldmid) * 20;
785 mid = position + tippoint;
787 mid += (tippoint - mid) / 20;
789 if (mid.y < terrain.getHeight(mid.x, mid.z)) {
791 mid.y = terrain.getHeight(mid.x, mid.z);
793 terrainnormal = terrain.getNormal(mid.x, mid.z);
794 ReflectVector(&tipvelocity, &terrainnormal);
795 //mid+=terrainnormal*.002;
796 bounceness = terrainnormal * findLength(&tipvelocity) * (abs(normaldotproduct(tipvelocity, terrainnormal)));
797 if (findLengthfast(&tipvelocity) < findLengthfast(&bounceness))
799 frictionness = abs(normaldotproduct(tipvelocity, terrainnormal));
800 tipvelocity -= bounceness;
801 if (1 - friction * frictionness > 0)
802 tipvelocity *= 1 - friction * frictionness;
805 if (terrain.getOpacity(mid.x, mid.z) < .2)
806 tipvelocity += bounceness * elasticity * .3;
808 tipvelocity += bounceness * elasticity;
810 if (findLengthfast(&bounceness) > 1) {
812 if (terrain.getOpacity(mid.x, mid.z) > .2) {
814 whichsound = footstepsound3 + abs(Random() % 2);
816 whichsound = clank1sound + abs(Random() % 4);
818 whichsound = footstepsound + abs(Random() % 2);
820 emit_sound_at(whichsound, mid,
821 findLengthfast(&bounceness)
822 * (terrain.getOpacity(position.x, position.z) > .2
826 tippoint += (mid - oldmid) * 20;
829 velocity.y += gravity * multiplier;
830 tipvelocity.y += gravity * multiplier;
833 XYZ temppoint1, temppoint2, tempforward;
836 temppoint1 = position;
837 temppoint2 = tippoint;
838 distance = findDistance(&temppoint1, &temppoint2);
839 rotation2 = asin((temppoint1.y - temppoint2.y) / distance);
840 rotation2 *= 360 / 6.28;
843 rotation1 = acos((temppoint1.z - temppoint2.z) / findDistance(&temppoint1, &temppoint2));
844 rotation1 *= 360 / 6.28;
851 if (temppoint1.x > temppoint2.x)
852 rotation1 = 360 - rotation1;
855 if (findLengthfast(&velocity) < .3 && findLengthfast(&tipvelocity) < .3 && hitsomething) {
856 freetime += multiplier;
866 multiplier = tempmult;
867 if (blooddrip && bloody) {
868 blooddripdelay -= blooddrip * multiplier / 2;
869 blooddrip -= multiplier;
874 if (blooddripdelay < 0 && bloodtoggle) {
878 bloodloc = position + (tippoint - position) * .7;
882 Sprite::MakeSprite(bloodsprite, bloodloc, bloodvel, 1, 1, 1, .03, 1);
887 flamedelay -= multiplier;
888 if (onfire && flamedelay <= 0) {
890 flamedelay -= multiplier;
893 normalrot = Person::players[owner]->velocity;
897 if (Person::players[owner]->onterrain) {
901 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);
902 Sprite::setLastSpriteSpeed(4);
903 Sprite::setLastSpriteAlivetime(.3);
907 if (!onfire && owner == -1 && type != staff) {
908 flamedelay -= multiplier;
909 if (flamedelay <= 0) {
911 flamedelay -= multiplier;
913 if (Random() % 50 == 0 && distsq(&position, &viewer) > 80) {
915 shinepoint = position + (tippoint - position) * (((float)abs(Random() % 100)) / 100);
916 Sprite::MakeSprite(weaponshinesprite, shinepoint, normalrot, 1, 1, 1, (.1 + (float)abs(Random() % 100) / 200 - .25) * 1 / 3 * fast_sqrt(findDistance(&shinepoint, &viewer)), 1);
917 Sprite::setLastSpriteSpeed(4);
918 Sprite::setLastSpriteAlivetime(.3);
924 void Weapons::DoStuff()
928 for (std::vector<Weapon>::iterator weapon = begin(); weapon != end(); ++weapon) {
929 weapon->DoStuff(i++);
935 static XYZ terrainlight;
936 static GLfloat M[16];
938 if ((frustum.SphereInFrustum(position.x, position.y, position.z, 1) &&
939 distsq(&viewer, &position) < viewdistance * viewdistance)) {
943 if (velocity.x && !physics)
948 if (Person::players[owner]->occluded < 25)
949 if ((frustum.SphereInFrustum(Person::players[owner]->coords.x, Person::players[owner]->coords.y + Person::players[owner]->scale * 3, Person::players[owner]->coords.z, Person::players[owner]->scale * 8) && distsq(&viewer, &Person::players[owner]->coords) < viewdistance * viewdistance) || Person::players[owner]->skeleton.free == 3)
952 (Person::players[owner]->animTarget == knifeslashstartanim ||
953 Person::players[owner]->animTarget == swordsneakattackanim ||
954 (Person::players[owner]->animCurrent == staffhitanim && Person::players[owner]->frameCurrent > 1) ||
955 (Person::players[owner]->animCurrent == staffhitreversedanim && Person::players[owner]->frameCurrent > 1) ||
956 (Person::players[owner]->animCurrent == staffspinhitanim && Person::players[owner]->frameCurrent > 1) ||
957 (Person::players[owner]->animCurrent == staffspinhitreversedanim && Person::players[owner]->frameCurrent > 1) ||
958 (Person::players[owner]->animCurrent == staffgroundsmashanim && Person::players[owner]->frameCurrent > 1) ||
959 (Person::players[owner]->animTarget == swordslashanim && Person::players[owner]->frameTarget < 7) ||
960 Person::players[owner]->animTarget == crouchstabanim ||
961 Person::players[owner]->animTarget == swordslashreversalanim ||
962 Person::players[owner]->animTarget == swordslashreversedanim ||
963 Person::players[owner]->animTarget == knifefollowanim ||
964 Person::players[owner]->animTarget == swordgroundstabanim ||
965 Person::players[owner]->animTarget == knifethrowanim) &&
966 Person::players[owner]->animTarget == lastdrawnanim &&
967 !Person::players[owner]->skeleton.free
973 if (Person::players[owner]->animTarget == swordgroundstabanim) {
974 lastdrawnrotation1 = rotation1;
975 lastdrawnrotation2 = rotation2;
976 lastdrawnrotation3 = rotation3;
977 lastdrawnbigrotation = bigrotation;
978 lastdrawnbigtilt = bigtilt;
979 lastdrawnbigtilt2 = bigtilt2;
980 lastdrawnsmallrotation = smallrotation;
981 lastdrawnsmallrotation2 = smallrotation2;
985 terrainlight = terrain.getLighting(position.x, position.z);
986 if (drawhowmany > 0) {
987 glAlphaFunc(GL_GREATER, 0.01);
989 for (int j = drawhowmany; j > 0; j--) {
990 glMatrixMode(GL_MODELVIEW);
992 glColor4f(terrainlight.x, terrainlight.y, terrainlight.z, j / drawhowmany);
994 glTranslatef(position.x * (((float)(j)) / drawhowmany) + lastdrawnposition.x * (1 - ((float)(j)) / drawhowmany), position.y * (((float)(j)) / drawhowmany) + lastdrawnposition.y * (1 - ((float)(j)) / drawhowmany), position.z * (((float)(j)) / drawhowmany) + lastdrawnposition.z * (1 - ((float)(j)) / drawhowmany));
996 glTranslatef(position.x * (((float)(j)) / drawhowmany) + lastdrawnposition.x * (1 - ((float)(j)) / drawhowmany), position.y * (((float)(j)) / drawhowmany) - .02 + lastdrawnposition.y * (1 - ((float)(j)) / drawhowmany), position.z * (((float)(j)) / drawhowmany) + lastdrawnposition.z * (1 - ((float)(j)) / drawhowmany));
997 glRotatef(bigrotation * (((float)(j)) / drawhowmany) + lastdrawnbigrotation * (1 - ((float)(j)) / drawhowmany), 0, 1, 0);
998 glRotatef(bigtilt2 * (((float)(j)) / drawhowmany) + lastdrawnbigtilt2 * (1 - ((float)(j)) / drawhowmany), 1, 0, 0);
999 glRotatef(bigtilt * (((float)(j)) / drawhowmany) + lastdrawnbigtilt * (1 - ((float)(j)) / drawhowmany), 0, 0, 1);
1000 glRotatef(-rotation1 * (((float)(j)) / drawhowmany) - lastdrawnrotation1 * (1 - ((float)(j)) / drawhowmany) + 90, 0, 1, 0);
1001 glRotatef(-rotation2 * (((float)(j)) / drawhowmany) - lastdrawnrotation2 * (1 - ((float)(j)) / drawhowmany) + 90, 0, 0, 1);
1002 glRotatef(-rotation3 * (((float)(j)) / drawhowmany) - lastdrawnrotation3 * (1 - ((float)(j)) / drawhowmany), 0, 1, 0);
1003 glRotatef(smallrotation * (((float)(j)) / drawhowmany) + lastdrawnsmallrotation * (1 - ((float)(j)) / drawhowmany), 1, 0, 0);
1004 glRotatef(smallrotation2 * (((float)(j)) / drawhowmany) + lastdrawnsmallrotation2 * (1 - ((float)(j)) / drawhowmany), 0, 1, 0);
1007 if (Person::players[owner]->animTarget == staffhitanim || Person::players[owner]->animCurrent == staffhitanim || Person::players[owner]->animTarget == staffhitreversedanim || Person::players[owner]->animCurrent == staffhitreversedanim) {
1008 glTranslatef(0, 0, -.3);
1010 if (Person::players[owner]->animTarget == staffgroundsmashanim || Person::players[owner]->animCurrent == staffgroundsmashanim || Person::players[owner]->animTarget == staffspinhitreversedanim || Person::players[owner]->animCurrent == staffspinhitreversedanim || Person::players[owner]->animTarget == staffspinhitanim || Person::players[owner]->animCurrent == staffspinhitanim) {
1011 glTranslatef(0, 0, -.1);
1015 glEnable(GL_LIGHTING);
1018 if (!bloody || !bloodtoggle)
1019 throwingknifemodel.drawdifftex(knifetextureptr);
1022 throwingknifemodel.drawdifftex(lightbloodknifetextureptr);
1024 throwingknifemodel.drawdifftex(bloodknifetextureptr);
1028 if (!bloody || !bloodtoggle)
1029 swordmodel.drawdifftex(swordtextureptr);
1032 swordmodel.drawdifftex(lightbloodswordtextureptr);
1034 swordmodel.drawdifftex(bloodswordtextureptr);
1038 staffmodel.drawdifftex(stafftextureptr);
1045 lastdrawnposition = position;
1046 lastdrawntippoint = tippoint;
1047 lastdrawnrotation1 = rotation1;
1048 lastdrawnrotation2 = rotation2;
1049 lastdrawnrotation3 = rotation3;
1050 lastdrawnbigrotation = bigrotation;
1051 lastdrawnbigtilt = bigtilt;
1052 lastdrawnbigtilt2 = bigtilt2;
1053 lastdrawnsmallrotation = smallrotation;
1054 lastdrawnsmallrotation2 = smallrotation2;
1056 lastdrawnanim = Person::players[owner]->animCurrent;
1059 glMatrixMode(GL_MODELVIEW);
1062 glTranslatef(position.x, position.y - .02, position.z);
1063 glRotatef(bigrotation, 0, 1, 0);
1064 glRotatef(bigtilt2, 1, 0, 0);
1065 glRotatef(bigtilt, 0, 0, 1);
1066 glRotatef(-rotation1 + 90, 0, 1, 0);
1067 glRotatef(-rotation2 + 90, 0, 0, 1);
1068 glRotatef(-rotation3, 0, 1, 0);
1069 glRotatef(smallrotation, 1, 0, 0);
1070 glRotatef(smallrotation2, 0, 1, 0);
1071 glTranslatef(0, 0, length);
1072 glGetFloatv(GL_MODELVIEW_MATRIX, M);
1083 glAlphaFunc(GL_GREATER, 0.9);
1084 glEnable(GL_TEXTURE_2D);
1086 glEnable(GL_CULL_FACE);
1087 glCullFace(GL_FRONT);
1090 for (std::vector<Weapon>::iterator weapon = begin(); weapon != end(); ++weapon) {
1102 Weapon::stafftextureptr.destroy();
1103 Weapon::knifetextureptr.destroy();
1104 Weapon::lightbloodknifetextureptr.destroy();
1105 Weapon::bloodknifetextureptr.destroy();
1106 Weapon::swordtextureptr.destroy();
1107 Weapon::lightbloodswordtextureptr.destroy();
1108 Weapon::bloodswordtextureptr.destroy();