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 float realtexdetail;
43 extern GLubyte bloodText[512 * 512 * 3];
44 extern GLubyte wolfbloodText[512 * 512 * 3];
45 extern int bloodtoggle;
46 extern Objects objects;
48 extern bool autoslomo;
49 extern float camerashake;
51 extern float viewdistance;
52 extern float blackout;
53 extern int difficulty;
55 extern float fadestart;
57 extern bool winfreeze;
58 extern float flashamount, flashr, flashg, flashb;
59 extern int flashdelay;
60 extern bool showpoints;
61 extern bool immediate;
63 extern bool tilt2weird;
64 extern bool tiltweird;
66 extern bool proportionweird;
67 extern bool vertexweird[6];
68 extern XYZ envsound[30];
69 extern float envsoundvol[30];
70 extern float envsoundlife[30];
71 extern int numenvsounds;
72 extern int tutoriallevel;
73 extern float smoketex;
74 extern int tutorialstage;
75 extern bool reversaltrain;
76 extern bool canattack;
78 extern float damagedealt;
80 extern float hostiletime;
82 extern int indialogue;
84 extern bool gamestarted;
86 std::vector<std::shared_ptr<Person>> Person::players(1, std::shared_ptr<Person>(new Person()));
91 * GameTick/doPlayerCollisions
93 void Person::CheckKick()
96 && (animTarget == rabbitkickanim
98 && victim != this->shared_from_this()
100 && animCurrent == rabbitkickanim)
101 && distsq(&coords, &victim->coords) < 1.2
102 && !victim->skeleton.free))
105 if (animation[victim->animTarget].height != lowheight) {
106 float damagemult = (creature == wolftype ? 2.5 : 1.) * power * power;
107 XYZ relative = velocity;
109 Normalise(&relative);
113 if (tutoriallevel != 1)
114 emit_sound_at(heavyimpactsound, victim->coords);
116 for (int i = 0; i < victim->skeleton.num_joints; i++) {
117 victim->skeleton.joints[i].velocity += relative * 120 * damagemult;
120 victim->DoDamage(100 * damagemult / victim->protectionhigh);
126 animTarget = backflipanim;
128 velocity = facing * -10;
132 resume_stream(whooshsound);
134 award_bonus(id, cannon);
135 } else if (victim->isCrouch()) {
136 animTarget = rabbitkickreversedanim;
137 animCurrent = rabbitkickreversedanim;
138 victim->animCurrent = rabbitkickreversalanim;
139 victim->animTarget = rabbitkickreversalanim;
145 victim->oldcoords = victim->coords;
146 coords = victim->coords;
147 victim->targetyaw = targetyaw;
148 victim->victim = this->shared_from_this();
155 * GameTick/doPlayerCollisions - spread fire between players
156 * GameTick/doDebugKeys - press f to ignite
157 * Person::DoStuff - spread fire from lit campfires and bushes
159 void Person::CatchFire()
161 XYZ flatfacing, flatvelocity;
163 for (int i = 0; i < 10; i++) {
164 howmany = abs(Random() % (skeleton.num_joints));
166 flatvelocity = velocity;
168 flatvelocity = skeleton.joints[howmany].velocity;
170 flatfacing = DoRotation(DoRotation(DoRotation(skeleton.joints[howmany].position, 0, 0, tilt), tilt2, 0, 0), 0, yaw, 0) * scale + coords;
172 flatfacing = skeleton.joints[howmany].position * scale + coords;
173 Sprite::MakeSprite(flamesprite, flatfacing, flatvelocity, 1, 1, 1, 2, 1);
178 emit_sound_at(firestartsound, coords);
180 emit_stream_at(stream_firesound, coords);
188 * idle animation for this creature (depending on status)
190 int Person::getIdle()
192 if (indialogue != -1 && howactive == typeactive && creature == rabbittype)
194 if (hasvictim && (victim != this->shared_from_this())/*||(id==0&&attackkeydown)*/)
195 if (/*(id==0&&attackkeydown)||*/(!victim->dead && victim->aitype != passivetype &&
196 victim->aitype != searchtype && aitype != passivetype && aitype != searchtype &&
197 victim->id < Person::players.size())) {
198 if ((aitype == playercontrolled && stunned <= 0 && weaponactive == -1) || pause) {
199 if (creature == rabbittype)
200 return fightidleanim;
201 if (creature == wolftype)
204 if (aitype == playercontrolled && stunned <= 0 && weaponactive != -1) {
205 if (weapons[weaponids[weaponactive]].getType() == knife)
206 return knifefightidleanim;
207 if (weapons[weaponids[weaponactive]].getType() == sword && victim->weaponactive != -1)
208 return swordfightidlebothanim;
209 if (weapons[weaponids[weaponactive]].getType() == sword)
210 return swordfightidleanim;
211 if (weapons[weaponids[weaponactive]].getType() == staff)
212 return swordfightidleanim;
214 if (aitype != playercontrolled && stunned <= 0 && creature != wolftype && !pause)
215 return fightsidestep;
217 if ((damage > permanentdamage || damage > damagetolerance * .8 || deathbleeding > 0) && creature != wolftype)
219 if (howactive == typesitting) return sitanim;
220 if (howactive == typesittingwall) return sitwallanim;
221 if (howactive == typesleeping) return sleepanim;
222 if (howactive == typedead1) return dead1anim;
223 if (howactive == typedead2) return dead2anim;
224 if (howactive == typedead3) return dead3anim;
225 if (howactive == typedead4) return dead4anim;
226 if (creature == rabbittype) return bounceidleanim;
227 if (creature == wolftype) return wolfidle;
232 * crouch animation for this creature
234 int Person::getCrouch()
236 if (creature == rabbittype)
238 if (creature == wolftype)
239 return wolfcrouchanim;
244 * running animation for this creature (can be upright or all fours)
248 if (creature == rabbittype && (!superruntoggle || weaponactive != -1))
250 if (creature == wolftype && (!superruntoggle))
253 if (creature == rabbittype && (superruntoggle && weaponactive == -1))
254 return rabbitrunninganim;
255 if (creature == wolftype && (superruntoggle))
256 return wolfrunninganim;
262 int Person::getStop()
264 if (creature == rabbittype)
266 if (creature == wolftype)
273 int Person::getLanding()
275 if (creature == rabbittype)
277 if (creature == wolftype)
284 int Person::getLandhard()
286 if (creature == rabbittype)
288 if (creature == wolftype)
289 return wolflandhardanim;
296 * Person::DoAnimations
299 SolidHitBonus(int playerid)
301 if (bonustime < 1.5 && bonus >= solidhit && bonus <= megacombo)
302 award_bonus(playerid, bonus == megacombo ? bonus : bonus + 1);
304 award_bonus(playerid, solidhit);
308 * spawns blood effects
310 void Person::DoBlood(float howmuch, int which)
312 // FIXME: should abstract out inputs
313 static int bleedxint, bleedyint;
315 //if(howmuch&&id==0)blooddimamount=1;
316 if (bloodtoggle && tutoriallevel != 1) {
317 if (bleeding <= 0 && spurt) {
319 for (int i = 0; i < 3; i++) {
320 // emit blood particles
322 if (!skeleton.free) {
324 bloodvel = DoRotation(bloodvel, ((float)(Random() % 100)) / 4, yaw + ((float)(Random() % 100)) / 4, 0) * scale;
327 bloodvel -= DoRotation(skeleton.forward * 10 * scale, ((float)(Random() % 100)) / 4, ((float)(Random() % 100)) / 4, 0);
330 bloodvel += DoRotation(jointVel(head), ((float)(Random() % 100)) / 4, yaw + ((float)(Random() % 100)) / 4, 0) * scale;
332 bloodvel += DoRotation(velocity, ((float)(Random() % 100)) / 4, ((float)(Random() % 100)) / 4, 0) * scale;
334 Sprite::MakeSprite(bloodsprite, jointPos(head) * scale + coords, bloodvel, 1, 1, 1, .05, 1);
335 Sprite::MakeSprite(bloodflamesprite, jointPos(head) * scale + coords, bloodvel, 1, 1, 1, .3, 1);
337 if (!skeleton.free) {
338 Sprite::MakeSprite(bloodsprite, DoRotation((jointPos(head) + jointPos(neck)) / 2, 0, yaw, 0)*scale + coords, bloodvel, 1, 1, 1, .05, 1);
339 Sprite::MakeSprite(bloodflamesprite, DoRotation((jointPos(head) + jointPos(neck)) / 2, 0, yaw, 0)*scale + coords, bloodvel, 1, 1, 1, .3, 1);
342 if (Random() % 2 == 0) // 50% chance
343 for (int i = 0; i < 3; i++) {
344 if (Random() % 2 != 0) {
345 // emit teeth particles
348 bloodvel -= DoRotation(skeleton.forward * 10 * scale, ((float)(Random() % 100)) / 4, ((float)(Random() % 100)) / 4, 0);
349 bloodvel += DoRotation(jointVel(head), ((float)(Random() % 100)) / 4, yaw + ((float)(Random() % 100)) / 4, 0) * scale;
352 bloodvel = DoRotation(bloodvel, ((float)(Random() % 100)) / 4, yaw + ((float)(Random() % 100)) / 4, 0) * scale;
353 bloodvel += DoRotation(velocity, ((float)(Random() % 100)) / 4, ((float)(Random() % 100)) / 4, 0) * scale;
357 Sprite::MakeSprite(splintersprite, jointPos(head) * scale + coords, bloodvel, 1, 1, 1, .05, 1);
359 Sprite::MakeSprite(splintersprite, DoRotation((jointPos(head) + jointPos(neck)) / 2, 0, yaw, 0)*scale + coords, bloodvel, 1, 1, 1, .05, 1);
361 Sprite::setLastSpriteSpecial(3); // sets it to teeth
366 // FIXME: manipulating attributes
367 bleeding = howmuch + (float)abs(Random() % 100) / 200 - .25;
370 if (creature == rabbittype)
371 while (bloodText[bleedxint * 512 * 3 + bleedyint * 3 + 0] > which + 4 || bloodText[bleedxint * 512 * 3 + bleedyint * 3 + 0] < which - 4 || bleedxint < 10 || bleedyint < 10 || bleedxint > 500 || bleedyint > 500) {
372 bleedxint = abs(Random() % 512);
373 bleedyint = abs(Random() % 512);
375 if (creature == wolftype)
376 while (wolfbloodText[bleedxint * 512 * 3 + bleedyint * 3 + 0] > which + 4 || wolfbloodText[bleedxint * 512 * 3 + bleedyint * 3 + 0] < which - 4 || bleedxint < 10 || bleedyint < 10 || bleedxint > 500 || bleedyint > 500) {
377 bleedxint = abs(Random() % 512);
378 bleedyint = abs(Random() % 512);
382 bleedy /= realtexdetail;
383 bleedx /= realtexdetail;
384 direction = abs(Random() % 2) * 2 - 1;
393 * spawns big blood effects and ???
394 * modifies character's skin texture
396 void Person::DoBloodBig(float howmuch, int which)
398 static int bleedxint, bleedyint, i, j;
400 if (howmuch && id == 0)
403 if (tutoriallevel != 1 || id == 0)
404 if (aitype != playercontrolled && howmuch > 0) {
408 // FIXME: seems to be spawning sounds by manipulating attributes... MESSY!
409 if (creature == wolftype) {
410 int i = abs(Random() % 2);
412 whichsound = snarlsound;
414 whichsound = snarl2sound;
415 envsound[numenvsounds] = coords;
416 envsoundvol[numenvsounds] = 16;
417 envsoundlife[numenvsounds] = .4;
420 if (creature == rabbittype) {
421 int i = abs(Random() % 2);
423 whichsound = rabbitpainsound;
424 if (i == 1 && howmuch >= 2)
425 whichsound = rabbitpain1sound;
426 envsound[numenvsounds] = coords;
427 envsoundvol[numenvsounds] = 16;
428 envsoundlife[numenvsounds] = .4;
430 //if(i==2)whichsound=rabbitpain2sound;
433 if (whichsound != -1)
434 emit_sound_at(whichsound, coords);
437 if (id == 0 && howmuch > 0) {
438 // FIXME: manipulating attributes
446 if (bloodtoggle && decals && tutoriallevel != 1) {
447 if (bleeding <= 0 && spurt) {
449 for (int i = 0; i < 3; i++) {
450 // emit blood particles
451 // FIXME: copypaste from above
453 if (!skeleton.free) {
455 bloodvel = DoRotation(bloodvel, ((float)(Random() % 100)) / 4, yaw + ((float)(Random() % 100)) / 4, 0) * scale;
458 bloodvel -= DoRotation(skeleton.forward * 10 * scale, ((float)(Random() % 100)) / 4, ((float)(Random() % 100)) / 4, 0);
461 bloodvel += DoRotation(jointVel(head), ((float)(Random() % 100)) / 4, yaw + ((float)(Random() % 100)) / 4, 0) * scale;
463 bloodvel += DoRotation(velocity, ((float)(Random() % 100)) / 4, ((float)(Random() % 100)) / 4, 0) * scale;
465 Sprite::MakeSprite(bloodsprite, jointPos(head) * scale + coords, bloodvel, 1, 1, 1, .05, 1);
466 Sprite::MakeSprite(bloodflamesprite, jointPos(head) * scale + coords, bloodvel, 1, 1, 1, .3, 1);
468 if (!skeleton.free) {
469 Sprite::MakeSprite(bloodsprite, DoRotation((jointPos(head) + jointPos(neck)) / 2, 0, yaw, 0)*scale + coords, bloodvel, 1, 1, 1, .05, 1);
470 Sprite::MakeSprite(bloodflamesprite, DoRotation((jointPos(head) + jointPos(neck)) / 2, 0, yaw, 0)*scale + coords, bloodvel, 1, 1, 1, .3, 1);
475 // weird texture manipulation code follows.
476 // looks like this is painting blood onto the character's skin texture
477 // FIXME: surely there's a better way
479 int offsetx = 0, offsety = 0;
481 offsety = Random() % 40;
482 offsetx = abs(Random() % 60);
484 if (which == 190 || which == 185) {
485 offsety = Random() % 40;
486 offsetx = abs(Random() % 100) - 20;
489 offsety = Random() % 10;
490 offsetx = Random() % 10;
493 offsety = Random() % 20;
494 offsetx = Random() % 20;
496 if (which == 220 || which == 215) {
506 if (creature == rabbittype)
507 for (i = 0; i < 512; i++) {
508 for (j = 0; j < 512; j++) {
509 if (bloodText[i * 512 * 3 + j * 3 + 0] <= which + 4 && bloodText[i * 512 * 3 + j * 3 + 0] >= which - 4) {
510 if (i < startx) startx = i;
511 if (j < starty) starty = j;
512 if (i > endx) endx = i;
513 if (j > endy) endy = j;
517 if (creature == wolftype)
518 for (i = 0; i < 512; i++) {
519 for (j = 0; j < 512; j++) {
520 if (wolfbloodText[i * 512 * 3 + j * 3 + 0] <= which + 4 && wolfbloodText[i * 512 * 3 + j * 3 + 0] >= which - 4) {
521 if (i < startx) startx = i;
522 if (j < starty) starty = j;
523 if (i > endx) endx = i;
524 if (j > endy) endy = j;
534 if (startx < 0) startx = 0;
535 if (starty < 0) starty = 0;
536 if (endx > 512 - 1) endx = 512 - 1;
537 if (endy > 512 - 1) endy = 512 - 1;
538 if (endx < startx) endx = startx;
539 if (endy < starty) endy = starty;
541 startx /= realtexdetail;
542 starty /= realtexdetail;
543 endx /= realtexdetail;
544 endy /= realtexdetail;
546 int texdetailint = realtexdetail;
548 if (creature == rabbittype)
549 for (i = startx; i < endx; i++) {
550 for (j = starty; j < endy; j++) {
551 if (bloodText[(i * texdetailint - offsetx) * 512 * 3 + (j * texdetailint - offsety) * 3 + 0] <= which + 4 && bloodText[(i * texdetailint - offsetx) * 512 * 3 + (j * texdetailint - offsety) * 3 + 0] >= which - 4) {
552 color = Random() % 85 + 170;
553 where = i * skeleton.skinsize * 3 + j * 3;
554 if (skeleton.skinText[where + 0] > color / 2)
555 skeleton.skinText[where + 0] = color / 2;
556 skeleton.skinText[where + 1] = 0;
557 skeleton.skinText[where + 2] = 0;
561 if (creature == wolftype)
562 for (i = startx; i < endx; i++) {
563 for (j = starty; j < endy; j++) {
564 if (wolfbloodText[(i * texdetailint - offsetx) * 512 * 3 + (j * texdetailint - offsety) * 3 + 0] <= which + 4 && wolfbloodText[(i * texdetailint - offsetx) * 512 * 3 + (j * texdetailint - offsety) * 3 + 0] >= which - 4) {
565 color = Random() % 85 + 170;
566 where = i * skeleton.skinsize * 3 + j * 3;
567 if (skeleton.skinText[where + 0] > color / 2)
568 skeleton.skinText[where + 0] = color / 2;
569 skeleton.skinText[where + 1] = 0;
570 skeleton.skinText[where + 2] = 0;
574 skeleton.drawmodel.textureptr.bind();
579 if (creature == rabbittype)
580 while (bloodText[bleedxint * 512 * 3 + bleedyint * 3 + 0] > which + 4 || bloodText[bleedxint * 512 * 3 + bleedyint * 3 + 0] < which - 4 || bleedxint < 10 || bleedyint < 10 || bleedxint > 500 || bleedyint > 500) {
581 bleedxint = abs(Random() % 512);
582 bleedyint = abs(Random() % 512);
584 if (creature == wolftype)
585 while (wolfbloodText[bleedxint * 512 * 3 + bleedyint * 3 + 0] > which + 4 || wolfbloodText[bleedxint * 512 * 3 + bleedyint * 3 + 0] < which - 4 || bleedxint < 10 || bleedyint < 10 || bleedxint > 500 || bleedyint > 500) {
586 bleedxint = abs(Random() % 512);
587 bleedyint = abs(Random() % 512);
589 bleedy = bleedxint + offsetx;
590 bleedx = bleedyint + offsety;
591 bleedy /= realtexdetail;
592 bleedx /= realtexdetail;
597 if (bleedx > skeleton.skinsize - 1)
598 bleedx = skeleton.skinsize - 1;
599 if (bleedy > skeleton.skinsize - 1)
600 bleedy = skeleton.skinsize - 1;
601 direction = abs(Random() % 2) * 2 - 1;
604 bleeding = howmuch + (float)abs(Random() % 100) / 200 - .25;
605 deathbleeding += bleeding;
606 bloodloss += bleeding * 3;
608 if (tutoriallevel != 1 && aitype != playercontrolled && bloodloss > damagetolerance * 2 / 3 && bloodloss < damagetolerance && creature == rabbittype) {
609 if (abs(Random() % 2) == 0) {
610 aitype = gethelptype;
613 aitype = attacktypecutoff;
621 * similar to DoBloodBig
623 bool Person::DoBloodBigWhere(float howmuch, int which, XYZ where)
627 static XYZ startpoint, endpoint, colpoint, movepoint;
628 static float rotationpoint;
630 static XYZ p1, p2, p3, p0;
634 float coordsx, coordsy;
637 if (bloodtoggle && decals && tutoriallevel != 1) {
640 where = DoRotation(where, 0, -yaw, 0);
648 // ray testing for a tri in the character model
649 whichtri = skeleton.drawmodel.LineCheck(&startpoint, &endpoint, &colpoint, &movepoint, &rotationpoint);
650 if (whichtri != -1) {
651 // low level geometry math
653 p1 = skeleton.drawmodel.vertex[skeleton.drawmodel.Triangles[whichtri].vertex[0]];
654 p2 = skeleton.drawmodel.vertex[skeleton.drawmodel.Triangles[whichtri].vertex[1]];
655 p3 = skeleton.drawmodel.vertex[skeleton.drawmodel.Triangles[whichtri].vertex[2]];
657 CrossProduct(p2-p1,p3-p1,&N);
658 CrossProduct(p0-p1,p3-p1,&temp);
659 s = dotproduct(&temp,&N)/findLength(&N);
660 CrossProduct(p2-p1,p1-p0,&temp);
661 t = dotproduct(&temp,&N)/findLength(&N);
664 bary.x = distsq(&p0, &p1);
665 bary.y = distsq(&p0, &p2);
666 bary.z = distsq(&p0, &p3);
668 total = bary.x + bary.y + bary.z;
677 total = bary.x + bary.y + bary.z;
683 gxx.x = skeleton.drawmodel.Triangles[whichtri].gx[0];
684 gxx.y = skeleton.drawmodel.Triangles[whichtri].gx[1];
685 gxx.z = skeleton.drawmodel.Triangles[whichtri].gx[2];
686 gyy.x = skeleton.drawmodel.Triangles[whichtri].gy[0];
687 gyy.y = skeleton.drawmodel.Triangles[whichtri].gy[1];
688 gyy.z = skeleton.drawmodel.Triangles[whichtri].gy[2];
689 coordsx = skeleton.drawmodel.Triangles[whichtri].gx[0] * bary.x + skeleton.drawmodel.Triangles[whichtri].gx[1] * bary.y + skeleton.drawmodel.Triangles[whichtri].gx[2] * bary.z;
690 coordsy = skeleton.drawmodel.Triangles[whichtri].gy[0] * bary.x + skeleton.drawmodel.Triangles[whichtri].gy[1] * bary.y + skeleton.drawmodel.Triangles[whichtri].gy[2] * bary.z;
692 //coordsx=skeleton.drawmodel.Triangles[whichtri].gx[1];
693 //coordsy=skeleton.drawmodel.Triangles[whichtri].gy[1];
695 if (bleeding <= 0 && spurt) {
697 for (int i = 0; i < 3; i++) {
698 // emit blood particles
699 // FIXME: more copypaste code
701 if (!skeleton.free) {
703 bloodvel = DoRotation(bloodvel, ((float)(Random() % 100)) / 4, yaw + ((float)(Random() % 100)) / 4, 0) * scale;
706 bloodvel -= DoRotation(skeleton.forward * 10 * scale, ((float)(Random() % 100)) / 4, ((float)(Random() % 100)) / 4, 0);
709 bloodvel += DoRotation(jointVel(head), ((float)(Random() % 100)) / 4, yaw + ((float)(Random() % 100)) / 4, 0) * scale;
711 bloodvel += DoRotation(velocity, ((float)(Random() % 100)) / 4, ((float)(Random() % 100)) / 4, 0) * scale;
713 Sprite::MakeSprite(bloodsprite, jointPos(head) * scale + coords, bloodvel, 1, 1, 1, .05, 1);
714 Sprite::MakeSprite(bloodflamesprite, jointPos(head) * scale + coords, bloodvel, 1, 1, 1, .3, 1);
716 if (!skeleton.free) {
717 Sprite::MakeSprite(bloodsprite, DoRotation((jointPos(head) + jointPos(neck)) / 2, 0, yaw, 0)*scale + coords, bloodvel, 1, 1, 1, .05, 1);
718 Sprite::MakeSprite(bloodflamesprite, DoRotation((jointPos(head) + jointPos(neck)) / 2, 0, yaw, 0)*scale + coords, bloodvel, 1, 1, 1, .3, 1);
723 // texture manipulation follows
725 int offsetx = 0, offsety = 0;
728 offsetx=abs(Random()%120);
730 if(which==220||which==215){
732 offsetx=abs(Random()%80);
735 offsetx = (1 + coordsy) * 512 - 291;
736 offsety = coordsx * 512 - 437;
743 if (creature == rabbittype)
744 for (i = 0; i < 512; i++) {
745 for (j = 0; j < 512; j++) {
746 if (bloodText[i * 512 * 3 + j * 3 + 0] <= which + 4 && bloodText[i * 512 * 3 + j * 3 + 0] >= which - 4) {
747 if (i < startx) startx = i;
748 if (j < starty) starty = j;
749 if (i > endx) endx = i;
750 if (j > endy) endy = j;
754 if (creature == wolftype)
755 for (i = 0; i < 512; i++) {
756 for (j = 0; j < 512; j++) {
757 if (wolfbloodText[i * 512 * 3 + j * 3 + 0] <= which + 4 && wolfbloodText[i * 512 * 3 + j * 3 + 0] >= which - 4) {
758 if (i < startx) startx = i;
759 if (j < starty) starty = j;
760 if (i > endx) endx = i;
761 if (j > endy) endy = j;
770 if (startx < 0) startx = 0;
771 if (starty < 0) starty = 0;
772 if (endx > 512 - 1) endx = 512 - 1;
773 if (endy > 512 - 1) endy = 512 - 1;
774 if (endx < startx) endx = startx;
775 if (endy < starty) endy = starty;
777 startx /= realtexdetail;
778 starty /= realtexdetail;
779 endx /= realtexdetail;
780 endy /= realtexdetail;
782 int texdetailint = realtexdetail;
784 if (creature == rabbittype)
785 for (i = startx; i < endx; i++) {
786 for (j = starty; j < endy; j++) {
787 if (bloodText[(i * texdetailint - offsetx) * 512 * 3 + (j * texdetailint - offsety) * 3 + 0] <= which + 4 && bloodText[(i * texdetailint - offsetx) * 512 * 3 + (j * texdetailint - offsety) * 3 + 0] >= which - 4) {
788 color = Random() % 85 + 170;
789 where = i * skeleton.skinsize * 3 + j * 3;
790 if (skeleton.skinText[where + 0] > color / 2)
791 skeleton.skinText[where + 0] = color / 2;
792 skeleton.skinText[where + 1] = 0;
793 skeleton.skinText[where + 2] = 0;
794 } else if (bloodText[(i * texdetailint - offsetx) * 512 * 3 + (j * texdetailint - offsety) * 3 + 0] <= 160 + 4 && bloodText[(i * texdetailint - offsetx) * 512 * 3 + (j * texdetailint - offsety) * 3 + 0] >= 160 - 4) {
795 color = Random() % 85 + 170;
796 where = i * skeleton.skinsize * 3 + j * 3;
797 if (skeleton.skinText[where + 0] > color / 2)
798 skeleton.skinText[where + 0] = color / 2;
799 skeleton.skinText[where + 1] = 0;
800 skeleton.skinText[where + 2] = 0;
804 if (creature == wolftype)
805 for (i = startx; i < endx; i++) {
806 for (j = starty; j < endy; j++) {
807 if (wolfbloodText[(i * texdetailint - offsetx) * 512 * 3 + (j * texdetailint - offsety) * 3 + 0] <= which + 4 && wolfbloodText[(i * texdetailint - offsetx) * 512 * 3 + (j * texdetailint - offsety) * 3 + 0] >= which - 4) {
808 color = Random() % 85 + 170;
809 where = i * skeleton.skinsize * 3 + j * 3;
810 if (skeleton.skinText[where + 0] > color / 2)
811 skeleton.skinText[where + 0] = color / 2;
812 skeleton.skinText[where + 1] = 0;
813 skeleton.skinText[where + 2] = 0;
814 } else if (wolfbloodText[(i * texdetailint - offsetx) * 512 * 3 + (j * texdetailint - offsety) * 3 + 0] <= 160 + 4 && wolfbloodText[(i * texdetailint - offsetx) * 512 * 3 + (j * texdetailint - offsety) * 3 + 0] >= 160 - 4) {
815 color = Random() % 85 + 170;
816 where = i * skeleton.skinsize * 3 + j * 3;
817 if (skeleton.skinText[where + 0] > color / 2)
818 skeleton.skinText[where + 0] = color / 2;
819 skeleton.skinText[where + 1] = 0;
820 skeleton.skinText[where + 2] = 0;
824 skeleton.drawmodel.textureptr.bind();
827 bleedy = (1 + coordsy) * 512;
828 bleedx = coordsx * 512;
829 bleedy /= realtexdetail;
830 bleedx /= realtexdetail;
835 if (bleedx > skeleton.skinsize - 1)
836 bleedx = skeleton.skinsize - 1;
837 if (bleedy > skeleton.skinsize - 1)
838 bleedy = skeleton.skinsize - 1;
839 direction = abs(Random() % 2) * 2 - 1;
844 bleeding = howmuch + (float)abs(Random() % 100) / 200 - .25;
845 deathbleeding += bleeding;
846 bloodloss += bleeding * 3;
848 if (tutoriallevel != 1 && aitype != playercontrolled && bloodloss > damagetolerance * 2 / 3 && bloodloss < damagetolerance && creature == rabbittype) {
849 if (abs(Random() % 2) == 0) {
850 aitype = gethelptype;
853 aitype = attacktypecutoff;
864 * guessing this performs a reversal
866 void Person::Reverse()
868 if (!((victim->aitype == playercontrolled
870 || staggerdelay <= 0)
871 && victim->animTarget != jumpupanim
872 && victim->animTarget != jumpdownanim
873 && (tutoriallevel != 1 || cananger)
877 if (normaldotproduct (victim->facing, victim->coords - coords) > 0
878 && (victim->id != 0 || difficulty >= 2)
879 && (creature != wolftype || victim->creature == wolftype))
882 if (animTarget == sweepanim) {
883 animTarget = sweepreversedanim;
884 animCurrent = sweepreversedanim;
885 victim->animCurrent = sweepreversalanim;
886 victim->animTarget = sweepreversalanim;
888 if (animTarget == spinkickanim) {
889 animTarget = spinkickreversedanim;
890 animCurrent = spinkickreversedanim;
891 victim->animCurrent = spinkickreversalanim;
892 victim->animTarget = spinkickreversalanim;
894 if (animTarget == upunchanim || animTarget == rabbittacklinganim) {
895 if (animTarget == rabbittacklinganim) {
898 victim->frameCurrent = 6;
899 victim->frameTarget = 7;
901 animTarget = upunchreversedanim;
902 animCurrent = upunchreversedanim;
903 victim->animCurrent = upunchreversalanim;
904 victim->animTarget = upunchreversalanim;
906 if (animTarget == staffhitanim && distsq(&victim->coords, &coords) < 2 && ((victim->id == 0 && victim->crouchkeydown) || Random() % 4 == 0)) {
907 if (victim->weaponactive != -1) {
908 victim->throwtogglekeydown = 1;
909 weapons[victim->weaponids[0]].owner = -1;
910 weapons[victim->weaponids[0]].velocity = victim->velocity * .2;
911 if (weapons[victim->weaponids[0]].velocity.x == 0)
912 weapons[victim->weaponids[0]].velocity.x = .1;
913 weapons[victim->weaponids[0]].tipvelocity = weapons[victim->weaponids[0]].velocity;
914 weapons[victim->weaponids[0]].missed = 1;
915 weapons[victim->weaponids[0]].freetime = 0;
916 weapons[victim->weaponids[0]].firstfree = 1;
917 weapons[victim->weaponids[0]].physics = 1;
918 victim->num_weapons--;
919 if (victim->num_weapons) {
920 victim->weaponids[0] = victim->weaponids[victim->num_weapons];
921 if (victim->weaponstuck == victim->num_weapons)
922 victim->weaponstuck = 0;
925 victim->weaponactive = -1;
926 for (int j = 0; j < Person::players.size(); j++) {
927 Person::players[j]->wentforweapon = 0;
931 animTarget = staffhitreversedanim;
932 animCurrent = staffhitreversedanim;
933 victim->animCurrent = staffhitreversalanim;
934 victim->animTarget = staffhitreversalanim;
936 if (animTarget == staffspinhitanim && distsq(&victim->coords, &coords) < 2 && ((victim->id == 0 && victim->crouchkeydown) || Random() % 2 == 0)) {
937 if (victim->weaponactive != -1) {
938 victim->throwtogglekeydown = 1;
939 weapons[victim->weaponids[0]].owner = -1;
940 weapons[victim->weaponids[0]].velocity = victim->velocity * .2;
941 if (weapons[victim->weaponids[0]].velocity.x == 0)
942 weapons[victim->weaponids[0]].velocity.x = .1;
943 weapons[victim->weaponids[0]].tipvelocity = weapons[victim->weaponids[0]].velocity;
944 weapons[victim->weaponids[0]].missed = 1;
945 weapons[victim->weaponids[0]].freetime = 0;
946 weapons[victim->weaponids[0]].firstfree = 1;
947 weapons[victim->weaponids[0]].physics = 1;
948 victim->num_weapons--;
949 if (victim->num_weapons) {
950 victim->weaponids[0] = victim->weaponids[victim->num_weapons];
951 if (victim->weaponstuck == victim->num_weapons)
952 victim->weaponstuck = 0;
955 victim->weaponactive = -1;
956 for (int j = 0; j < Person::players.size(); j++) {
957 Person::players[j]->wentforweapon = 0;
960 animTarget = staffspinhitreversedanim;
961 animCurrent = staffspinhitreversedanim;
962 victim->animCurrent = staffspinhitreversalanim;
963 victim->animTarget = staffspinhitreversalanim;
965 if (animTarget == swordslashanim && distsq(&victim->coords, &coords) < 2 && ((victim->id == 0 && victim->crouchkeydown) || Random() % 4 == 0)) {
966 if (victim->weaponactive != -1) {
967 victim->throwtogglekeydown = 1;
968 weapons[victim->weaponids[0]].owner = -1;
969 weapons[victim->weaponids[0]].velocity = victim->velocity * .2;
970 if (weapons[victim->weaponids[0]].velocity.x == 0)
971 weapons[victim->weaponids[0]].velocity.x = .1;
972 weapons[victim->weaponids[0]].tipvelocity = weapons[victim->weaponids[0]].velocity;
973 weapons[victim->weaponids[0]].missed = 1;
974 weapons[victim->weaponids[0]].freetime = 0;
975 weapons[victim->weaponids[0]].firstfree = 1;
976 weapons[victim->weaponids[0]].physics = 1;
977 victim->num_weapons--;
978 if (victim->num_weapons) {
979 victim->weaponids[0] = victim->weaponids[victim->num_weapons];
980 if (victim->weaponstuck == victim->num_weapons)
981 victim->weaponstuck = 0;
984 victim->weaponactive = -1;
985 for (int j = 0; j < Person::players.size(); j++) {
986 Person::players[j]->wentforweapon = 0;
989 animTarget = swordslashreversedanim;
990 animCurrent = swordslashreversedanim;
991 victim->animCurrent = swordslashreversalanim;
992 victim->animTarget = swordslashreversalanim;
994 if (animTarget == knifeslashstartanim && distsq(&victim->coords, &coords) < 2 && (victim->id == 0 || Random() % 4 == 0)) {
995 if (victim->weaponactive != -1) {
996 victim->throwtogglekeydown = 1;
997 weapons[victim->weaponids[0]].owner = -1;
998 weapons[victim->weaponids[0]].velocity = victim->velocity * .2;
999 if (weapons[victim->weaponids[0]].velocity.x == 0)
1000 weapons[victim->weaponids[0]].velocity.x = .1;
1001 weapons[victim->weaponids[0]].tipvelocity = weapons[victim->weaponids[0]].velocity;
1002 weapons[victim->weaponids[0]].missed = 1;
1003 weapons[victim->weaponids[0]].freetime = 0;
1004 weapons[victim->weaponids[0]].firstfree = 1;
1005 weapons[victim->weaponids[0]].physics = 1;
1006 victim->num_weapons--;
1007 if (victim->num_weapons) {
1008 victim->weaponids[0] = victim->weaponids[victim->num_weapons];
1009 if (victim->weaponstuck == victim->num_weapons)
1010 victim->weaponstuck = 0;
1013 victim->weaponactive = -1;
1014 for (int j = 0; j < Person::players.size(); j++) {
1015 Person::players[j]->wentforweapon = 0;
1018 animTarget = knifeslashreversedanim;
1019 animCurrent = knifeslashreversedanim;
1020 victim->animCurrent = knifeslashreversalanim;
1021 victim->animTarget = knifeslashreversalanim;
1023 if (animTarget != knifeslashstartanim && animTarget != staffhitanim && animTarget != staffspinhitanim && animTarget != winduppunchanim && animTarget != wolfslapanim && animTarget != swordslashanim && animTarget != swordslashanim) {
1024 victim->targettilt2 = targettilt2;
1025 victim->frameCurrent = frameCurrent;
1026 victim->frameTarget = frameTarget;
1027 victim->target = target;
1028 victim->velocity = 0;
1029 victim->oldcoords = victim->coords;
1030 victim->coords = coords;
1031 victim->targetyaw = targetyaw;
1032 victim->yaw = targetyaw;
1033 victim->victim = this->shared_from_this();
1035 if (animTarget == winduppunchanim) {
1036 animTarget = winduppunchblockedanim;
1037 victim->animTarget = blockhighleftanim;
1038 victim->frameTarget = 1;
1039 victim->target = .5;
1040 victim->victim = this->shared_from_this();
1041 victim->targetyaw = targetyaw + 180;
1043 if (animTarget == wolfslapanim) {
1044 animTarget = winduppunchblockedanim;
1045 victim->animTarget = blockhighleftanim;
1046 victim->frameTarget = 1;
1047 victim->target = .5;
1048 victim->victim = this->shared_from_this();
1049 victim->targetyaw = targetyaw + 180;
1051 if ((animTarget == swordslashanim || animTarget == staffhitanim || animTarget == staffspinhitanim) && victim->weaponactive != -1) {
1052 animTarget = swordslashparriedanim;
1053 parriedrecently = .4;
1054 victim->parriedrecently = 0;
1055 victim->animTarget = swordslashparryanim;
1056 victim->frameTarget = 1;
1057 victim->target = .5;
1058 victim->victim = this->shared_from_this();
1059 victim->targetyaw = targetyaw + 180;
1061 if (abs(Random() % 20) == 0 || weapons[victim->weaponids[victim->weaponactive]].getType() == knife) {
1062 if (victim->weaponactive != -1) {
1063 if (weapons[victim->weaponids[0]].getType() == staff || weapons[weaponids[0]].getType() == staff) {
1064 if (weapons[victim->weaponids[0]].getType() == staff)
1065 weapons[victim->weaponids[0]].damage += .2 + float(abs(Random() % 100) - 50) / 250;
1066 if (weapons[weaponids[0]].getType() == staff)
1067 weapons[weaponids[0]].damage += .2 + float(abs(Random() % 100) - 50) / 250;
1068 emit_sound_at(swordstaffsound, victim->coords);
1070 emit_sound_at(metalhitsound, victim->coords);
1074 victim->Puff(righthand);
1076 victim->frameTarget = 0;
1077 victim->animTarget = staggerbackhighanim;
1078 victim->targetyaw = targetyaw + 180;
1080 weapons[victim->weaponids[0]].owner = -1;
1081 aim = DoRotation(facing, 0, 90, 0) * 21;
1083 weapons[victim->weaponids[0]].velocity = aim * -.2;
1084 weapons[victim->weaponids[0]].tipvelocity = aim;
1085 weapons[victim->weaponids[0]].missed = 1;
1086 weapons[victim->weaponids[0]].hitsomething = 0;
1087 weapons[victim->weaponids[0]].freetime = 0;
1088 weapons[victim->weaponids[0]].firstfree = 1;
1089 weapons[victim->weaponids[0]].physics = 1;
1090 victim->num_weapons--;
1091 if (victim->num_weapons) {
1092 victim->weaponids[0] = victim->weaponids[num_weapons];
1093 if (victim->weaponstuck == victim->num_weapons)
1094 victim->weaponstuck = 0;
1096 victim->weaponactive = -1;
1097 for (int i = 0; i < Person::players.size(); i++) {
1098 Person::players[i]->wentforweapon = 0;
1102 if (abs(Random() % 20) == 0) {
1103 if (weaponactive != -1) {
1104 if (weapons[victim->weaponids[0]].getType() == staff || weapons[weaponids[0]].getType() == staff) {
1105 if (weapons[victim->weaponids[0]].getType() == staff)
1106 weapons[victim->weaponids[0]].damage += .2 + float(abs(Random() % 100) - 50) / 250;
1107 if (weapons[weaponids[0]].getType() == staff)
1108 weapons[weaponids[0]].damage += .2 + float(abs(Random() % 100) - 50) / 250;
1110 emit_sound_at(swordstaffsound, coords);
1112 emit_sound_at(metalhitsound, coords);
1120 animTarget = staggerbackhighanim;
1121 targetyaw = targetyaw + 180;
1123 weapons[weaponids[0]].owner = -1;
1124 aim = DoRotation(facing, 0, 90, 0) * 21;
1126 weapons[weaponids[0]].velocity = aim * -.2;
1127 weapons[weaponids[0]].tipvelocity = aim;
1128 weapons[weaponids[0]].hitsomething = 0;
1129 weapons[weaponids[0]].missed = 1;
1130 weapons[weaponids[0]].freetime = 0;
1131 weapons[weaponids[0]].firstfree = 1;
1132 weapons[weaponids[0]].physics = 1;
1135 weaponids[0] = weaponids[num_weapons];
1136 if (weaponstuck == num_weapons)
1140 for (int i = 0; i < Person::players.size(); i++) {
1141 Person::players[i]->wentforweapon = 0;
1148 if (animTarget == knifeslashstartanim || animTarget == swordslashanim || animTarget == staffhitanim || animTarget == staffspinhitanim) {
1149 if ((animTarget != staffhitanim && animTarget != staffspinhitanim) || distsq(&coords, &victim->coords) > .2) {
1150 victim->animTarget = dodgebackanim;
1151 victim->frameTarget = 0;
1155 rotatetarget = coords - victim->coords;
1156 Normalise(&rotatetarget);
1157 victim->targetyaw = -asin(0 - rotatetarget.x);
1158 victim->targetyaw *= 360 / 6.28;
1159 if (rotatetarget.z < 0)
1160 victim->targetyaw = 180 - victim->targetyaw;
1162 victim->targettilt2 = -asin(rotatetarget.y) * 360 / 6.28; //*-70;
1164 victim->lastattack3 = victim->lastattack2;
1165 victim->lastattack2 = victim->lastattack;
1166 victim->lastattack = victim->animTarget;
1168 victim->animTarget = sweepanim;
1169 victim->frameTarget = 0;
1173 rotatetarget = coords - victim->coords;
1174 Normalise(&rotatetarget);
1175 victim->targetyaw = -asin(0 - rotatetarget.x);
1176 victim->targetyaw *= 360 / 6.28;
1177 if (rotatetarget.z < 0)
1178 victim->targetyaw = 180 - victim->targetyaw;
1180 victim->targettilt2 = -asin(rotatetarget.y) * 360 / 6.28; //*-70;
1182 victim->lastattack3 = victim->lastattack2;
1183 victim->lastattack2 = victim->lastattack;
1184 victim->lastattack = victim->animTarget;
1189 victim->velocity = 0;
1191 if (aitype != playercontrolled)
1193 if (aitype != playercontrolled && Random() % 3 == 0 && escapednum < 2 && difficulty == 2)
1195 if (aitype != playercontrolled && Random() % 5 == 0 && escapednum < 2 && difficulty == 1)
1197 if (aitype != playercontrolled && Random() % 10 == 0 && escapednum < 2 && difficulty == 0)
1200 if (victim->id == 0 && animation[victim->animTarget].attack == reversal)
1207 void Person::DoDamage(float howmuch)
1209 // subtract health (temporary?)
1210 if (tutoriallevel != 1)
1211 damage += howmuch / power;
1214 damagedealt += howmuch / power;
1216 damagetaken += howmuch / power;
1219 if (id == 0 && (bonus == solidhit || bonus == twoxcombo || bonus == threexcombo || bonus == fourxcombo || bonus == megacombo))
1222 if (tutoriallevel != 1)
1223 permanentdamage += howmuch / 2 / power;
1224 if (tutoriallevel != 1)
1225 superpermanentdamage += howmuch / 4 / power;
1227 if (permanentdamage > damagetolerance / 2 && permanentdamage - howmuch < damagetolerance / 2 && Random() % 2)
1229 if ((permanentdamage > damagetolerance * .8 && Random() % 2 && !deathbleeding) || spurt)
1233 camerashake += howmuch / 100;
1234 if (id == 0 && ((howmuch > 50 && damage > damagetolerance / 2)))
1235 blackout = damage / damagetolerance;
1240 if (aitype == passivetype && damage < damagetolerance && ((tutoriallevel != 1 || cananger) && hostile))
1241 aitype = attacktypecutoff;
1242 if (tutoriallevel != 1 && aitype != playercontrolled && damage < damagetolerance && damage > damagetolerance * 2 / 3 && creature == rabbittype) {
1243 if (abs(Random() % 2) == 0) {
1244 aitype = gethelptype;
1247 aitype = attacktypecutoff;
1251 if (howmuch > damagetolerance * 50 && skeleton.free != 2) {
1254 for (int i = 0; i < skeleton.num_joints; i++) {
1256 flatvelocity2 = velocity;
1258 flatvelocity2 = skeleton.joints[i].velocity;
1260 flatfacing2 = DoRotation(DoRotation(DoRotation(skeleton.joints[i].position, 0, 0, tilt), tilt2, 0, 0), 0, yaw, 0) * scale + coords;
1262 flatfacing2 = skeleton.joints[i].position * scale + coords;
1263 flatvelocity2.x += (float)(abs(Random() % 100) - 50) / 10;
1264 flatvelocity2.y += (float)(abs(Random() % 100) - 50) / 10;
1265 flatvelocity2.z += (float)(abs(Random() % 100) - 50) / 10;
1266 Sprite::MakeSprite(bloodflamesprite, flatfacing2, flatvelocity2, 1, 1, 1, 3, 1);
1267 Sprite::MakeSprite(bloodsprite, flatfacing2, flatvelocity2, 1, 1, 1, .4, 1);
1268 Sprite::MakeSprite(cloudsprite, flatfacing2, flatvelocity2 * 0, .6, 0, 0, 1, .5);
1271 emit_sound_at(splattersound, coords);
1280 if (!dead && creature == wolftype) {
1281 award_bonus(0, Wolfbonus);
1288 if (tutoriallevel != 1 || id == 0)
1289 if (speechdelay <= 0 && !dead && aitype != playercontrolled) {
1290 int whichsound = -1;
1292 if (creature == wolftype) {
1293 int i = abs(Random() % 2);
1295 whichsound = snarlsound;
1297 whichsound = snarl2sound;
1298 envsound[numenvsounds] = coords;
1299 envsoundvol[numenvsounds] = 16;
1300 envsoundlife[numenvsounds] = .4;
1303 if (creature == rabbittype) {
1304 int i = abs(Random() % 2);
1306 whichsound = rabbitpainsound;
1307 if (i == 1 && damage > damagetolerance)
1308 whichsound = rabbitpain1sound;
1309 envsound[numenvsounds] = coords;
1310 envsoundvol[numenvsounds] = 16;
1311 envsoundlife[numenvsounds] = .4;
1313 //if(i==2)whichsound=rabbitpain2sound;
1316 if (whichsound != -1) {
1317 emit_sound_at(whichsound, coords);
1322 //if(permanentdamage>=damagetolerance&&howmuch<50)permanentdamage=damagetolerance-1;
1323 //if(damage>=damagetolerance&&howmuch<30&&!dead)damage=damagetolerance-1;
1327 * calculate/animate head facing direction?
1329 void Person::DoHead()
1331 static XYZ rotatearound;
1333 static float lookspeed = 500;
1335 if (!freeze && !winfreeze) {
1338 targetheadyaw = (float)((int)((0 - yaw - targetheadyaw + 180) * 100) % 36000) / 100;
1339 targetheadpitch = (float)((int)(targetheadpitch * 100) % 36000) / 100;
1341 while (targetheadyaw > 180)targetheadyaw -= 360;
1342 while (targetheadyaw < -180)targetheadyaw += 360;
1344 if (targetheadyaw > 160)
1345 targetheadpitch = targetheadpitch * -1;
1346 if (targetheadyaw < -160)
1347 targetheadpitch = targetheadpitch * -1;
1348 if (targetheadyaw > 160)
1349 targetheadyaw = targetheadyaw - 180;
1350 if (targetheadyaw < -160)
1351 targetheadyaw = targetheadyaw + 180;
1353 if (targetheadpitch > 120)
1354 targetheadpitch = 120;
1355 if (targetheadpitch < -120)
1356 targetheadpitch = -120;
1357 if (targetheadyaw > 120)
1358 targetheadyaw = 120;
1359 if (targetheadyaw < -120)
1360 targetheadyaw = -120;
1363 targetheadpitch = 0;
1365 if (targetheadyaw > 80)
1367 if (targetheadyaw < -80)
1368 targetheadyaw = -80;
1369 if (targetheadpitch > 50)
1370 targetheadpitch = 50;
1371 if (targetheadpitch < -50)
1372 targetheadpitch = -50;
1375 if (abs(headyaw - targetheadyaw) < multiplier * lookspeed)
1376 headyaw = targetheadyaw;
1377 else if (headyaw > targetheadyaw) {
1378 headyaw -= multiplier * lookspeed;
1379 } else if (headyaw < targetheadyaw) {
1380 headyaw += multiplier * lookspeed;
1383 if (abs(headpitch - targetheadpitch) < multiplier * lookspeed / 2)
1384 headpitch = targetheadpitch;
1385 else if (headpitch > targetheadpitch) {
1386 headpitch -= multiplier * lookspeed / 2;
1387 } else if (headpitch < targetheadpitch) {
1388 headpitch += multiplier * lookspeed / 2;
1391 rotatearound = jointPos(neck);
1392 jointPos(head) = rotatearound + DoRotation(jointPos(head) - rotatearound, headpitch, 0, 0);
1396 if (animTarget != bounceidleanim && animTarget != fightidleanim && animTarget != wolfidle && animTarget != knifefightidleanim && animTarget != drawrightanim && animTarget != drawleftanim && animTarget != walkanim) {
1397 facing = DoRotation(facing, headpitch * .4, 0, 0);
1398 facing = DoRotation(facing, 0, headyaw * .4, 0);
1401 if (animTarget == bounceidleanim || animTarget == fightidleanim || animTarget == wolfidle || animTarget == knifefightidleanim || animTarget == drawrightanim || animTarget == drawleftanim) {
1402 facing = DoRotation(facing, headpitch * .8, 0, 0);
1403 facing = DoRotation(facing, 0, headyaw * .8, 0);
1406 if (animTarget == walkanim) {
1407 facing = DoRotation(facing, headpitch * .6, 0, 0);
1408 facing = DoRotation(facing, 0, headyaw * .6, 0);
1411 skeleton.specialforward[0] = facing;
1412 //skeleton.specialforward[0]=DoRotation(facing,0,yaw,0);
1414 for (i = 0; i < skeleton.num_muscles; i++) {
1415 if (skeleton.muscles[i].visible && (skeleton.muscles[i].parent1->label == head || skeleton.muscles[i].parent2->label == head)) {
1416 skeleton.FindRotationMuscle(i, animTarget);
1423 * ragdolls character?
1425 void Person::RagDoll(bool checkcollision)
1430 if (!skeleton.free) {
1433 if (id == 0 && isFlip())
1440 facing = DoRotation(facing, 0, yaw, 0);
1442 skeleton.freetime = 0;
1444 skeleton.longdead = 0;
1447 skeleton.broken = 0;
1448 skeleton.spinny = 1;
1450 skeleton.freefall = 1;
1452 if (!isnormal(velocity.x)) velocity.x = 0;
1453 if (!isnormal(velocity.y)) velocity.y = 0;
1454 if (!isnormal(velocity.z)) velocity.z = 0;
1455 if (!isnormal(yaw)) yaw = 0;
1456 if (!isnormal(coords.x)) coords = 0;
1457 if (!isnormal(tilt)) tilt = 0;
1458 if (!isnormal(tilt2)) tilt2 = 0;
1460 for (i = 0; i < skeleton.num_joints; i++) {
1461 skeleton.joints[i].delay = 0;
1462 skeleton.joints[i].locked = 0;
1463 skeleton.joints[i].position = DoRotation(DoRotation(DoRotation(skeleton.joints[i].position, 0, 0, tilt), tilt2, 0, 0), 0, yaw, 0);
1464 if (!isnormal(skeleton.joints[i].position.x)) skeleton.joints[i].position = DoRotation(skeleton.joints[i].position, 0, yaw, 0);
1465 if (!isnormal(skeleton.joints[i].position.x)) skeleton.joints[i].position = skeleton.joints[i].position;
1466 if (!isnormal(skeleton.joints[i].position.x)) skeleton.joints[i].position = coords;
1467 skeleton.joints[i].position.y += .1;
1468 skeleton.joints[i].oldposition = skeleton.joints[i].position;
1469 skeleton.joints[i].realoldposition = skeleton.joints[i].position * scale + coords;
1472 for (i = 0; i < skeleton.num_joints; i++) {
1473 skeleton.joints[i].velocity = 0;
1474 skeleton.joints[i].velchange = 0;
1476 skeleton.DoConstraints(&coords, &scale);
1477 if (animation[animCurrent].height == lowheight || animation[animTarget].height == lowheight) {
1478 skeleton.DoConstraints(&coords, &scale);
1479 skeleton.DoConstraints(&coords, &scale);
1480 skeleton.DoConstraints(&coords, &scale);
1481 skeleton.DoConstraints(&coords, &scale);
1484 speed = animation[animTarget].speed[frameTarget] * 2;
1485 if (animation[animCurrent].speed[frameCurrent] > animation[animTarget].speed[frameTarget]) {
1486 speed = animation[animCurrent].speed[frameCurrent] * 2;
1489 speed = transspeed * 2;
1493 for (i = 0; i < skeleton.num_joints; i++) {
1494 if ((animation[animCurrent].attack != reversed || animCurrent == swordslashreversedanim) && animCurrent != rabbitkickanim && !isLanding() && !wasLanding() && animation[animCurrent].height == animation[animTarget].height)
1495 skeleton.joints[i].velocity = velocity / scale + facing * 5 + DoRotation(DoRotation(DoRotation((animation[animTarget].position[i][frameTarget] - animation[animCurrent].position[i][frameCurrent]) * speed, 0, 0, tilt), tilt2, 0, 0), 0, yaw, 0);
1497 skeleton.joints[i].velocity = velocity / scale + facing * 5;
1498 change.x = (float)(Random() % 100) / 100;
1499 change.y = (float)(Random() % 100) / 100;
1500 change.z = (float)(Random() % 100) / 100;
1501 skeleton.joints[i].velocity += change;
1502 skeleton.joints[abs(Random() % skeleton.num_joints)].velocity -= change;
1504 change.x = (float)(Random() % 100) / 100;
1505 change.y = (float)(Random() % 100) / 100;
1506 change.z = (float)(Random() % 100) / 100;
1507 skeleton.joints[i].velchange += change;
1508 skeleton.joints[abs(Random() % skeleton.num_joints)].velchange -= change;
1511 if (checkcollision) {
1518 for (j = 0; j < skeleton.num_joints; j++) {
1519 average += skeleton.joints[j].position;
1523 coords += average * scale;
1524 for (j = 0; j < skeleton.num_joints; j++) {
1525 skeleton.joints[j].position -= average;
1528 whichpatchx = coords.x / (terrain.size / subdivision * terrain.scale);
1529 whichpatchz = coords.z / (terrain.size / subdivision * terrain.scale);
1530 if (terrain.patchobjectnum[whichpatchx][whichpatchz])
1531 for (l = 0; l < terrain.patchobjectnum[whichpatchx][whichpatchz]; l++) {
1532 i = terrain.patchobjects[whichpatchx][whichpatchz][l];
1535 if (SphereCheck(&lowpoint, 3, &colpoint, &objects.position[i], &objects.yaw[i], &objects.model[i]) != -1) {
1536 coords.x = lowpoint.x;
1537 coords.z = lowpoint.z;
1546 for (i = 0; i < skeleton.num_joints; i++) {
1547 velocity += skeleton.joints[i].velocity * scale;
1549 velocity /= skeleton.num_joints;
1552 if (Random() % 2 == 0) {
1553 if (weaponactive != -1 && animTarget != rabbitkickanim && num_weapons > 0) {
1554 weapons[weaponids[0]].owner = -1;
1555 weapons[weaponids[0]].hitsomething = 0;
1556 weapons[weaponids[0]].velocity = jointVel(righthand) * scale * -.3;
1557 weapons[weaponids[0]].velocity.x += .01;
1558 weapons[weaponids[0]].tipvelocity = jointVel(righthand) * scale;
1559 weapons[weaponids[0]].missed = 1;
1560 weapons[weaponids[0]].freetime = 0;
1561 weapons[weaponids[0]].firstfree = 1;
1562 weapons[weaponids[0]].physics = 1;
1565 weaponids[0] = weaponids[num_weapons];
1566 if (weaponstuck == num_weapons)
1570 for (i = 0; i < Person::players.size(); i++) {
1571 Person::players[i]->wentforweapon = 0;
1576 animTarget = bounceidleanim;
1577 animCurrent = bounceidleanim;
1587 void Person::FootLand(int which, float opacity)
1589 static XYZ terrainlight;
1590 static XYZ footvel, footpoint;
1591 if (opacity >= 1 || skiddelay <= 0)
1595 footpoint = DoRotation(jointPos(leftfoot), 0, yaw, 0) * scale + coords;
1597 footpoint = DoRotation(jointPos(rightfoot), 0, yaw, 0) * scale + coords;
1598 //footpoint.y=coords.y;
1599 if (distsq(&footpoint, &viewer))
1600 Sprite::MakeSprite(cloudsprite, footpoint, footvel, 1, 1, 1, .5, .2 * opacity);
1601 } else if (environment == snowyenvironment && onterrain && terrain.getOpacity(coords.x, coords.z) < .2) {
1602 footvel = velocity / 5;
1606 footpoint = DoRotation(jointPos(leftfoot), 0, yaw, 0) * scale + coords;
1608 footpoint = DoRotation(jointPos(rightfoot), 0, yaw, 0) * scale + coords;
1609 footpoint.y = terrain.getHeight(footpoint.x, footpoint.z);
1610 terrainlight = terrain.getLighting(footpoint.x, footpoint.z);
1611 if (distsq(&footpoint, &viewer) < viewdistance * viewdistance / 4)
1612 Sprite::MakeSprite(cloudsprite, footpoint, footvel * .6, terrainlight.x, terrainlight.y, terrainlight.z, .5, .7 * opacity);
1613 if (opacity >= 1 || detail == 2)
1615 if (distsq(&footpoint, &viewer) < viewdistance * viewdistance / 4)
1616 terrain.MakeDecal(footprintdecal, footpoint, .2, 1 * opacity, yaw);
1617 } else if (environment == grassyenvironment && onterrain && terrain.getOpacity(coords.x, coords.z) < .2) {
1618 footvel = velocity / 5;
1622 footpoint = DoRotation(jointPos(leftfoot), 0, yaw, 0) * scale + coords;
1624 footpoint = DoRotation(jointPos(rightfoot), 0, yaw, 0) * scale + coords;
1625 footpoint.y = terrain.getHeight(footpoint.x, footpoint.z);
1626 terrainlight = terrain.getLighting(footpoint.x, footpoint.z);
1627 if (distsq(&footpoint, &viewer) < viewdistance * viewdistance / 4)
1628 Sprite::MakeSprite(cloudsprite, footpoint, footvel * .6, terrainlight.x * 90 / 255, terrainlight.y * 70 / 255, terrainlight.z * 8 / 255, .5, .5 * opacity);
1629 } else if (environment == desertenvironment && onterrain && terrain.getOpacity(coords.x, coords.z) < .2) {
1630 footvel = velocity / 5;
1634 footpoint = DoRotation(jointPos(leftfoot), 0, yaw, 0) * scale + coords;
1636 footpoint = DoRotation(jointPos(rightfoot), 0, yaw, 0) * scale + coords;
1637 footpoint.y = terrain.getHeight(footpoint.x, footpoint.z);
1638 terrainlight = terrain.getLighting(footpoint.x, footpoint.z);
1639 if (distsq(&footpoint, &viewer) < viewdistance * viewdistance / 4)
1640 Sprite::MakeSprite(cloudsprite, footpoint, footvel * .6, terrainlight.x * 190 / 255, terrainlight.y * 170 / 255, terrainlight.z * 108 / 255, .5, .7 * opacity);
1641 if (opacity >= 1 || detail == 2)
1643 if (distsq(&footpoint, &viewer) < viewdistance * viewdistance / 4)
1644 terrain.MakeDecal(footprintdecal, footpoint, .2, .25 * opacity, yaw);
1645 } else if (isLanding() || animTarget == jumpupanim || isLandhard()) {
1646 footvel = velocity / 5;
1650 footpoint = DoRotation(jointPos(leftfoot), 0, yaw, 0) * scale + coords;
1652 footpoint = DoRotation(jointPos(rightfoot), 0, yaw, 0) * scale + coords;
1653 //footpoint.y=coords.y;
1654 if (distsq(&footpoint, &viewer) < viewdistance * viewdistance / 4)
1655 Sprite::MakeSprite(cloudsprite, footpoint, footvel * .6, 1, 1, 1, .5, .2 * opacity);
1660 * make a puff effect at a body part (dust effect?)
1662 void Person::Puff(int whichlabel)
1664 static XYZ footvel, footpoint;
1667 footpoint = DoRotation(jointPos(whichlabel), 0, yaw, 0) * scale + coords;
1668 Sprite::MakeSprite(cloudimpactsprite, footpoint, footvel, 1, 1, 1, .9, .3);
1672 * I think I added this in an attempt to clean up code
1674 void Person::setAnimation(int animation)
1676 animTarget = animation;
1685 void Person::DoAnimations()
1687 if (!skeleton.free) {
1689 static float oldtarget;
1691 if (isIdle() && animCurrent != getIdle())
1692 normalsupdatedelay = 0;
1694 if (animTarget == tempanim || animCurrent == tempanim) {
1695 animation[tempanim] = tempanimation;
1697 if (animTarget == jumpupanim || animTarget == jumpdownanim || isFlip()) {
1703 vel[0] = velocity.x;
1704 vel[1] = velocity.y;
1705 vel[2] = velocity.z;
1708 OPENAL_3D_SetAttributes(channels[whooshsound], gLoc, vel);
1709 OPENAL_SetVolume(channels[whooshsound], 64 * findLength(&velocity) / 5);
1711 if (((velocity.y < -15) || (crouchkeydown && velocity.y < -8)) && abs(velocity.y) * 4 > fast_sqrt(velocity.x * velocity.x * velocity.z * velocity.z))
1713 if (!crouchkeydown && velocity.y >= -15)
1716 if ((animCurrent == jumpupanim || animTarget == jumpdownanim)/*&&velocity.y<40*/ && !isFlip() && (!isLanding() && !isLandhard()) && ((crouchkeydown && !crouchtogglekeydown))) {
1721 targfacing = DoRotation(targfacing, 0, targetyaw, 0);
1723 if (normaldotproduct(targfacing, velocity) >= -.3)
1724 animTarget = flipanim;
1726 animTarget = backflipanim;
1727 crouchtogglekeydown = 1;
1735 if (animation[animTarget].attack != reversed)
1737 if (!crouchkeydown || (isLanding() || isLandhard()) || (wasLanding() || wasLandhard())) {
1738 crouchtogglekeydown = 0;
1739 if (aitype == playercontrolled)
1742 if (!crouchtogglekeydown && animation[animTarget].attack == reversed && aitype == playercontrolled && (escapednum < 2 || reversaltrain))
1745 crouchtogglekeydown = 1;
1749 if (animation[animTarget].attack || animCurrent == getupfrombackanim || animCurrent == getupfromfrontanim) {
1751 normalsupdatedelay = 0;
1755 if (animTarget == rollanim && frameTarget == 3 && onfire) {
1757 emit_sound_at(fireendsound, coords);
1758 pause_sound(stream_firesound);
1762 if (animTarget == rabbittacklinganim && frameTarget == 1) {
1763 //if(victim->aitype==attacktypecutoff&&Random()%2==0&&victim->stunned<=0&&animation[victim->animTarget].attack==neutral&&victim->id!=0)Reverse();
1764 if (victim->aitype == attacktypecutoff && victim->stunned <= 0 && victim->surprised <= 0 && victim->id != 0)
1766 if (animTarget == rabbittacklinganim && frameTarget == 1 && !victim->isCrouch() && victim->animTarget != backhandspringanim) {
1767 if (normaldotproduct(victim->facing, facing) > 0)
1768 victim->animTarget = rabbittackledbackanim;
1770 victim->animTarget = rabbittackledfrontanim;
1771 victim->frameTarget = 2;
1774 victim->targetyaw = yaw;
1775 if (victim->aitype == gethelptype)
1776 victim->DoDamage(victim->damagetolerance - victim->damage);
1777 //victim->DoDamage(30);
1778 if (creature == wolftype) {
1780 emit_sound_at(clawslicesound, victim->coords);
1782 victim->DoBloodBig(1 / victim->armorhead, 210);
1784 award_bonus(id, TackleBonus,
1785 victim->aitype == gethelptype ? 50 : 0);
1789 if (!drawtogglekeydown && drawkeydown && (weaponactive == -1 || num_weapons == 1) && (animation[animTarget].label[frameTarget] || (animTarget != animCurrent && animCurrent == rollanim)) && num_weapons > 0 && creature != wolftype) {
1790 if (weapons[weaponids[0]].getType() == knife) {
1791 if (weaponactive == -1)
1793 else if (weaponactive == 0)
1796 if (weaponactive == -1) {
1797 emit_sound_at(knifesheathesound, coords);
1799 if (weaponactive != -1) {
1800 emit_sound_at(knifedrawsound, coords, 128);
1803 drawtogglekeydown = 1;
1806 if (tutoriallevel != 1 || id == 0)
1807 if ((animation[animTarget].label[frameTarget] && (animation[animTarget].label[frameTarget] < 5 || animation[animTarget].label[frameTarget] == 8))/*||(animTarget==rollanim&&frameTarget==animation[rollanim].numframes-1)*/) {
1810 if (terrain.getOpacity(coords.x, coords.z) < .2) {
1811 if (animation[animTarget].label[frameTarget] == 1)
1812 whichsound = footstepsound;
1814 whichsound = footstepsound2;
1815 if (animation[animTarget].label[frameTarget] == 1)
1817 if (animation[animTarget].label[frameTarget] == 2)
1819 if (animation[animTarget].label[frameTarget] == 3 && isRun()) {
1825 if (terrain.getOpacity(coords.x, coords.z) >= .2) {
1826 if (animation[animTarget].label[frameTarget] == 1)
1827 whichsound = footstepsound3;
1829 whichsound = footstepsound4;
1833 if (animation[animTarget].label[frameTarget] == 1)
1834 whichsound = footstepsound3;
1836 whichsound = footstepsound4;
1838 if (animation[animTarget].label[frameTarget] == 4 && (weaponactive == -1 || (animTarget != knifeslashstartanim && animTarget != knifethrowanim && animTarget != crouchstabanim && animTarget != swordgroundstabanim && animTarget != knifefollowanim))) {
1839 if (animation[animTarget].attack != neutral) {
1840 i = abs(Random() % 3);
1842 whichsound = lowwhooshsound;
1844 whichsound = midwhooshsound;
1846 whichsound = highwhooshsound;
1848 if (animation[animTarget].attack == neutral)
1849 whichsound = movewhooshsound;
1850 } else if (animation[animTarget].label[frameTarget] == 4)
1851 whichsound = knifeswishsound;
1852 if (animation[animTarget].label[frameTarget] == 8 && tutoriallevel != 1)
1853 whichsound = landsound2;
1855 emit_sound_at(whichsound, coords, 256.);
1858 if (whichsound == footstepsound || whichsound == footstepsound2 || whichsound == footstepsound3 || whichsound == footstepsound4) {
1859 envsound[numenvsounds] = coords;
1860 if (animTarget == wolfrunninganim || animTarget == rabbitrunninganim)
1861 envsoundvol[numenvsounds] = 15;
1863 envsoundvol[numenvsounds] = 6;
1864 envsoundlife[numenvsounds] = .4;
1868 if (animation[animTarget].label[frameTarget] == 3) {
1870 emit_sound_at(whichsound, coords, 128.);
1875 if (tutoriallevel != 1 || id == 0)
1876 if (speechdelay <= 0)
1877 if (animTarget != crouchstabanim && animTarget != swordgroundstabanim && animTarget != staffgroundsmashanim)
1878 if ((animation[animTarget].label[frameTarget] && (animation[animTarget].label[frameTarget] < 5 || animation[animTarget].label[frameTarget] == 8))/*||(animTarget==rollanim&&frameTarget==animation[rollanim].numframes-1)*/) {
1879 int whichsound = -1;
1880 if (animation[animTarget].label[frameTarget] == 4 && aitype != playercontrolled) {
1881 if (animation[animTarget].attack != neutral) {
1882 i = abs(Random() % 4);
1883 if (creature == rabbittype) {
1884 if (i == 0) whichsound = rabbitattacksound;
1885 if (i == 1) whichsound = rabbitattack2sound;
1886 if (i == 2) whichsound = rabbitattack3sound;
1887 if (i == 3) whichsound = rabbitattack4sound;
1889 if (creature == wolftype) {
1890 if (i == 0) whichsound = barksound;
1891 if (i == 1) whichsound = bark2sound;
1892 if (i == 2) whichsound = bark3sound;
1893 if (i == 3) whichsound = barkgrowlsound;
1897 //if(animation[animTarget].attack==neutral)whichsound=movewhooshsound;
1899 //else if(animation[animTarget].label[frameTarget]==4)whichsound=knifeswishsound;
1900 //if(animation[animTarget].label[frameTarget]==8)whichsound=landsound2;
1902 if (whichsound != -1) {
1903 emit_sound_at(whichsound, coords);
1909 if ((!wasLanding() && !wasLandhard()) && animCurrent != getIdle() && (isLanding() || isLandhard())) {
1915 currentoffset = targetoffset;
1916 frameTarget = frameCurrent;
1917 animCurrent = animTarget;
1920 if (animTarget == removeknifeanim && animation[animTarget].label[frameCurrent] == 5) {
1921 for (i = 0; i < weapons.size(); i++) {
1922 if (weapons[i].owner == -1)
1923 if (distsqflat(&coords, &weapons[i].position) < 4 && weaponactive == -1) {
1924 if (distsq(&coords, &weapons[i].position) >= 1) {
1925 if (weapons[i].getType() != staff) {
1926 emit_sound_at(knifedrawsound, coords, 128.);
1930 weapons[i].owner = id;
1931 if (num_weapons > 0) {
1932 weaponids[num_weapons] = weaponids[0];
1941 if (animTarget == crouchremoveknifeanim && animation[animTarget].label[frameCurrent] == 5) {
1942 for (i = 0; i < weapons.size(); i++) {
1943 bool willwork = true;
1944 if (weapons[i].owner != -1)
1945 if (Person::players[weapons[i].owner]->weaponstuck != -1)
1946 if (Person::players[weapons[i].owner]->weaponids[Person::players[weapons[i].owner]->weaponstuck] == i)
1947 if (Person::players[weapons[i].owner]->num_weapons > 1)
1949 if ((weapons[i].owner == -1) || (hasvictim && weapons[i].owner == victim->id && victim->skeleton.free))
1950 if (willwork && distsqflat(&coords, &weapons[i].position) < 3 && weaponactive == -1) {
1951 if (distsq(&coords, &weapons[i].position) < 1 || hasvictim) {
1952 bool fleshstuck = false;
1953 if (weapons[i].owner != -1)
1954 if (victim->weaponstuck != -1) {
1955 if (victim->weaponids[victim->weaponstuck] == i) {
1960 emit_sound_at(fleshstabremovesound, coords, 128.);
1962 if (weapons[i].getType() != staff) {
1963 emit_sound_at(knifedrawsound, coords, 128.);
1967 if (weapons[i].owner != -1) {
1969 victim = Person::players[weapons[i].owner];
1970 if (victim->num_weapons == 1)
1971 victim->num_weapons = 0;
1973 victim->num_weapons = 1;
1975 //victim->weaponactive=-1;
1976 victim->skeleton.longdead = 0;
1977 victim->skeleton.free = 1;
1978 victim->skeleton.broken = 0;
1980 for (int j = 0; j < victim->skeleton.num_joints; j++) {
1981 victim->skeleton.joints[j].velchange = 0;
1982 victim->skeleton.joints[j].locked = 0;
1988 Normalise(&relative);
1989 XYZ footvel, footpoint;
1991 footpoint = weapons[i].position;
1992 if (victim->weaponstuck != -1) {
1993 if (victim->weaponids[victim->weaponstuck] == i) {
1995 Sprite::MakeSprite(cloudimpactsprite, footpoint, footvel, 1, 0, 0, .8, .3);
1996 weapons[i].bloody = 2;
1997 weapons[i].blooddrip = 5;
1998 victim->weaponstuck = -1;
2001 if (victim->num_weapons > 0) {
2002 if (victim->weaponstuck != 0 && victim->weaponstuck != -1)
2003 victim->weaponstuck = 0;
2004 if (victim->weaponids[0] == i)
2005 victim->weaponids[0] = victim->weaponids[victim->num_weapons];
2008 victim->jointVel(abdomen) += relative * 6;
2009 victim->jointVel(neck) += relative * 6;
2010 victim->jointVel(rightshoulder) += relative * 6;
2011 victim->jointVel(leftshoulder) += relative * 6;
2013 weapons[i].owner = id;
2014 if (num_weapons > 0) {
2015 weaponids[num_weapons] = weaponids[0];
2024 if (animCurrent == drawleftanim && animation[animTarget].label[frameCurrent] == 5) {
2025 if (weaponactive == -1)
2027 else if (weaponactive == 0) {
2029 if (num_weapons == 2) {
2031 buffer = weaponids[0];
2032 weaponids[0] = weaponids[1];
2033 weaponids[1] = buffer;
2036 if (weaponactive == -1) {
2037 emit_sound_at(knifesheathesound, coords, 128.);
2039 if (weaponactive != -1) {
2040 emit_sound_at(knifedrawsound, coords, 128.);
2045 if ((animCurrent == walljumprightkickanim && animTarget == walljumprightkickanim) || (animCurrent == walljumpleftkickanim && animTarget == walljumpleftkickanim)) {
2046 XYZ rotatetarget = DoRotation(skeleton.forward, 0, yaw, 0);
2047 Normalise(&rotatetarget);
2048 targetyaw = -asin(0 - rotatetarget.x);
2049 targetyaw *= 360 / 6.28;
2050 if (rotatetarget.z < 0)
2051 targetyaw = 180 - targetyaw;
2053 if (animTarget == walljumprightkickanim)
2055 if (animTarget == walljumpleftkickanim)
2061 if ((animTarget == rabbitrunninganim || animTarget == wolfrunninganim) && frameTarget == 3 && (jumpkeydown || attackkeydown || id != 0))
2064 if (distsq(&victim->coords, &/*Person::players[i]->*/coords) < 5 && victim->aitype == gethelptype && (attackkeydown) && !victim->skeleton.free && victim->isRun() && victim->runninghowlong >= 1)
2069 if ((animTarget == rabbitrunninganim || animTarget == wolfrunninganim) && id == 0) {
2070 animTarget = rabbittackleanim;
2072 emit_sound_at(jumpsound, coords);
2080 targetloc = velocity;
2081 Normalise(&targetloc);
2082 targetloc += coords;
2083 for (i = 0; i < Person::players.size(); i++) {
2085 if (distsq(&targetloc, &Person::players[i]->coords) < closestdist || closestdist == 0) {
2086 closestdist = distsq(&targetloc, &Person::players[i]->coords);
2090 if (closestid != -1)
2091 if (closestdist < 5 && !Person::players[closestid]->dead && animation[Person::players[closestid]->animTarget].height != lowheight && Person::players[closestid]->animTarget != backhandspringanim) {
2093 victim = Person::players[closestid];
2094 coords = victim->coords;
2095 animCurrent = rabbittacklinganim;
2096 animTarget = rabbittacklinganim;
2100 if (coords.z != victim->coords.z || coords.x != victim->coords.x) {
2101 rotatetarget = coords - victim->coords;
2102 Normalise(&rotatetarget);
2103 targetyaw = -asin(0 - rotatetarget.x);
2104 targetyaw *= 360 / 6.28;
2105 if (rotatetarget.z < 0)
2106 targetyaw = 180 - targetyaw;
2108 if (animTarget != rabbitrunninganim) {
2109 emit_sound_at(jumpsound, coords, 128.);
2115 float damagemult = 1 * power;
2116 if (creature == wolftype)
2117 damagemult = 2.5 * power;
2119 damagemult /= victim->damagetolerance / 200;
2121 //if(onfire)damagemult=3;
2122 if ((animation[animTarget].attack == normalattack || animTarget == walljumprightkickanim || animTarget == walljumpleftkickanim) && (!feint) && (victim->skeleton.free != 2 || animTarget == killanim || animTarget == dropkickanim || animTarget == crouchstabanim || animTarget == swordgroundstabanim || animTarget == staffgroundsmashanim)) {
2123 if (animTarget == spinkickanim && animation[animTarget].label[frameCurrent] == 5) {
2124 if (distsq(&coords, &victim->coords) < (scale * 5) * (scale * 5) * 3 && 3 && animation[victim->animTarget].height != lowheight) {
2128 if (Random() % 2 || creature == wolftype) {
2131 if (creature == wolftype)
2134 if (tutoriallevel != 1) {
2135 emit_sound_at(heavyimpactsound, victim->coords, 128.);
2137 if (creature == wolftype) {
2138 emit_sound_at(clawslicesound, victim->coords, 128.);
2140 victim->DoBloodBig(2 / victim->armorhead, 175);
2144 relative = victim->coords - coords;
2146 Normalise(&relative);
2147 relative = DoRotation(relative, 0, -90, 0);
2148 for (i = 0; i < victim->skeleton.num_joints; i++) {
2149 victim->skeleton.joints[i].velocity += relative * damagemult * 40;
2151 victim->jointVel(head) += relative * damagemult * 200;
2154 victim->DoDamage(damagemult * 100 / victim->protectionhead);
2160 if (animTarget == wolfslapanim && animation[animTarget].label[frameCurrent] == 5) {
2161 if (distsq(&coords, &victim->coords) < (scale * 5) * (scale * 5) * 3 && 3 && animation[victim->animTarget].height != lowheight) {
2165 if (Random() % 2 || creature == wolftype) {
2167 if (creature == wolftype)
2170 emit_sound_at(whooshhitsound, victim->coords);
2171 if (creature == wolftype) {
2172 emit_sound_at(clawslicesound, victim->coords, 128.);
2174 victim->DoBloodBig(2, 175);
2178 relative = victim->coords - coords;
2180 Normalise(&relative);
2182 Normalise(&relative);
2183 relative = DoRotation(relative, 0, 90, 0);
2184 for (i = 0; i < victim->skeleton.num_joints; i++) {
2185 victim->skeleton.joints[i].velocity += relative * damagemult * 20;
2187 victim->jointVel(head) += relative * damagemult * 100;
2190 victim->DoDamage(damagemult * 50 / victim->protectionhead);
2194 if (animTarget == walljumprightkickanim && animation[animTarget].label[frameCurrent] == 5) {
2195 if (distsq(&coords, &victim->coords) < (scale * 5) * (scale * 5) * 3 && animation[victim->animTarget].height != lowheight) {
2201 if (tutoriallevel != 1) {
2202 emit_sound_at(heavyimpactsound, victim->coords, 160.);
2204 if (creature == wolftype) {
2205 emit_sound_at(clawslicesound, victim->coords, 128.);
2207 victim->DoBloodBig(2 / victim->armorhead, 175);
2213 Normalise(&relative);
2214 relative = DoRotation(relative, 0, -90, 0);
2215 for (i = 0; i < victim->skeleton.num_joints; i++) {
2216 victim->skeleton.joints[i].velocity += relative * damagemult * 40;
2218 victim->jointVel(head) += relative * damagemult * 200;
2221 victim->DoDamage(damagemult * 150 / victim->protectionhead);
2223 if (victim->damage > victim->damagetolerance)
2224 award_bonus(id, style);
2230 if (animTarget == walljumpleftkickanim && animation[animTarget].label[frameCurrent] == 5) {
2231 if (distsq(&coords, &victim->coords) < (scale * 5) * (scale * 5) * 3 && animation[victim->animTarget].height != lowheight) {
2237 if (tutoriallevel != 1) {
2238 emit_sound_at(heavyimpactsound, victim->coords, 160.);
2240 if (creature == wolftype) {
2241 emit_sound_at(clawslicesound, victim->coords, 128.);
2243 victim->DoBloodBig(2 / victim->armorhead, 175);
2249 Normalise(&relative);
2250 relative = DoRotation(relative, 0, 90, 0);
2251 for (i = 0; i < victim->skeleton.num_joints; i++) {
2252 victim->skeleton.joints[i].velocity += relative * damagemult * 40;
2254 victim->jointVel(head) += relative * damagemult * 200;
2257 victim->DoDamage(damagemult * 150 / victim->protectionhead);
2259 if (victim->damage > victim->damagetolerance)
2260 award_bonus(id, style);
2266 if (animTarget == blockhighleftstrikeanim && animation[animTarget].label[frameCurrent] == 5) {
2267 if (distsq(&coords, &victim->coords) < (scale * 5) * (scale * 5) * 3 && animation[victim->animTarget].height != lowheight) {
2275 emit_sound_at(whooshhitsound, victim->coords);
2278 relative = victim->coords - coords;
2280 Normalise(&relative);
2281 for (i = 0; i < victim->skeleton.num_joints; i++) {
2282 victim->skeleton.joints[i].velocity += relative * damagemult * 30;
2284 victim->jointVel(head) += relative * damagemult * 100;
2287 victim->DoDamage(damagemult * 50 / victim->protectionhead);
2291 if (animTarget == killanim && animation[animTarget].label[frameCurrent] == 8) {
2292 if (distsq(&coords, &victim->coords) < (scale * 5) * (scale * 5) * 3 && victim->dead) {
2296 emit_sound_at(whooshhitsound, victim->coords, 128.);
2298 victim->skeleton.longdead = 0;
2299 victim->skeleton.free = 1;
2300 victim->skeleton.broken = 0;
2301 victim->skeleton.spinny = 1;
2303 for (i = 0; i < victim->skeleton.num_joints; i++) {
2304 victim->skeleton.joints[i].velchange = 0;
2305 victim->skeleton.joints[i].delay = 0;
2306 victim->skeleton.joints[i].locked = 0;
2307 //victim->skeleton.joints[i].velocity=0;
2313 Normalise(&relative);
2314 for (i = 0; i < victim->skeleton.num_joints; i++) {
2315 victim->skeleton.joints[i].velocity.y = relative.y * 10;
2316 victim->skeleton.joints[i].position.y += relative.y * .3;
2317 victim->skeleton.joints[i].oldposition.y += relative.y * .3;
2318 victim->skeleton.joints[i].realoldposition.y += relative.y * .3;
2320 victim->Puff(abdomen);
2321 victim->jointVel(abdomen).y = relative.y * 400;
2325 if (animTarget == killanim && animation[animTarget].label[frameCurrent] == 5) {
2326 if (distsq(&coords, &victim->coords) < (scale * 5) * (scale * 5) * 9 && victim->dead) {
2330 if (tutoriallevel != 1) {
2331 emit_sound_at(heavyimpactsound, coords, 128.);
2334 relative = victim->coords - coords;
2336 Normalise(&relative);
2337 for (i = 0; i < victim->skeleton.num_joints; i++) {
2338 victim->skeleton.joints[i].velocity += relative * damagemult * 90;
2340 victim->Puff(abdomen);
2341 if (victim->dead != 2 && victim->permanentdamage > victim->damagetolerance - 250 && autoslomo) {
2345 victim->DoDamage(damagemult * 500 / victim->protectionhigh);
2346 victim->jointVel(abdomen) += relative * damagemult * 300;
2350 if (animTarget == dropkickanim && animation[animTarget].label[frameCurrent] == 7) {
2351 if (distsq(&coords, &victim->coords) < (scale * 5) * (scale * 5) * 9 && victim->skeleton.free) {
2355 if (tutoriallevel != 1) {
2356 emit_sound_at(thudsound, coords);
2359 victim->skeleton.longdead = 0;
2360 victim->skeleton.free = 1;
2361 victim->skeleton.broken = 0;
2362 victim->skeleton.spinny = 1;
2364 for (i = 0; i < victim->skeleton.num_joints; i++) {
2365 victim->skeleton.joints[i].velchange = 0;
2366 //victim->skeleton.joints[i].delay=0;
2367 victim->skeleton.joints[i].locked = 0;
2370 relative = victim->coords - coords;
2371 Normalise(&relative);
2373 Normalise(&relative);
2374 for (i = 0; i < victim->skeleton.num_joints; i++) {
2375 victim->skeleton.joints[i].velocity += relative * damagemult * 20;
2380 victim->Puff(abdomen);
2381 victim->DoDamage(damagemult * 20 / victim->protectionhigh);
2382 victim->jointVel(abdomen) += relative * damagemult * 200;
2391 if ((animTarget == crouchstabanim || animTarget == swordgroundstabanim) && animation[animTarget].label[frameCurrent] == 5) {
2392 //if(id==0)camerashake+=.4;
2395 if (!victim->skeleton.free)
2399 terrain.MakeDecal(blooddecalfast, (weapons[weaponids[weaponactive]].tippoint * .8 + weapons[weaponids[weaponactive]].position * .2), .08, .6, Random() % 360);
2400 emit_sound_at(knifesheathesound, coords, 128.);
2403 if (victim && hasvictim) {
2404 if (distsq(&coords, &victim->coords) < (scale * 5) * (scale * 5) * 3) {
2406 XYZ where, startpoint, endpoint, movepoint, colpoint;
2407 float rotationpoint;
2409 if (weapons[weaponids[weaponactive]].getType() == knife) {
2410 where = (weapons[weaponids[weaponactive]].tippoint * .6 + weapons[weaponids[weaponactive]].position * .4);
2411 where -= victim->coords;
2412 if (!victim->skeleton.free)
2413 where = DoRotation(where, 0, -victim->yaw, 0);
2416 startpoint.y += 100;
2420 if (weapons[weaponids[weaponactive]].getType() == sword) {
2421 where = weapons[weaponids[weaponactive]].position;
2422 where -= victim->coords;
2423 if (!victim->skeleton.free)
2424 where = DoRotation(where, 0, -victim->yaw, 0);
2426 where = weapons[weaponids[weaponactive]].tippoint;
2427 where -= victim->coords;
2428 if (!victim->skeleton.free)
2429 where = DoRotation(where, 0, -victim->yaw, 0);
2432 if (weapons[weaponids[weaponactive]].getType() == staff) {
2433 where = weapons[weaponids[weaponactive]].position;
2434 where -= victim->coords;
2435 if (!victim->skeleton.free)
2436 where = DoRotation(where, 0, -victim->yaw, 0);
2438 where = weapons[weaponids[weaponactive]].tippoint;
2439 where -= victim->coords;
2440 if (!victim->skeleton.free)
2441 where = DoRotation(where, 0, -victim->yaw, 0);
2446 whichtri = victim->skeleton.drawmodel.LineCheck(&startpoint, &endpoint, &colpoint, &movepoint, &rotationpoint);
2448 if (whichtri != -1) {
2449 if (victim->dead != 2) {
2450 victim->DoDamage(abs((victim->damagetolerance - victim->permanentdamage) * 2));
2452 award_bonus(id, FinishedBonus);
2455 weapons[weaponids[weaponactive]].bloody = 2;
2457 victim->skeleton.longdead = 0;
2458 victim->skeleton.free = 1;
2459 victim->skeleton.broken = 0;
2461 for (i = 0; i < victim->skeleton.num_joints; i++) {
2462 victim->skeleton.joints[i].velchange = 0;
2463 victim->skeleton.joints[i].locked = 0;
2464 //victim->skeleton.joints[i].velocity=0;
2466 emit_sound_at(fleshstabsound, coords, 128);
2469 if (whichtri != -1 || weapons[weaponids[weaponactive]].bloody) {
2470 weapons[weaponids[weaponactive]].blooddrip += 5;
2471 weapons[weaponids[weaponactive]].blooddripdelay = 0;
2473 if (whichtri == -1) {
2475 emit_sound_at(knifesheathesound, coords, 128.);
2481 if ((animTarget == crouchstabanim || animTarget == swordgroundstabanim) && animation[animTarget].label[frameCurrent] == 6) {
2483 emit_sound_at(knifedrawsound, coords, 128);
2486 if (victim && hasvictim) {
2487 XYZ footvel, footpoint;
2489 emit_sound_at(fleshstabremovesound, coords, 128.);
2492 footpoint = (weapons[weaponids[weaponactive]].tippoint * .8 + weapons[weaponids[weaponactive]].position * .2);
2494 if (weapons[weaponids[weaponactive]].getType() == sword) {
2495 XYZ where, startpoint, endpoint, movepoint;
2496 float rotationpoint;
2499 where = weapons[weaponids[weaponactive]].position;
2500 where -= victim->coords;
2501 if (!victim->skeleton.free)
2502 where = DoRotation(where, 0, -victim->yaw, 0);
2504 where = weapons[weaponids[weaponactive]].tippoint;
2505 where -= victim->coords;
2506 if (!victim->skeleton.free)
2507 where = DoRotation(where, 0, -victim->yaw, 0);
2512 whichtri = victim->skeleton.drawmodel.LineCheck(&startpoint, &endpoint, &footpoint, &movepoint, &rotationpoint);
2513 footpoint += victim->coords;
2515 if (whichtri == -1) {
2516 footpoint = (weapons[weaponids[weaponactive]].tippoint * .8 + weapons[weaponids[weaponactive]].position * .2);
2519 if (weapons[weaponids[weaponactive]].getType() == staff) {
2520 XYZ where, startpoint, endpoint, movepoint;
2521 float rotationpoint;
2524 where = weapons[weaponids[weaponactive]].position;
2525 where -= victim->coords;
2526 if (!victim->skeleton.free)
2527 where = DoRotation(where, 0, -victim->yaw, 0);
2529 where = weapons[weaponids[weaponactive]].tippoint;
2530 where -= victim->coords;
2531 if (!victim->skeleton.free)
2532 where = DoRotation(where, 0, -victim->yaw, 0);
2537 whichtri = victim->skeleton.drawmodel.LineCheck(&startpoint, &endpoint, &footpoint, &movepoint, &rotationpoint);
2538 footpoint += victim->coords;
2540 if (whichtri == -1) {
2541 footpoint = (weapons[weaponids[weaponactive]].tippoint * .8 + weapons[weaponids[weaponactive]].position * .2);
2544 hasvictim = victim->DoBloodBigWhere(2, 220, footpoint);
2546 if (distsq(&coords, &victim->coords) < (scale * 5) * (scale * 5) * 3) {
2547 victim->skeleton.longdead = 0;
2548 victim->skeleton.free = 1;
2549 victim->skeleton.broken = 0;
2551 for (i = 0; i < victim->skeleton.num_joints; i++) {
2552 victim->skeleton.joints[i].velchange = 0;
2553 victim->skeleton.joints[i].locked = 0;
2554 //victim->skeleton.joints[i].velocity=0;
2560 Normalise(&relative);
2561 //victim->Puff(abdomen);
2563 Sprite::MakeSprite(cloudimpactsprite, footpoint, footvel, 1, 0, 0, .8, .3);
2565 if (victim->bloodloss < victim->damagetolerance) {
2566 victim->bloodloss += 1000;
2570 victim->jointVel(abdomen) += relative * damagemult * 20;
2574 if (!hasvictim && onterrain) {
2575 weapons[weaponids[weaponactive]].bloody = 0;
2576 weapons[weaponids[weaponactive]].blooddrip = 0;
2580 if (animTarget == upunchanim && animation[animTarget].label[frameCurrent] == 5) {
2581 if (distsq(&coords, &victim->coords) < (scale * 5) * (scale * 5) * 3) {
2589 if (tutoriallevel != 1) {
2590 emit_sound_at(heavyimpactsound, victim->coords, 128);
2595 relative = victim->coords - coords;
2597 Normalise(&relative);
2598 for (i = 0; i < victim->skeleton.num_joints; i++) {
2599 victim->skeleton.joints[i].velocity = relative * 30;
2601 victim->jointVel(head) += relative * damagemult * 150;
2603 victim->frameTarget = 0;
2604 victim->animTarget = staggerbackhardanim;
2605 victim->targetyaw = targetyaw + 180;
2607 victim->stunned = 1;
2610 victim->Puff(abdomen);
2611 victim->DoDamage(damagemult * 60 / victim->protectionhigh);
2618 if (animTarget == winduppunchanim && animation[animTarget].label[frameCurrent] == 5) {
2619 if (distsq(&coords, &victim->coords) < (scale * 5) * (scale * 5) * 2) {
2623 if (victim->damage <= victim->damagetolerance - 60 && normaldotproduct(victim->facing, victim->coords - coords) < (scale * 5) * (scale * 5) * 0 && animation[victim->animTarget].height != lowheight) {
2624 if (tutoriallevel != 1) {
2625 emit_sound_at(thudsound, victim->coords);
2627 } else if (victim->damage <= victim->damagetolerance - 60 && normaldotproduct(victim->facing, victim->coords - coords) < (scale * 5) * (scale * 5) * 0 && animation[victim->animTarget].height == lowheight) {
2628 if (tutoriallevel != 1) {
2629 emit_sound_at(whooshhitsound, victim->coords);
2632 if (tutoriallevel != 1) {
2633 emit_sound_at(heavyimpactsound, victim->coords);
2637 if (victim->damage > victim->damagetolerance - 60 || normaldotproduct(victim->facing, victim->coords - coords) > 0 || animation[victim->animTarget].height == lowheight)
2640 relative = victim->coords - coords;
2642 Normalise(&relative);
2644 Normalise(&relative);
2645 for (i = 0; i < victim->skeleton.num_joints; i++) {
2646 victim->skeleton.joints[i].velocity = relative * 5;
2648 victim->jointVel(abdomen) += relative * damagemult * 400;
2650 victim->frameTarget = 0;
2651 victim->animTarget = staggerbackhardanim;
2652 victim->targetyaw = targetyaw + 180;
2654 victim->stunned = 1;
2656 victim->Puff(abdomen);
2657 victim->DoDamage(damagemult * 60 / victim->protectionhigh);
2663 if (animTarget == blockhighleftanim && animation[animTarget].label[frameCurrent] == 5) {
2664 if (distsq(&coords, &victim->coords) < (scale * 5) * (scale * 5) * 4) {
2665 if (victim->id == 0)
2667 emit_sound_at(landsound2, victim->coords);
2673 if (animTarget == swordslashparryanim && animation[animTarget].label[frameCurrent] == 5) {
2674 if (distsq(&coords, &victim->coords) < (scale * 5) * (scale * 5) * 4) {
2675 if (victim->id == 0)
2678 if (weaponactive != -1) {
2679 if (weapons[victim->weaponids[0]].getType() == staff || weapons[weaponids[0]].getType() == staff) {
2680 if (weapons[victim->weaponids[0]].getType() == staff)
2681 weapons[victim->weaponids[0]].damage += .2 + float(abs(Random() % 100) - 50) / 250;
2682 if (weapons[weaponids[0]].getType() == staff)
2683 weapons[weaponids[0]].damage += .2 + float(abs(Random() % 100) - 50) / 250;
2685 emit_sound_at(swordstaffsound, victim->coords);
2687 emit_sound_at(metalhitsound, victim->coords);
2695 if (animTarget == knifethrowanim && animation[animTarget].label[frameCurrent] == 5) {
2696 if (weaponactive != -1) {
2699 weapons[weaponids[0]].owner = -1;
2700 aim = victim->coords + DoRotation(victim->jointPos(abdomen), 0, victim->yaw, 0) * victim->scale + victim->velocity * findDistance(&victim->coords, &coords) / 50 - (coords + DoRotation(jointPos(righthand), 0, yaw, 0) * scale);
2702 /*if(victim->animTarget==jumpupanim||victim->animTarget==jumpdownanim){
2703 aim=DoRotation(aim,(float)abs(Random()%15)-7,(float)abs(Random()%15)-7,0);
2705 weapons[weaponids[0]].velocity = aim * 50;
2706 weapons[weaponids[0]].tipvelocity = aim * 50;
2707 weapons[weaponids[0]].missed = 0;
2708 weapons[weaponids[0]].hitsomething = 0;
2709 weapons[weaponids[0]].freetime = 0;
2710 weapons[weaponids[0]].firstfree = 1;
2711 weapons[weaponids[0]].physics = 0;
2714 weaponids[0] = weaponids[num_weapons];
2720 if (animTarget == knifeslashstartanim && animation[animTarget].label[frameCurrent] == 5) {
2722 if (distsq(&coords, &victim->coords) < (scale * 5) * (scale * 5) * 4.5 &&/*animation[victim->animTarget].height!=lowheight&&*/victim->animTarget != dodgebackanim && victim->animTarget != rollanim) {
2724 if (tutoriallevel != 1)
2725 victim->DoBloodBig(1.5 / victim->armorhigh, 225);
2727 award_bonus(id, Slicebonus);
2728 if (tutoriallevel != 1) {
2729 emit_sound_at(knifeslicesound, victim->coords);
2731 //victim->jointVel(abdomen)+=relative*damagemult*200;
2732 if (animation[victim->animTarget].attack && (victim->aitype != playercontrolled || victim->animTarget == knifeslashstartanim) && (victim->creature == rabbittype || victim->deathbleeding <= 0)) {
2733 if (victim->id != 0 || difficulty == 2) {
2734 victim->frameTarget = 0;
2735 victim->animTarget = staggerbackhardanim;
2736 victim->targetyaw = targetyaw + 180;
2740 victim->lowreversaldelay = 0;
2741 victim->highreversaldelay = 0;
2742 if (aitype != playercontrolled)
2743 weaponmissdelay = .6;
2745 if (tutoriallevel != 1)
2746 if (bloodtoggle && !weapons[weaponids[weaponactive]].bloody)
2747 weapons[weaponids[weaponactive]].bloody = 1;
2748 if (tutoriallevel != 1)
2749 weapons[weaponids[weaponactive]].blooddrip += 3;
2751 XYZ footvel, footpoint;
2753 if (skeleton.free) {
2754 footpoint = (victim->jointPos(abdomen) + victim->jointPos(neck)) / 2 * victim->scale + victim->coords;
2756 if (!skeleton.free) {
2757 footpoint = DoRotation((victim->jointPos(abdomen) + victim->jointPos(neck)) / 2, 0, victim->yaw, 0) * victim->scale + victim->coords;
2759 if (tutoriallevel != 1) {
2761 Sprite::MakeSprite(cloudimpactsprite, footpoint, footvel, 1, 0, 0, .6, .3);
2762 footvel = DoRotation(facing, 0, 90, 0) * .8;
2764 Sprite::MakeSprite(bloodsprite, footpoint, DoRotation(footvel * 7, (float)(Random() % 20), (float)(Random() % 20), 0), 1, 1, 1, .05, .9);
2765 Sprite::MakeSprite(bloodsprite, footpoint, DoRotation(footvel * 3, (float)(Random() % 20), (float)(Random() % 20), 0), 1, 1, 1, .05, .9);
2766 Sprite::MakeSprite(bloodflamesprite, footpoint, footvel * 5, 1, 1, 1, .2, 1);
2767 Sprite::MakeSprite(bloodflamesprite, footpoint, footvel * 2, 1, 1, 1, .2, 1);
2769 if (tutoriallevel == 1) {
2770 Sprite::MakeSprite(cloudimpactsprite, footpoint, footvel, 1, 1, 1, .6, .3);
2772 victim->DoDamage(damagemult * 0);
2775 if (animTarget == swordslashanim && animation[animTarget].label[frameCurrent] == 5 && victim->animTarget != rollanim) {
2776 if (distsq(&coords, &victim->coords) < (scale * 5) * (scale * 5) * 6.5 && victim->animTarget != dodgebackanim) {
2777 if (victim->weaponactive == -1 || normaldotproduct(victim->facing, victim->coords - coords) > 0 || (Random() % 2 == 0)) {
2778 award_bonus(id, Slashbonus);
2780 if (tutoriallevel != 1) {
2781 if (normaldotproduct(victim->facing, victim->coords - coords) < 0)
2782 victim->DoBloodBig(2 / victim->armorhigh, 190);
2784 victim->DoBloodBig(2 / victim->armorhigh, 185);
2785 victim->deathbleeding = 1;
2786 emit_sound_at(swordslicesound, victim->coords);
2788 //victim->jointVel(abdomen)+=relative*damagemult*200;
2789 if (tutoriallevel != 1) {
2790 victim->frameTarget = 0;
2791 victim->animTarget = staggerbackhardanim;
2792 victim->targetyaw = targetyaw + 180;
2796 if (tutoriallevel != 1) {
2797 if (bloodtoggle && !weapons[weaponids[weaponactive]].bloody)
2798 weapons[weaponids[weaponactive]].bloody = 1;
2799 weapons[weaponids[weaponactive]].blooddrip += 3;
2801 float bloodlossamount;
2802 bloodlossamount = 200 + abs((float)(Random() % 40)) - 20;
2803 victim->bloodloss += bloodlossamount / victim->armorhigh;
2804 //victim->bloodloss+=100*(6.5-distsq(&coords,&victim->coords));
2805 victim->DoDamage(damagemult * 0);
2807 XYZ footvel, footpoint;
2809 if (skeleton.free) {
2810 footpoint = (victim->jointPos(abdomen) + victim->jointPos(neck)) / 2 * victim->scale + victim->coords;
2812 if (!skeleton.free) {
2813 footpoint = DoRotation((victim->jointPos(abdomen) + victim->jointPos(neck)) / 2, 0, victim->yaw, 0) * victim->scale + victim->coords;
2816 Sprite::MakeSprite(cloudimpactsprite, footpoint, footvel, 1, 0, 0, .9, .3);
2817 footvel = DoRotation(facing, 0, 90, 0) * .8;
2819 Sprite::MakeSprite(bloodsprite, footpoint, DoRotation(footvel * 7, (float)(Random() % 20), (float)(Random() % 20), 0), 1, 1, 1, .05, .9);
2820 Sprite::MakeSprite(bloodsprite, footpoint, DoRotation(footvel * 3, (float)(Random() % 20), (float)(Random() % 20), 0), 1, 1, 1, .05, .9);
2821 Sprite::MakeSprite(bloodflamesprite, footpoint, footvel * 5, 1, 1, 1, .3, 1);
2822 Sprite::MakeSprite(bloodflamesprite, footpoint, footvel * 2, 1, 1, 1, .3, 1);
2825 if (victim->weaponactive != -1) {
2826 if (weapons[victim->weaponids[0]].getType() == staff || weapons[weaponids[0]].getType() == staff) {
2827 if (weapons[victim->weaponids[0]].getType() == staff)
2828 weapons[victim->weaponids[0]].damage += .2 + float(abs(Random() % 100) - 50) / 250;
2829 if (weapons[weaponids[0]].getType() == staff)
2830 weapons[weaponids[0]].damage += .2 + float(abs(Random() % 100) - 50) / 250;
2832 emit_sound_at(swordstaffsound, victim->coords);
2834 emit_sound_at(metalhitsound, victim->coords);
2840 victim->Puff(righthand);
2842 victim->frameTarget = 0;
2843 victim->animTarget = staggerbackhighanim;
2844 victim->targetyaw = targetyaw + 180;
2846 weapons[victim->weaponids[0]].owner = -1;
2847 aim = DoRotation(facing, 0, 90, 0) * 21;
2849 weapons[victim->weaponids[0]].velocity = aim * -.2;
2850 weapons[victim->weaponids[0]].tipvelocity = aim;
2851 weapons[victim->weaponids[0]].missed = 1;
2852 weapons[weaponids[0]].hitsomething = 0;
2853 weapons[victim->weaponids[0]].freetime = 0;
2854 weapons[victim->weaponids[0]].firstfree = 1;
2855 weapons[victim->weaponids[0]].physics = 1;
2856 victim->num_weapons--;
2857 if (victim->num_weapons) {
2858 victim->weaponids[0] = victim->weaponids[num_weapons];
2859 if (victim->weaponstuck == victim->num_weapons)
2860 victim->weaponstuck = 0;
2862 victim->weaponactive = -1;
2863 for (i = 0; i < Person::players.size(); i++) {
2864 Person::players[i]->wentforweapon = 0;
2871 if (animTarget == staffhitanim && animation[animTarget].label[frameCurrent] == 5 && victim->animTarget != rollanim) {
2872 if (distsq(&coords, &victim->coords) < (scale * 5) * (scale * 5) * 6.5 && victim->animTarget != dodgebackanim && victim->animTarget != sweepanim) {
2873 if (tutoriallevel != 1) {
2874 weapons[weaponids[0]].damage += .4 + float(abs(Random() % 100) - 50) / 250;
2878 if (Random() % 2 || creature == wolftype) {
2881 emit_sound_at(staffheadsound, victim->coords);
2885 relative = victim->coords - coords;
2887 Normalise(&relative);
2888 relative = DoRotation(relative, 0, 90, 0);
2890 Normalise(&relative);
2891 for (i = 0; i < victim->skeleton.num_joints; i++) {
2892 victim->skeleton.joints[i].velocity += relative * damagemult * 60;
2894 victim->jointVel(head) += relative * damagemult * 230;
2895 victim->jointVel(neck) += relative * damagemult * 230;
2898 if (tutoriallevel != 1) {
2899 victim->DoDamage(damagemult * 120 / victim->protectionhigh);
2901 award_bonus(id, solidhit, 30);
2906 if (animTarget == staffspinhitanim && animation[animTarget].label[frameCurrent] == 5 && victim->animTarget != rollanim) {
2907 if (distsq(&coords, &victim->coords) < (scale * 5) * (scale * 5) * 6.5 && victim->animTarget != dodgebackanim && victim->animTarget != sweepanim) {
2908 if (tutoriallevel != 1) {
2909 weapons[weaponids[0]].damage += .6 + float(abs(Random() % 100) - 50) / 250;
2913 if (Random() % 2 || creature == wolftype) {
2916 emit_sound_at(staffheadsound, victim->coords);
2920 relative = victim->coords - coords;
2922 Normalise(&relative);
2923 relative = DoRotation(relative, 0, -90, 0);
2924 for (i = 0; i < victim->skeleton.num_joints; i++) {
2925 victim->skeleton.joints[i].velocity += relative * damagemult * 40;
2927 victim->jointVel(head) += relative * damagemult * 220;
2928 victim->jointVel(neck) += relative * damagemult * 220;
2931 if (tutoriallevel != 1) {
2932 victim->DoDamage(damagemult * 350 / victim->protectionhead);
2934 award_bonus(id, solidhit, 60);
2939 if (animTarget == staffgroundsmashanim && animation[animTarget].label[frameCurrent] == 5) {
2940 if (distsq(&coords, &victim->coords) < (scale * 5) * (scale * 5) * 6.5) {
2942 if (tutoriallevel != 1) {
2944 weapons[weaponids[0]].damage += .4 + float(abs(Random() % 100) - 50) / 500;
2947 if (Random() % 2 || creature == wolftype) {
2950 emit_sound_at(staffbodysound, victim->coords);
2952 victim->skeleton.longdead = 0;
2953 victim->skeleton.free = 1;
2954 victim->skeleton.broken = 0;
2956 for (i = 0; i < victim->skeleton.num_joints; i++) {
2957 victim->skeleton.joints[i].velchange = 0;
2958 victim->skeleton.joints[i].locked = 0;
2959 //victim->skeleton.joints[i].velocity=0;
2965 /*relative=victim->coords-coords;
2967 Normalise(&relative);
2968 relative=DoRotation(relative,0,90,0);*/
2970 Normalise(&relative);
2971 if (!victim->dead) {
2972 for (i = 0; i < victim->skeleton.num_joints; i++) {
2973 victim->skeleton.joints[i].velocity = relative * damagemult * 40;
2976 victim->jointVel(abdomen) += relative * damagemult * 40;
2979 for (i = 0; i < victim->skeleton.num_joints; i++) {
2980 victim->skeleton.joints[i].velocity = relative * damagemult * abs(Random() % 20);
2983 //victim->jointVel(abdomen)+=relative*damagemult*20;
2985 victim->Puff(abdomen);
2986 if (tutoriallevel != 1) {
2987 victim->DoDamage(damagemult * 100 / victim->protectionhigh);
2989 if (!victim->dead) {
2990 award_bonus(id, solidhit, 40);
2996 if (animTarget == lowkickanim && animation[animTarget].label[frameCurrent] == 5) {
2997 if (distsq(&coords, &victim->coords) < (scale * 5) * (scale * 5) * 3 && animation[victim->animTarget].height != highheight) {
3002 relative = victim->coords - coords;
3004 Normalise(&relative);
3008 if (animation[victim->animTarget].height == lowheight) {
3014 for (i = 0; i < victim->skeleton.num_joints; i++) {
3015 victim->skeleton.joints[i].velocity += relative * damagemult * 40;
3017 victim->jointVel(head) += relative * damagemult * 200;
3018 if (tutoriallevel != 1) {
3019 emit_sound_at(heavyimpactsound, victim->coords, 128.);
3022 victim->DoDamage(damagemult * 100 / victim->protectionhead);
3023 if (victim->howactive == typesleeping)
3024 victim->DoDamage(damagemult * 150 / victim->protectionhead);
3025 if (creature == wolftype) {
3026 emit_sound_at(clawslicesound, victim->coords, 128.);
3028 victim->DoBloodBig(2 / victim->armorhead, 175);
3031 if (victim->damage >= victim->damagetolerance)
3033 for (i = 0; i < victim->skeleton.num_joints; i++) {
3034 victim->skeleton.joints[i].velocity += relative * damagemult * 10;
3036 victim->jointVel(abdomen) += relative * damagemult * 200;
3037 victim->frameTarget = 0;
3038 victim->animTarget = staggerbackhighanim;
3039 victim->targetyaw = targetyaw + 180;
3041 if (tutoriallevel != 1) {
3042 emit_sound_at(landsound2, victim->coords, 128.);
3044 victim->Puff(abdomen);
3045 victim->DoDamage(damagemult * 30 / victim->protectionhigh);
3046 if (creature == wolftype) {
3047 emit_sound_at(clawslicesound, victim->coords, 128.);
3049 victim->DoBloodBig(2 / victim->armorhigh, 170);
3056 if (animTarget == sweepanim && animation[animTarget].label[frameCurrent] == 5) {
3057 if ((victim->animTarget != jumpupanim) &&
3058 (distsq(&coords, &victim->coords) < (scale * 5) * (scale * 5) * 3) &&
3059 (victim != this->shared_from_this())) {
3063 if (tutoriallevel != 1) {
3064 emit_sound_at(landsound2, victim->coords, 128.);
3067 relative = victim->coords - coords;
3069 Normalise(&relative);
3071 if (animation[victim->animTarget].height == middleheight || animation[victim->animCurrent].height == middleheight || victim->damage >= victim->damagetolerance - 40) {
3074 for (i = 0; i < victim->skeleton.num_joints; i++) {
3075 victim->skeleton.joints[i].velocity += relative * damagemult * 15;
3077 relative = DoRotation(relative, 0, -90, 0);
3079 for (i = 0; i < victim->skeleton.num_joints; i++) {
3080 if (victim->skeleton.joints[i].label == leftfoot || victim->skeleton.joints[i].label == rightfoot || victim->skeleton.joints[i].label == leftankle || victim->skeleton.joints[i].label == rightankle)
3081 victim->skeleton.joints[i].velocity = relative * 80;
3083 victim->Puff(rightankle);
3084 victim->Puff(leftankle);
3085 victim->DoDamage(damagemult * 40 / victim->protectionlow);
3087 if (victim->damage >= victim->damagetolerance)
3089 for (i = 0; i < victim->skeleton.num_joints; i++) {
3090 victim->skeleton.joints[i].velocity += relative * damagemult * 10;
3092 relative = DoRotation(relative, 0, -90, 0);
3093 for (i = 0; i < victim->skeleton.num_joints; i++) {
3094 if (victim->skeleton.joints[i].label == leftfoot || victim->skeleton.joints[i].label == rightfoot || victim->skeleton.joints[i].label == leftankle || victim->skeleton.joints[i].label == rightankle)
3095 victim->skeleton.joints[i].velocity += relative * damagemult * 80;
3097 victim->jointVel(abdomen) += relative * damagemult * 200;
3098 victim->frameTarget = 0;
3099 victim->animTarget = staggerbackhighanim;
3100 victim->targetyaw = targetyaw + 180;
3102 if (tutoriallevel != 1) {
3103 emit_sound_at(landsound2, victim->coords, 128.);
3105 victim->Puff(abdomen);
3106 victim->DoDamage(damagemult * 30 / victim->protectionlow);
3114 if (animation[animTarget].attack == reversal && (!victim->feint || (victim->lastattack == victim->lastattack2 && victim->lastattack2 == victim->lastattack3 && Random() % 2) || animTarget == knifefollowanim)) {
3115 if (animTarget == spinkickreversalanim && animation[animTarget].label[frameCurrent] == 7) {
3123 if (tutoriallevel != 1) {
3124 emit_sound_at(heavyimpactsound, victim->coords, 128.);
3126 if (creature == wolftype) {
3127 emit_sound_at(clawslicesound, victim->coords, 128);
3129 victim->DoBloodBig(2 / victim->armorhigh, 170);
3133 relative = victim->coords - oldcoords;
3135 Normalise(&relative);
3136 //relative=DoRotation(relative,0,-90,0);
3137 for (i = 0; i < victim->skeleton.num_joints; i++) {
3138 victim->skeleton.joints[i].velocity += relative * damagemult * 40;
3140 victim->jointVel(abdomen) += relative * damagemult * 200;
3142 victim->Puff(abdomen);
3143 victim->DoDamage(damagemult * 150 / victim->protectionhigh);
3145 award_bonus(id, Reversal);
3148 if ((animTarget == swordslashreversalanim || animTarget == knifeslashreversalanim || animTarget == staffhitreversalanim || animTarget == staffspinhitreversalanim) && animation[animTarget].label[frameCurrent] == 5) {
3149 if (victim->weaponactive != -1 && victim->num_weapons > 0) {
3150 if (weapons[victim->weaponids[victim->weaponactive]].owner == victim->id) {
3151 weapons[victim->weaponids[victim->weaponactive]].owner = id;
3153 if (num_weapons > 0) {
3154 weaponids[num_weapons] = weaponids[victim->weaponactive];
3157 weaponids[0] = victim->weaponids[victim->weaponactive];
3158 victim->num_weapons--;
3159 if (victim->num_weapons > 0) {
3160 victim->weaponids[victim->weaponactive] = victim->weaponids[victim->num_weapons];
3161 //if(victim->weaponstuck==victim->num_weapons)victim->weaponstuck=0;
3163 victim->weaponactive = -1;
3168 if (animTarget == staffhitreversalanim && animation[animTarget].label[frameCurrent] == 5) {
3176 emit_sound_at(whooshhitsound, victim->coords, 128.);
3179 relative = victim->coords - oldcoords;
3181 Normalise(&relative);
3182 //relative=DoRotation(relative,0,-90,0);
3183 for (i = 0; i < victim->skeleton.num_joints; i++) {
3184 victim->skeleton.joints[i].velocity += relative * damagemult * 30;
3186 victim->jointVel(abdomen) += relative * damagemult * 200;
3189 victim->DoDamage(damagemult * 70 / victim->protectionhigh);
3192 if (animTarget == staffspinhitreversalanim && animation[animTarget].label[frameCurrent] == 7) {
3201 award_bonus(id, staffreversebonus);
3203 if (tutoriallevel != 1) {
3204 emit_sound_at(heavyimpactsound, victim->coords, 128.);
3207 award_bonus(id, staffreversebonus); // Huh, again?
3210 relative = victim->coords - oldcoords;
3212 Normalise(&relative);
3213 //relative=DoRotation(relative,0,-90,0);
3214 for (i = 0; i < victim->skeleton.num_joints; i++) {
3215 victim->skeleton.joints[i].velocity += relative * damagemult * 30;
3217 victim->jointVel(abdomen) += relative * damagemult * 200;
3220 victim->DoDamage(damagemult * 70 / victim->protectionhigh);
3223 if (animTarget == upunchreversalanim && animation[animTarget].label[frameCurrent] == 7) {
3229 Normalise(&relative);
3232 for (i = 0; i < victim->skeleton.num_joints; i++) {
3233 victim->skeleton.joints[i].velocity += relative * damagemult * 70;
3235 victim->jointVel(lefthand) *= .1;
3236 victim->jointVel(leftwrist) *= .2;
3237 victim->jointVel(leftelbow) *= .5;
3238 victim->jointVel(leftshoulder) *= .7;
3239 victim->jointVel(righthand) *= .1;
3240 victim->jointVel(rightwrist) *= .2;
3241 victim->jointVel(rightelbow) *= .5;
3242 victim->jointVel(rightshoulder) *= .7;
3244 victim->Puff(abdomen);
3245 victim->DoDamage(damagemult * 90 / victim->protectionhigh);
3247 award_bonus(id, Reversal);
3251 if (weaponactive != -1 || creature == wolftype)
3253 if (creature == rabbittype && weaponactive != -1)
3254 if (weapons[weaponids[0]].getType() == staff)
3257 if (weaponactive != -1) {
3258 victim->DoBloodBig(2 / victim->armorhigh, 225);
3259 emit_sound_at(knifeslicesound, victim->coords);
3260 if (bloodtoggle && !weapons[weaponids[weaponactive]].bloody)
3261 weapons[weaponids[weaponactive]].bloody = 1;
3262 weapons[weaponids[weaponactive]].blooddrip += 3;
3264 if (weaponactive == -1 && creature == wolftype) {
3266 emit_sound_at(clawslicesound, victim->coords, 128.);
3268 victim->DoBloodBig(2 / victim->armorhigh, 175);
3275 if (animTarget == swordslashreversalanim && animation[animTarget].label[frameCurrent] == 7) {
3281 Normalise(&relative);
3284 for (i = 0; i < victim->skeleton.num_joints; i++) {
3285 victim->skeleton.joints[i].velocity += relative * damagemult * 70;
3287 victim->jointVel(lefthand) *= .1 - 1;
3288 victim->jointVel(leftwrist) *= .2 - 1;
3289 victim->jointVel(leftelbow) *= .5 - 1;
3290 victim->jointVel(leftshoulder) *= .7 - 1;
3291 victim->jointVel(righthand) *= .1 - 1;
3292 victim->jointVel(rightwrist) *= .2 - 1;
3293 victim->jointVel(rightelbow) *= .5 - 1;
3294 victim->jointVel(rightshoulder) *= .7 - 1;
3296 award_bonus(id, swordreversebonus);
3299 if (hasvictim && animTarget == knifeslashreversalanim && animation[animTarget].label[frameCurrent] == 7) {
3307 if (tutoriallevel != 1) {
3308 emit_sound_at(heavyimpactsound, victim->coords, 128.);
3312 relative = victim->coords - oldcoords;
3314 Normalise(&relative);
3315 relative = DoRotation(relative, 0, -90, 0);
3316 for (i = 0; i < victim->skeleton.num_joints; i++) {
3317 victim->skeleton.joints[i].velocity += relative * damagemult * 40;
3319 victim->jointVel(abdomen) += relative * damagemult * 200;
3321 victim->Puff(abdomen);
3322 victim->DoDamage(damagemult * 30 / victim->protectionhigh);
3324 award_bonus(id, Reversal);
3327 if (hasvictim && animTarget == sneakattackanim && animation[animTarget].label[frameCurrent] == 7) {
3330 victim->skeleton.spinny = 0;
3332 relative = facing * -1;
3334 Normalise(&relative);
3335 if (victim->id == 0)
3337 for (i = 0; i < victim->skeleton.num_joints; i++) {
3338 victim->skeleton.joints[i].velocity += relative * damagemult * 40;
3340 //victim->DoDamage(1000);
3341 victim->damage = victim->damagetolerance;
3342 victim->permanentdamage = victim->damagetolerance - 1;
3345 if (weaponactive != -1 || creature == wolftype)
3347 if (creature == rabbittype && weaponactive != -1)
3348 if (weapons[weaponids[0]].getType() == staff)
3351 if (weaponactive != -1) {
3352 victim->DoBloodBig(200, 225);
3353 emit_sound_at(knifeslicesound, victim->coords);
3355 weapons[weaponids[weaponactive]].bloody = 2;
3356 weapons[weaponids[weaponactive]].blooddrip += 5;
3359 if (creature == wolftype && weaponactive == -1) {
3360 emit_sound_at(clawslicesound, victim->coords, 128.);
3362 victim->DoBloodBig(2, 175);
3365 award_bonus(id, spinecrusher);
3368 if (hasvictim && (animTarget == knifefollowanim || animTarget == knifesneakattackanim) && animation[animTarget].label[frameCurrent] == 5) {
3369 if (weaponactive != -1 && victim->bloodloss < victim->damagetolerance) {
3371 if (animTarget == knifefollowanim)
3372 victim->DoBloodBig(200, 210);
3373 if (animTarget == knifesneakattackanim) {
3374 /*victim->DoBloodBig(200,195);
3379 bloodvel=DoRotation(bloodvel,((float)(Random()%100))/4,yaw+((float)(Random()%100))/4,0)*scale;
3380 Sprite::MakeSprite(bloodsprite, DoRotation(jointPos(neck),0,yaw,0)*scale+coords,bloodvel, 1,1,1, .05, 1);
3382 XYZ footvel, footpoint;
3384 footpoint = weapons[weaponids[0]].tippoint;
3386 Sprite::MakeSprite(cloudimpactsprite, footpoint, footvel, 1, 0, 0, .9, .3);
3387 footvel = (weapons[weaponids[0]].tippoint - weapons[weaponids[0]].position);
3388 Sprite::MakeSprite(bloodsprite, footpoint, DoRotation(footvel * 7, (float)(Random() % 20), (float)(Random() % 20), 0), 1, 1, 1, .05, .9);
3389 Sprite::MakeSprite(bloodsprite, footpoint, DoRotation(footvel * 3, (float)(Random() % 20), (float)(Random() % 20), 0), 1, 1, 1, .05, .9);
3390 Sprite::MakeSprite(bloodflamesprite, footpoint, footvel * 5, 1, 1, 1, .3, 1);
3391 Sprite::MakeSprite(bloodflamesprite, footpoint, footvel * 2, 1, 1, 1, .3, 1);
3392 victim->DoBloodBig(200, 195);
3393 award_bonus(id, tracheotomy);
3395 if (animTarget == knifefollowanim) {
3396 award_bonus(id, Stabbonus);
3397 XYZ footvel, footpoint;
3399 footpoint = weapons[weaponids[0]].tippoint;
3401 Sprite::MakeSprite(cloudimpactsprite, footpoint, footvel, 1, 0, 0, .9, .3);
3402 footvel = (weapons[weaponids[0]].tippoint - weapons[weaponids[0]].position) * -1;
3403 Sprite::MakeSprite(bloodsprite, footpoint, DoRotation(footvel * 7, (float)(Random() % 20), (float)(Random() % 20), 0), 1, 1, 1, .05, .9);
3404 Sprite::MakeSprite(bloodsprite, footpoint, DoRotation(footvel * 3, (float)(Random() % 20), (float)(Random() % 20), 0), 1, 1, 1, .05, .9);
3405 Sprite::MakeSprite(bloodflamesprite, footpoint, footvel * 5, 1, 1, 1, .2, 1);
3406 Sprite::MakeSprite(bloodflamesprite, footpoint, footvel * 2, 1, 1, 1, .2, 1);
3409 victim->bloodloss += 10000;
3410 victim->velocity = 0;
3411 emit_sound_at(fleshstabsound, victim->coords);
3413 weapons[weaponids[weaponactive]].bloody = 2;
3414 weapons[weaponids[weaponactive]].blooddrip += 5;
3418 if (hasvictim && (animTarget == knifefollowanim || animTarget == knifesneakattackanim) && animation[animTarget].label[frameCurrent] == 6) {
3420 victim->velocity = 0;
3421 for (i = 0; i < victim->skeleton.num_joints; i++) {
3422 victim->skeleton.joints[i].velocity = 0;
3424 if (animTarget == knifefollowanim) {
3426 for (i = 0; i < victim->skeleton.num_joints; i++) {
3427 victim->skeleton.joints[i].velocity = 0;
3430 if (weaponactive != -1 && animation[victim->animTarget].attack != reversal) {
3431 emit_sound_at(fleshstabremovesound, victim->coords);
3433 weapons[weaponids[weaponactive]].bloody = 2;
3434 weapons[weaponids[weaponactive]].blooddrip += 5;
3436 XYZ footvel, footpoint;
3438 footpoint = weapons[weaponids[0]].tippoint;
3440 Sprite::MakeSprite(cloudimpactsprite, footpoint, footvel, 1, 0, 0, .9, .3);
3441 footvel = (weapons[weaponids[0]].tippoint - weapons[weaponids[0]].position) * -1;
3442 Sprite::MakeSprite(bloodsprite, footpoint, DoRotation(footvel * 7, (float)(Random() % 20), (float)(Random() % 20), 0), 1, 1, 1, .05, .9);
3443 Sprite::MakeSprite(bloodsprite, footpoint, DoRotation(footvel * 3, (float)(Random() % 20), (float)(Random() % 20), 0), 1, 1, 1, .05, .9);
3444 Sprite::MakeSprite(bloodflamesprite, footpoint, footvel * 5, 1, 1, 1, .3, 1);
3445 Sprite::MakeSprite(bloodflamesprite, footpoint, footvel * 2, 1, 1, 1, .3, 1);
3449 if (hasvictim && (animTarget == swordsneakattackanim) && animation[animTarget].label[frameCurrent] == 5) {
3450 if (weaponactive != -1 && victim->bloodloss < victim->damagetolerance) {
3451 award_bonus(id, backstab);
3455 XYZ footvel, footpoint;
3457 footpoint = (weapons[weaponids[0]].tippoint + weapons[weaponids[0]].position) / 2;
3459 Sprite::MakeSprite(cloudimpactsprite, footpoint, footvel, 1, 0, 0, .9, .3);
3460 footvel = (weapons[weaponids[0]].tippoint - weapons[weaponids[0]].position);
3461 Sprite::MakeSprite(bloodsprite, footpoint, DoRotation(footvel * 7, (float)(Random() % 20), (float)(Random() % 20), 0), 1, 1, 1, .05, .9);
3462 Sprite::MakeSprite(bloodsprite, footpoint, DoRotation(footvel * 3, (float)(Random() % 20), (float)(Random() % 20), 0), 1, 1, 1, .05, .9);
3463 Sprite::MakeSprite(bloodflamesprite, footpoint, DoRotation(footvel * 5, (float)(Random() % 20), (float)(Random() % 20), 0), 1, 1, 1, .3, 1);
3464 Sprite::MakeSprite(bloodflamesprite, footpoint, DoRotation(footvel * 3, (float)(Random() % 20), (float)(Random() % 20), 0), 1, 1, 1, .3, 1);
3465 victim->DoBloodBig(200, 180);
3466 victim->DoBloodBig(200, 215);
3467 victim->bloodloss += 10000;
3468 victim->velocity = 0;
3469 emit_sound_at(fleshstabsound, victim->coords);
3471 weapons[weaponids[weaponactive]].bloody = 2;
3472 weapons[weaponids[weaponactive]].blooddrip += 5;
3476 if (hasvictim && animTarget == swordsneakattackanim && animation[animTarget].label[frameCurrent] == 6) {
3478 victim->velocity = 0;
3479 for (i = 0; i < victim->skeleton.num_joints; i++) {
3480 victim->skeleton.joints[i].velocity = 0;
3482 if (weaponactive != -1) {
3483 emit_sound_at(fleshstabremovesound, victim->coords);
3485 weapons[weaponids[weaponactive]].bloody = 2;
3486 weapons[weaponids[weaponactive]].blooddrip += 5;
3488 XYZ footvel, footpoint;
3490 footpoint = weapons[weaponids[0]].tippoint;
3492 Sprite::MakeSprite(cloudimpactsprite, footpoint, footvel, 1, 0, 0, .9, .3);
3493 footvel = (weapons[weaponids[0]].tippoint - weapons[weaponids[0]].position) * -1;
3494 Sprite::MakeSprite(bloodsprite, footpoint, DoRotation(footvel * 7, (float)(Random() % 20), (float)(Random() % 20), 0), 1, 1, 1, .05, .9);
3495 Sprite::MakeSprite(bloodsprite, footpoint, DoRotation(footvel * 3, (float)(Random() % 20), (float)(Random() % 20), 0), 1, 1, 1, .05, .9);
3496 Sprite::MakeSprite(bloodflamesprite, footpoint, footvel * 5, 1, 1, 1, .3, 1);
3497 Sprite::MakeSprite(bloodflamesprite, footpoint, footvel * 2, 1, 1, 1, .3, 1);
3501 if (animTarget == sweepreversalanim && animation[animTarget].label[frameCurrent] == 7) {
3509 if (weaponactive == -1) {
3510 if (tutoriallevel != 1) {
3511 emit_sound_at(heavyimpactsound, victim->coords, 128.);
3516 if (weaponactive != -1 || creature == wolftype)
3518 if (creature == rabbittype && weaponactive != -1)
3519 if (weapons[weaponids[0]].getType() == staff)
3522 if (weaponactive != -1) {
3523 victim->DoBloodBig(2 / victim->armorhead, 225);
3524 emit_sound_at(knifeslicesound, victim->coords);
3525 if (bloodtoggle && !weapons[weaponids[weaponactive]].bloody)
3526 weapons[weaponids[weaponactive]].bloody = 1;
3527 weapons[weaponids[weaponactive]].blooddrip += 3;
3529 if (weaponactive == -1 && creature == wolftype) {
3530 emit_sound_at(clawslicesound, victim->coords, 128.);
3532 victim->DoBloodBig(2 / victim->armorhead, 175);
3536 award_bonus(id, Reversal);
3541 //relative=victim->coords-oldcoords;
3542 relative = facing * -1;
3544 Normalise(&relative);
3545 relative = DoRotation(relative, 0, 90, 0);
3547 Normalise(&relative);
3548 for (i = 0; i < victim->skeleton.num_joints; i++) {
3549 victim->skeleton.joints[i].velocity += relative * damagemult * 20;
3551 victim->jointVel(head) += relative * damagemult * 200;
3552 if (victim->damage < victim->damagetolerance - 100)
3553 victim->velocity = relative * 200;
3554 victim->DoDamage(damagemult * 100 / victim->protectionhead);
3555 victim->velocity = 0;
3558 if (animTarget == sweepreversalanim && ((animation[animTarget].label[frameCurrent] == 9 && victim->damage < victim->damagetolerance) || (animation[animTarget].label[frameCurrent] == 7 && victim->damage > victim->damagetolerance))) {
3562 //relative=victim->coords-oldcoords;
3563 relative = facing * -1;
3565 Normalise(&relative);
3566 relative = DoRotation(relative, 0, 90, 0);
3568 Normalise(&relative);
3569 for (i = 0; i < victim->skeleton.num_joints; i++) {
3570 victim->skeleton.joints[i].velocity += relative * damagemult * 20;
3572 victim->jointVel(head) += relative * damagemult * 200;
3575 if (hasvictim && (animTarget == spinkickreversalanim || animTarget == sweepreversalanim || animTarget == rabbitkickreversalanim || animTarget == upunchreversalanim || animTarget == jumpreversalanim || animTarget == swordslashreversalanim || animTarget == knifeslashreversalanim || animTarget == rabbittacklereversal || animTarget == wolftacklereversal || animTarget == staffhitreversalanim || animTarget == staffspinhitreversalanim))
3576 if (victim->damage > victim->damagetolerance && bonus != reverseko) {
3577 award_bonus(id, reverseko);
3583 if (frameTarget > animation[animCurrent].numframes - 1) {
3586 animTarget = getIdle();
3590 if (animCurrent == rabbittackleanim || animCurrent == rabbittacklinganim) {
3591 animTarget = rollanim;
3593 emit_sound_at(movewhooshsound, coords, 128.);
3595 if (animCurrent == staggerbackhighanim) {
3596 animTarget = getIdle();
3598 if (animCurrent == staggerbackhardanim) {
3599 animTarget = getIdle();
3601 if (animCurrent == removeknifeanim) {
3602 animTarget = getIdle();
3604 if (animCurrent == crouchremoveknifeanim) {
3605 animTarget = getCrouch();
3607 if (animCurrent == backhandspringanim) {
3608 animTarget = getIdle();
3610 if (animCurrent == dodgebackanim) {
3611 animTarget = getIdle();
3613 if (animCurrent == drawleftanim) {
3614 animTarget = getIdle();
3616 if (animCurrent == drawrightanim || animCurrent == crouchdrawrightanim) {
3617 animTarget = getIdle();
3618 if (animCurrent == crouchdrawrightanim) {
3619 animTarget = getCrouch();
3621 if (weaponactive == -1)
3623 else if (weaponactive == 0) {
3625 if (num_weapons == 2) {
3627 buffer = weaponids[0];
3628 weaponids[0] = weaponids[1];
3629 weaponids[1] = buffer;
3633 if (weaponactive == -1) {
3634 emit_sound_at(knifesheathesound, coords, 128.);
3636 if (weaponactive != -1) {
3637 emit_sound_at(knifedrawsound, coords, 128.);
3640 if (animCurrent == rollanim) {
3641 animTarget = getCrouch();
3646 if (animTarget == walljumprightkickanim) {
3649 if (animTarget == walljumpleftkickanim) {
3652 animTarget = jumpdownanim;
3654 if (animCurrent == climbanim) {
3655 animTarget = getCrouch();
3657 coords += facing * .1;
3658 if (!isnormal(coords.x))
3669 if (animTarget == rabbitkickreversalanim) {
3670 animTarget = getCrouch();
3673 if (animTarget == jumpreversalanim) {
3674 animTarget = getCrouch();
3677 if (animTarget == walljumprightanim || animTarget == walljumpbackanim || animTarget == walljumpfrontanim) {
3678 if (attackkeydown && animTarget != walljumpfrontanim) {
3680 float closestdist = -1;
3682 if (Person::players.size() > 1)
3683 for (i = 0; i < Person::players.size(); i++) {
3684 if (id != i && Person::players[i]->coords.y < coords.y && !Person::players[i]->skeleton.free) {
3685 distance = distsq(&Person::players[i]->coords, &coords);
3686 if (closestdist == -1 || distance < closestdist) {
3687 closestdist = distance;
3692 if (closestdist > 0 && closest >= 0 && closestdist < 16) {
3693 victim = Person::players[closest];
3694 animTarget = walljumprightkickanim;
3696 XYZ rotatetarget = victim->coords - coords;
3697 Normalise(&rotatetarget);
3698 yaw = -asin(0 - rotatetarget.x);
3700 if (rotatetarget.z < 0)
3702 targettilt2 = -asin(rotatetarget.y) * 360 / 6.28;
3703 velocity = (victim->coords - coords) * 4;
3708 if (animTarget == walljumpbackanim) {
3709 animTarget = backflipanim;
3711 velocity = facing * -8;
3714 resume_stream(whooshsound);
3716 if (animTarget == walljumprightanim) {
3717 animTarget = rightflipanim;
3721 velocity = DoRotation(facing, 0, 30, 0) * -8;
3724 if (animTarget == walljumpfrontanim) {
3725 animTarget = frontflipanim;
3729 velocity = facing * 8;
3733 resume_stream(whooshsound);
3735 if (animTarget == walljumpleftanim) {
3736 if (attackkeydown) {
3738 float closestdist = -1;
3740 if (Person::players.size() > 1)
3741 for (i = 0; i < Person::players.size(); i++) {
3742 if (id != i && Person::players[i]->coords.y < coords.y && !Person::players[i]->skeleton.free) {
3743 distance = distsq(&Person::players[i]->coords, &coords);
3744 if (closestdist == -1 || distance < closestdist) {
3745 closestdist = distance;
3750 if (closestdist > 0 && closest >= 0 && closestdist < 16) {
3751 victim = Person::players[closest];
3752 animTarget = walljumpleftkickanim;
3754 XYZ rotatetarget = victim->coords - coords;
3755 Normalise(&rotatetarget);
3756 yaw = -asin(0 - rotatetarget.x);
3758 if (rotatetarget.z < 0)
3760 targettilt2 = -asin(rotatetarget.y) * 360 / 6.28;
3761 velocity = (victim->coords - coords) * 4;
3766 if (animTarget != walljumpleftkickanim) {
3767 animTarget = leftflipanim;
3771 velocity = DoRotation(facing, 0, -30, 0) * -8;
3775 resume_stream(whooshsound);
3777 if (animTarget == sneakattackanim) {
3778 animCurrent = getCrouch();
3779 animTarget = getCrouch();
3786 transspeed = 1000000;
3787 targetheadyaw += 180;
3788 coords -= facing * .7;
3790 coords.y = terrain.getHeight(coords.x, coords.z);
3794 if (animTarget == knifesneakattackanim || animTarget == swordsneakattackanim) {
3795 animTarget = getIdle();
3798 coords.y = terrain.getHeight(coords.x, coords.z);
3802 if (animCurrent == knifefollowanim) {
3803 animTarget = getIdle();
3806 if (animation[animTarget].attack == reversal && animCurrent != sneakattackanim && animCurrent != knifesneakattackanim && animCurrent != swordsneakattackanim && animCurrent != knifefollowanim) {
3807 float ycoords = oldcoords.y;
3808 animTarget = getStop();
3813 transspeed = 1000000;
3814 targetheadyaw += 180;
3815 if (!isnormal(coords.x))
3817 if (animCurrent == spinkickreversalanim || animCurrent == swordslashreversalanim)
3818 oldcoords = coords + facing * .5;
3819 else if (animCurrent == sweepreversalanim)
3820 oldcoords = coords + facing * 1.1;
3821 else if (animCurrent == upunchreversalanim) {
3822 oldcoords = coords + facing * 1.5;
3825 targetheadyaw += 180;
3828 } else if (animCurrent == knifeslashreversalanim) {
3829 oldcoords = coords + facing * .5;
3832 targetheadyaw += 90;
3835 } else if (animCurrent == staffspinhitreversalanim) {
3838 targetheadyaw += 180;
3843 oldcoords.y = terrain.getHeight(oldcoords.x, oldcoords.z);
3845 oldcoords.y = ycoords;
3846 currentoffset = coords - oldcoords;
3852 if (animCurrent == knifesneakattackedanim || animCurrent == swordsneakattackedanim) {
3857 if (animation[animTarget].attack == reversed) {
3859 if (animTarget == sweepreversedanim)
3861 animTarget = backhandspringanim;
3863 emit_sound_at(landsound, coords, 128);
3865 if (animCurrent == upunchreversedanim || animCurrent == swordslashreversedanim) {
3866 animTarget = rollanim;
3869 coords += (DoRotation(jointPos(leftfoot), 0, yaw, 0) + DoRotation(jointPos(rightfoot), 0, yaw, 0)) / 2 * scale;
3870 coords.y = oldcoords.y;
3872 if (animCurrent == knifeslashreversedanim) {
3873 animTarget = rollanim;
3878 coords += (DoRotation(jointPos(leftfoot), 0, yaw, 0) + DoRotation(jointPos(rightfoot), 0, yaw, 0)) / 2 * scale;
3879 coords.y = oldcoords.y;
3883 animTarget = jumpdownanim;
3886 animTarget = getIdle();
3888 animTarget = getIdle();
3889 if (animCurrent == spinkickanim || animCurrent == getupfrombackanim || animCurrent == getupfromfrontanim || animCurrent == lowkickanim) {
3890 animTarget = getIdle();
3892 coords += (DoRotation(jointPos(leftfoot), 0, yaw, 0) + DoRotation(jointPos(rightfoot), 0, yaw, 0)) / 2 * scale;
3893 coords.y = oldcoords.y;
3894 //coords+=DoRotation(animation[animCurrent].offset,0,yaw,0)*scale;
3895 targetoffset.y = coords.y;
3897 targetoffset.y = terrain.getHeight(coords.x, coords.z);
3898 currentoffset = DoRotation(animation[animCurrent].offset * -1, 0, yaw, 0) * scale;
3899 currentoffset.y -= (coords.y - targetoffset.y);
3900 coords.y = targetoffset.y;
3902 normalsupdatedelay = 0;
3904 if (animCurrent == upunchanim) {
3905 animTarget = getStop();
3906 normalsupdatedelay = 0;
3909 if (animCurrent == rabbitkickanim && animTarget != backflipanim) {
3913 if (num_weapons > 0)
3914 if (weapons[0].getType() == staff)
3920 rabbitkickragdoll = 1;
3922 if (animCurrent == rabbitkickreversedanim) {
3928 skeleton.spinny = 0;
3929 SolidHitBonus(!id); // FIXME: tricky id
3933 animTarget = rollanim;
3936 pause_sound(whooshsound);
3940 if (animCurrent == rabbittackledbackanim || animCurrent == rabbittackledfrontanim) {
3944 skeleton.spinny = 0;
3946 if (animCurrent == jumpreversedanim) {
3952 skeleton.spinny = 0;
3953 SolidHitBonus(!id); // FIXME: tricky id
3957 animTarget = rollanim;
3958 coords += facing * 2;
3960 pause_sound(whooshsound);
3965 if (animation[animCurrent].attack == normalattack && !victim->skeleton.free && victim->animTarget != staggerbackhighanim && victim->animTarget != staggerbackhardanim && animTarget != winduppunchblockedanim && animTarget != blockhighleftanim && animTarget != swordslashparryanim && animTarget != swordslashparriedanim && animTarget != crouchstabanim && animTarget != swordgroundstabanim) {
3966 animTarget = getupfromfrontanim;
3968 } else if (animation[animCurrent].attack == normalattack) {
3969 animTarget = getIdle();
3972 if (animCurrent == blockhighleftanim && aitype != playercontrolled) {
3973 animTarget = blockhighleftstrikeanim;
3975 if (animCurrent == knifeslashstartanim || animCurrent == knifethrowanim || animCurrent == swordslashanim || animCurrent == staffhitanim || animCurrent == staffgroundsmashanim || animCurrent == staffspinhitanim) {
3976 animTarget = getIdle();
3979 if (animCurrent == spinkickanim && victim->skeleton.free) {
3980 if (creature == rabbittype)
3981 animTarget = fightidleanim;
3986 if (isIdle() && !wasIdle())
3987 normalsupdatedelay = 0;
3989 if (animCurrent == jumpupanim && velocity.y < 0 && !isFlip()) {
3990 animTarget = jumpdownanim;
3993 if (!skeleton.free) {
3995 if (!transspeed && animation[animTarget].attack != 2 && animation[animTarget].attack != 3) {
3996 if (!isRun() || !wasRun()) {
3997 if (animation[animTarget].speed[frameTarget] > animation[animCurrent].speed[frameCurrent])
3998 target += multiplier * animation[animTarget].speed[frameTarget] * speed * 2;
3999 if (animation[animTarget].speed[frameTarget] <= animation[animCurrent].speed[frameCurrent])
4000 target += multiplier * animation[animCurrent].speed[frameCurrent] * speed * 2;
4002 if (isRun() && wasRun()) {
4004 tempspeed = velspeed;
4005 if (tempspeed < 10 * speedmult)
4006 tempspeed = 10 * speedmult;
4007 target += multiplier * animation[animTarget].speed[frameCurrent] * speed * 1.7 * tempspeed / (speed * 45 * scale);
4009 } else if (transspeed)
4010 target += multiplier * transspeed * speed * 2;
4012 if (!isRun() || !wasRun()) {
4013 if (animation[animTarget].speed[frameTarget] > animation[animCurrent].speed[frameCurrent])
4014 target += multiplier * animation[animTarget].speed[frameTarget] * 2;
4015 if (animation[animTarget].speed[frameTarget] <= animation[animCurrent].speed[frameCurrent])
4016 target += multiplier * animation[animCurrent].speed[frameCurrent] * 2;
4020 if (animCurrent != animTarget)
4021 target = (target + oldtarget) / 2;
4024 frameCurrent = frameTarget;
4028 rot = targetrot * target;
4029 yaw += rot - oldrot;
4035 if (animCurrent != oldanimCurrent || animTarget != oldanimTarget || ((frameCurrent != oldframeCurrent || frameTarget != oldframeTarget) && !calcrot)) {
4037 for (i = 0; i < skeleton.num_joints; i++) {
4038 skeleton.joints[i].position = animation[animCurrent].position[i][frameCurrent];
4041 skeleton.FindForwards();
4043 for (i = 0; i < skeleton.num_muscles; i++) {
4044 if (skeleton.muscles[i].visible) {
4045 skeleton.FindRotationMuscle(i, animTarget);
4048 for (i = 0; i < skeleton.num_muscles; i++) {
4049 if (skeleton.muscles[i].visible) {
4050 if (isnormal((float)((int)(skeleton.muscles[i].rotate1 * 100) % 36000) / 100))
4051 skeleton.muscles[i].oldrotate1 = (float)((int)(skeleton.muscles[i].rotate1 * 100) % 36000) / 100;
4052 if (isnormal((float)((int)(skeleton.muscles[i].rotate2 * 100) % 36000) / 100))
4053 skeleton.muscles[i].oldrotate2 = (float)((int)(skeleton.muscles[i].rotate2 * 100) % 36000) / 100;
4054 if (isnormal((float)((int)(skeleton.muscles[i].rotate3 * 100) % 36000) / 100))
4055 skeleton.muscles[i].oldrotate3 = (float)((int)(skeleton.muscles[i].rotate3 * 100) % 36000) / 100;
4060 for (i = 0; i < skeleton.num_joints; i++) {
4061 skeleton.joints[i].position = animation[animTarget].position[i][frameTarget];
4064 skeleton.FindForwards();
4066 for (i = 0; i < skeleton.num_muscles; i++) {
4067 if (skeleton.muscles[i].visible) {
4068 skeleton.FindRotationMuscle(i, animTarget);
4071 for (i = 0; i < skeleton.num_muscles; i++) {
4072 if (skeleton.muscles[i].visible) {
4073 if (isnormal((float)((int)(skeleton.muscles[i].rotate1 * 100) % 36000) / 100))
4074 skeleton.muscles[i].newrotate1 = (float)((int)(skeleton.muscles[i].rotate1 * 100) % 36000) / 100;
4075 if (isnormal((float)((int)(skeleton.muscles[i].rotate2 * 100) % 36000) / 100))
4076 skeleton.muscles[i].newrotate2 = (float)((int)(skeleton.muscles[i].rotate2 * 100) % 36000) / 100;
4077 if (isnormal((float)((int)(skeleton.muscles[i].rotate3 * 100) % 36000) / 100))
4078 skeleton.muscles[i].newrotate3 = (float)((int)(skeleton.muscles[i].rotate3 * 100) % 36000) / 100;
4079 if (skeleton.muscles[i].newrotate3 > skeleton.muscles[i].oldrotate3 + 180) skeleton.muscles[i].newrotate3 -= 360;
4080 if (skeleton.muscles[i].newrotate3 < skeleton.muscles[i].oldrotate3 - 180) skeleton.muscles[i].newrotate3 += 360;
4081 if (skeleton.muscles[i].newrotate2 > skeleton.muscles[i].oldrotate2 + 180) skeleton.muscles[i].newrotate2 -= 360;
4082 if (skeleton.muscles[i].newrotate2 < skeleton.muscles[i].oldrotate2 - 180) skeleton.muscles[i].newrotate2 += 360;
4083 if (skeleton.muscles[i].newrotate1 > skeleton.muscles[i].oldrotate1 + 180) skeleton.muscles[i].newrotate1 -= 360;
4084 if (skeleton.muscles[i].newrotate1 < skeleton.muscles[i].oldrotate1 - 180) skeleton.muscles[i].newrotate1 += 360;
4088 if (frameCurrent >= animation[animCurrent].numframes)
4089 frameCurrent = animation[animCurrent].numframes - 1;
4091 oldanimCurrent = animCurrent;
4092 oldanimTarget = animTarget;
4093 oldframeTarget = frameTarget;
4094 oldframeCurrent = frameCurrent;
4096 for (i = 0; i < skeleton.num_joints; i++) {
4097 skeleton.joints[i].velocity = (animation[animCurrent].position[i][frameCurrent] * (1 - target) + animation[animTarget].position[i][frameTarget] * (target) - skeleton.joints[i].position) / multiplier;
4098 skeleton.joints[i].position = animation[animCurrent].position[i][frameCurrent] * (1 - target) + animation[animTarget].position[i][frameTarget] * (target);
4100 offset = currentoffset * (1 - target) + targetoffset * target;
4101 for (i = 0; i < skeleton.num_muscles; i++) {
4102 if (skeleton.muscles[i].visible) {
4103 skeleton.muscles[i].rotate1 = skeleton.muscles[i].oldrotate1 * (1 - target) + skeleton.muscles[i].newrotate1 * (target);
4104 skeleton.muscles[i].rotate2 = skeleton.muscles[i].oldrotate2 * (1 - target) + skeleton.muscles[i].newrotate2 * (target);
4105 skeleton.muscles[i].rotate3 = skeleton.muscles[i].oldrotate3 * (1 - target) + skeleton.muscles[i].newrotate3 * (target);
4110 if (isLanding() && landhard) {
4113 animTarget = getLandhard();
4120 //skeleton.DoConstraints();
4127 void Person::DoStuff()
4129 static XYZ terrainnormal;
4130 static XYZ flatfacing;
4131 static XYZ flatvelocity;
4132 static float flatvelspeed;
4136 static int bloodsize;
4137 static int startx, starty, endx, endy;
4138 static GLubyte color;
4139 static XYZ bloodvel;
4141 onfiredelay -= multiplier;
4142 if (onfiredelay < 0 && onfire) {
4143 if (Random() % 2 == 0) {
4149 crouchkeydowntime += multiplier;
4151 crouchkeydowntime = 0;
4152 jumpkeydowntime += multiplier;
4153 if (!jumpkeydown && skeleton.free)
4154 jumpkeydowntime = 0;
4156 if (hostile || damage > 0 || bloodloss > 0)
4159 if (isIdle() || isRun())
4162 if (num_weapons == 1 && weaponactive != -1)
4166 blooddimamount -= multiplier * .3;
4167 speechdelay -= multiplier;
4168 texupdatedelay -= multiplier;
4169 interestdelay -= multiplier;
4170 flamedelay -= multiplier;
4171 parriedrecently -= multiplier;
4173 victim = this->shared_from_this();
4178 speed = 1.1 * speedmult;
4180 speed = 1.0 * speedmult;
4182 rabbitkickragdoll = 0;
4186 if (id != 0 && (creature == rabbittype || difficulty != 2))
4188 if (id != 0 && creature == wolftype && difficulty == 2) {
4190 if (aitype != passivetype) {
4192 if (aitype == attacktypecutoff && (Person::players[0]->isIdle() || Person::players[0]->isCrouch() || Person::players[0]->skeleton.free || Person::players[0]->animTarget == getupfrombackanim || Person::players[0]->animTarget == getupfromfrontanim || Person::players[0]->animTarget == sneakanim) && distsq(&coords, &Person::players[0]->coords) < 16) {
4198 if (animTarget == wolfrunninganim && !superruntoggle) {
4199 animTarget = getRun();
4203 if (weaponactive == -1 && num_weapons > 0) {
4204 if (weapons[weaponids[0]].getType() == staff) {
4210 burnt += multiplier;
4211 /*if(aitype!=playercontrolled)*///deathbleeding=5;
4212 /*if(aitype!=playercontrolled)*/
4216 OPENAL_SetVolume(channels[stream_firesound], 256 + 256 * findLength(&velocity) / 3);
4218 if (animTarget == jumpupanim || animTarget == jumpdownanim || isFlip()) {
4224 vel[0] = velocity.x;
4225 vel[1] = velocity.y;
4226 vel[2] = velocity.z;
4229 OPENAL_3D_SetAttributes(channels[whooshsound], gLoc, vel);
4230 OPENAL_SetVolume(channels[whooshsound], 64 * findLength(&velocity) / 5);
4234 while (flamedelay < 0 && onfire) {
4236 howmany = abs(Random() % (skeleton.num_joints));
4238 flatvelocity = (coords - oldcoords) / multiplier / 2; //velocity/2;
4240 flatvelocity = skeleton.joints[howmany].velocity * scale / 2;
4242 flatfacing = DoRotation(DoRotation(DoRotation(skeleton.joints[howmany].position, 0, 0, tilt), tilt2, 0, 0), 0, yaw, 0) * scale + coords;
4244 flatfacing = skeleton.joints[howmany].position * scale + coords;
4245 Sprite::MakeSprite(flamesprite, flatfacing, flatvelocity, 1, 1, 1, .6 + (float)abs(Random() % 100) / 200 - .25, 1);
4248 while (flamedelay < 0 && !onfire && tutoriallevel == 1 && id != 0) {
4250 howmany = abs(Random() % (skeleton.num_joints));
4252 flatvelocity = (coords - oldcoords) / multiplier / 2; //velocity/2;
4254 flatvelocity = skeleton.joints[howmany].velocity * scale / 2;
4256 flatfacing = DoRotation(DoRotation(DoRotation(skeleton.joints[howmany].position, 0, 0, tilt), tilt2, 0, 0), 0, yaw, 0) * scale + coords;
4258 flatfacing = skeleton.joints[howmany].position * scale + coords;
4259 Sprite::MakeSprite(breathsprite, flatfacing, flatvelocity, 1, 1, 1, .6 + (float)abs(Random() % 100) / 200 - .25, .3);
4263 bleeding -= multiplier * .3;
4264 if (bloodtoggle == 2) {
4265 skeleton.drawmodel.textureptr.bind();
4266 if (bleeding <= 0 && (detail != 2 || osx))
4271 if (neckspurtamount > 0) {
4272 neckspurtamount -= multiplier;
4273 neckspurtdelay -= multiplier * 3;
4274 neckspurtparticledelay -= multiplier * 3;
4275 if (neckspurtparticledelay < 0 && neckspurtdelay > 2) {
4278 if (!skeleton.free) {
4279 bloodvel.z = 5 * neckspurtamount;
4280 bloodvel = DoRotation(bloodvel, ((float)(Random() % 100)) / 40, yaw + ((float)(Random() % 100)) / 40, 0) * scale;
4282 if (skeleton.free) {
4283 bloodvel -= DoRotation(skeleton.forward * 10 * scale, ((float)(Random() % 100)) / 40, ((float)(Random() % 100)) / 40, 0);
4286 bloodvel += DoRotation(jointVel(head), ((float)(Random() % 100)) / 40, yaw + ((float)(Random() % 100)) / 40, 0) * scale;
4288 bloodvel += DoRotation(velocity, ((float)(Random() % 100)) / 40, ((float)(Random() % 100)) / 40, 0) * scale;
4290 Sprite::MakeSprite(bloodsprite, (jointPos(neck) + (jointPos(neck) - jointPos(head)) / 5)*scale + coords, bloodvel, 1, 1, 1, .05, .9);
4292 Sprite::MakeSprite(bloodsprite, DoRotation(jointPos(neck) + (jointPos(neck) - jointPos(head)) / 5, 0, yaw, 0)*scale + coords, bloodvel, 1, 1, 1, .05, .9);
4293 neckspurtparticledelay = .05;
4295 if (neckspurtdelay < 0) {
4300 if (deathbleeding > 0 && dead != 2) {
4301 if (deathbleeding < 5)
4302 bleeddelay -= deathbleeding * multiplier / 4;
4304 bleeddelay -= 5 * multiplier / 4;
4305 if (bleeddelay < 0 && bloodtoggle) {
4311 bloodvel += DoRotation(jointVel(abdomen), ((float)(Random() % 100)) / 4, yaw + ((float)(Random() % 100)) / 4, 0) * scale;
4313 bloodvel += DoRotation(velocity, ((float)(Random() % 100)) / 4, ((float)(Random() % 100)) / 4, 0) * scale;
4315 Sprite::MakeSprite(bloodsprite, jointPos(abdomen) * scale + coords, bloodvel, 1, 1, 1, .05, 1);
4317 Sprite::MakeSprite(bloodsprite, DoRotation((jointPos(abdomen) + jointPos(abdomen)) / 2, 0, yaw, 0)*scale + coords, bloodvel, 1, 1, 1, .05, 1);
4320 bloodloss += deathbleeding * multiplier * 80;
4321 deathbleeding -= multiplier * 1.6;
4322 //if(id==0)deathbleeding-=multiplier*.2;
4323 if (deathbleeding < 0)
4325 if (bloodloss > damagetolerance && animation[animTarget].attack == neutral) {
4326 if (weaponactive != -1) {
4327 weapons[weaponids[0]].owner = -1;
4328 weapons[weaponids[0]].velocity = velocity * scale * -.3;
4329 weapons[weaponids[0]].velocity.x += .01;
4330 weapons[weaponids[0]].tipvelocity = velocity * scale;
4331 weapons[weaponids[0]].missed = 1;
4332 weapons[weaponids[0]].hitsomething = 0;
4333 weapons[weaponids[0]].freetime = 0;
4334 weapons[weaponids[0]].firstfree = 1;
4335 weapons[weaponids[0]].physics = 1;
4338 weaponids[0] = weaponids[num_weapons];
4339 if (weaponstuck == num_weapons)
4343 for (i = 0; i < Person::players.size(); i++) {
4344 Person::players[i]->wentforweapon = 0;
4356 if (!dead && creature == wolftype) {
4357 award_bonus(0, Wolfbonus);
4360 if (animTarget == knifefollowedanim && !skeleton.free) {
4361 for (i = 0; i < skeleton.num_joints; i++) {
4362 skeleton.joints[i].velocity = 0;
4363 skeleton.joints[i].velocity.y = -2;
4366 if (id != 0 && unconscioustime > .1) {
4374 if (texupdatedelay < 0 && bleeding > 0 && bloodtoggle == 2 && distsq(&viewer, &coords) < 9) {
4375 texupdatedelay = .12;
4377 bloodsize = 5 - realtexdetail;
4381 startx = bleedy; //abs(Random()%(skeleton.skinsize-bloodsize-1));
4382 starty = bleedx; //abs(Random()%(skeleton.skinsize-bloodsize-1));
4383 endx = startx + bloodsize;
4384 endy = starty + bloodsize;
4394 if (endx > skeleton.skinsize - 1) {
4395 endx = skeleton.skinsize - 1;
4398 if (endy > skeleton.skinsize - 1) {
4399 endy = skeleton.skinsize - 1;
4407 for (i = startx; i < endx; i++) {
4408 for (j = starty; j < endy; j++) {
4409 if (Random() % 2 == 0) {
4410 color = Random() % 85 + 170;
4411 if (skeleton.skinText[i * skeleton.skinsize * 3 + j * 3 + 0] > color / 2)
4412 skeleton.skinText[i * skeleton.skinsize * 3 + j * 3 + 0] = color / 2;
4413 skeleton.skinText[i * skeleton.skinsize * 3 + j * 3 + 1] = 0;
4414 skeleton.skinText[i * skeleton.skinsize * 3 + j * 3 + 2] = 0;
4418 if (!osx && detail > 1) {
4419 skeleton.drawmodel.textureptr.bind();
4423 if (!skeleton.free) {
4424 bleedy -= 4 / realtexdetail;
4426 bleedx += (abs(Random() % 3) - 1) * 2 / realtexdetail;
4428 bleedx += (abs(Random() % 3) - 1) * 4 / realtexdetail;
4430 if (skeleton.free) {
4431 bleedx += 4 * direction / realtexdetail;
4433 bleedy += (abs(Random() % 3) - 1) * 2 / realtexdetail;
4435 bleedy += (abs(Random() % 3) - 1) * 4 / realtexdetail;
4439 if (abs(righthandmorphness - targetrighthandmorphness) < multiplier * 4) {
4440 righthandmorphness = targetrighthandmorphness;
4441 righthandmorphstart = righthandmorphend;
4442 } else if (righthandmorphness > targetrighthandmorphness) {
4443 righthandmorphness -= multiplier * 4;
4444 } else if (righthandmorphness < targetrighthandmorphness) {
4445 righthandmorphness += multiplier * 4;
4448 if (abs(lefthandmorphness - targetlefthandmorphness) < multiplier * 4) {
4449 lefthandmorphness = targetlefthandmorphness;
4450 lefthandmorphstart = lefthandmorphend;
4451 } else if (lefthandmorphness > targetlefthandmorphness) {
4452 lefthandmorphness -= multiplier * 4;
4453 } else if (lefthandmorphness < targetlefthandmorphness) {
4454 lefthandmorphness += multiplier * 4;
4457 if (creature == rabbittype || targettailmorphness == 5 || targettailmorphness == 0) {
4458 if (abs(tailmorphness - targettailmorphness) < multiplier * 10) {
4459 tailmorphness = targettailmorphness;
4460 tailmorphstart = tailmorphend;
4461 } else if (tailmorphness > targettailmorphness) {
4462 tailmorphness -= multiplier * 10;
4463 } else if (tailmorphness < targettailmorphness) {
4464 tailmorphness += multiplier * 10;
4468 if (creature == wolftype) {
4469 if (abs(tailmorphness - targettailmorphness) < multiplier * 4) {
4470 tailmorphness = targettailmorphness;
4471 tailmorphstart = tailmorphend;
4472 } else if (tailmorphness > targettailmorphness) {
4473 tailmorphness -= multiplier * 2;
4474 } else if (tailmorphness < targettailmorphness) {
4475 tailmorphness += multiplier * 2;
4479 if (headmorphend == 3 || headmorphstart == 3) {
4480 if (abs(headmorphness - targetheadmorphness) < multiplier * 7) {
4481 headmorphness = targetheadmorphness;
4482 headmorphstart = headmorphend;
4483 } else if (headmorphness > targetheadmorphness) {
4484 headmorphness -= multiplier * 7;
4485 } else if (headmorphness < targetheadmorphness) {
4486 headmorphness += multiplier * 7;
4488 } else if (headmorphend == 5 || headmorphstart == 5) {
4489 if (abs(headmorphness - targetheadmorphness) < multiplier * 10) {
4490 headmorphness = targetheadmorphness;
4491 headmorphstart = headmorphend;
4492 } else if (headmorphness > targetheadmorphness) {
4493 headmorphness -= multiplier * 10;
4494 } else if (headmorphness < targetheadmorphness) {
4495 headmorphness += multiplier * 10;
4498 if (abs(headmorphness - targetheadmorphness) < multiplier * 4) {
4499 headmorphness = targetheadmorphness;
4500 headmorphstart = headmorphend;
4501 } else if (headmorphness > targetheadmorphness) {
4502 headmorphness -= multiplier * 4;
4503 } else if (headmorphness < targetheadmorphness) {
4504 headmorphness += multiplier * 4;
4508 if (abs(chestmorphness - targetchestmorphness) < multiplier) {
4509 chestmorphness = targetchestmorphness;
4510 chestmorphstart = chestmorphend;
4511 } else if (chestmorphness > targetchestmorphness) {
4512 chestmorphness -= multiplier;
4513 } else if (chestmorphness < targetchestmorphness) {
4514 chestmorphness += multiplier;
4517 if (dead != 2 && howactive <= typesleeping) {
4518 if (chestmorphstart == 0 && chestmorphend == 0) {
4520 targetchestmorphness = 1;
4523 if (chestmorphstart != 0 && chestmorphend != 0) {
4525 targetchestmorphness = 1;
4527 if (environment == snowyenvironment) {
4531 footvel = DoRotation(skeleton.specialforward[0], 0, yaw, 0) * -1;
4533 footvel = skeleton.specialforward[0] * -1;
4535 footpoint = DoRotation((jointPos(head) + jointPos(neck)) / 2, 0, yaw, 0) * scale + coords;
4537 footpoint = ((jointPos(head) + jointPos(neck)) / 2) * scale + coords;
4538 if (animTarget == sleepanim)
4539 footvel = DoRotation(footvel, 0, 90, 0);
4540 Sprite::MakeSprite(breathsprite, footpoint + footvel * .2, footvel * .4, 1, 1, 1, .4, .3);
4544 if (!dead && howactive < typesleeping) {
4545 blinkdelay -= multiplier * 2;
4546 if (headmorphstart == 0 && headmorphend == 0 && blinkdelay <= 0) {
4548 targetheadmorphness = 1;
4550 blinkdelay = (float)(abs(Random() % 40)) / 5;
4552 if (headmorphstart == 3 && headmorphend == 3) {
4554 targetheadmorphness = 1;
4559 twitchdelay -= multiplier * 1.5;
4560 if (animTarget != hurtidleanim) {
4561 if (headmorphstart == 0 && headmorphend == 0 && twitchdelay <= 0) {
4563 targetheadmorphness = 1;
4565 twitchdelay = (float)(abs(Random() % 40)) / 5;
4567 if (headmorphstart == 5 && headmorphend == 5) {
4569 targetheadmorphness = 1;
4573 if ((isIdle() || isCrouch()) && animTarget != hurtidleanim) {
4574 twitchdelay3 -= multiplier * 1;
4575 if (Random() % 2 == 0) {
4576 if (righthandmorphstart == 0 && righthandmorphend == 0 && twitchdelay3 <= 0) {
4577 righthandmorphness = 0;
4578 targetrighthandmorphness = 1;
4579 righthandmorphend = 1;
4580 if (Random() % 2 == 0)twitchdelay3 = (float)(abs(Random() % 40)) / 5;
4582 if (righthandmorphstart == 1 && righthandmorphend == 1) {
4583 righthandmorphness = 0;
4584 targetrighthandmorphness = 1;
4585 righthandmorphend = 0;
4588 if (Random() % 2 == 0) {
4589 if (lefthandmorphstart == 0 && lefthandmorphend == 0 && twitchdelay3 <= 0) {
4590 lefthandmorphness = 0;
4591 targetlefthandmorphness = 1;
4592 lefthandmorphend = 1;
4593 twitchdelay3 = (float)(abs(Random() % 40)) / 5;
4595 if (lefthandmorphstart == 1 && lefthandmorphend == 1) {
4596 lefthandmorphness = 0;
4597 targetlefthandmorphness = 1;
4598 lefthandmorphend = 0;
4604 if (creature == rabbittype) {
4605 if (howactive < typesleeping)
4606 twitchdelay2 -= multiplier * 1.5;
4608 twitchdelay2 -= multiplier * 0.5;
4609 if (howactive <= typesleeping) {
4610 if (tailmorphstart == 0 && tailmorphend == 0 && twitchdelay2 <= 0) {
4612 targettailmorphness = 1;
4614 twitchdelay2 = (float)(abs(Random() % 40)) / 5;
4616 if (tailmorphstart == 1 && tailmorphend == 1) {
4618 targettailmorphness = 1;
4621 if (tailmorphstart == 2 && tailmorphend == 2) {
4623 targettailmorphness = 1;
4630 if (creature == wolftype) {
4631 twitchdelay2 -= multiplier * 1.5;
4632 if (tailmorphend != 0)
4633 if ((isRun() || animTarget == jumpupanim || animTarget == jumpdownanim || animTarget == backflipanim) && !skeleton.free) {
4635 targettailmorphness = 1;
4639 if (tailmorphend != 5)
4640 if (animTarget == flipanim || animTarget == frontflipanim || animTarget == rollanim || skeleton.free) {
4642 targettailmorphness = 1;
4646 if (twitchdelay2 <= 0) {
4647 if (((tailmorphstart == 0 && tailmorphend == 0) || (tailmorphstart == 5 && tailmorphend == 5))) {
4649 targettailmorphness = 1;
4652 if (tailmorphstart == 1 && tailmorphend == 1) {
4654 targettailmorphness = 1;
4657 if (tailmorphstart == 2 && tailmorphend == 2) {
4659 targettailmorphness = 1;
4662 if (tailmorphstart == 3 && tailmorphend == 3) {
4664 targettailmorphness = 1;
4667 if (tailmorphstart == 4 && tailmorphend == 4) {
4669 targettailmorphness = 1;
4676 unconscioustime = 0;
4678 if (dead == 1 || howactive == typesleeping) {
4679 unconscioustime += multiplier;
4680 //If unconscious, close eyes and mouth
4681 if (righthandmorphend != 0)
4682 righthandmorphness = 0;
4683 righthandmorphend = 0;
4684 targetrighthandmorphness = 1;
4686 if (lefthandmorphend != 0)
4687 lefthandmorphness = 0;
4688 lefthandmorphend = 0;
4689 targetlefthandmorphness = 1;
4691 if (headmorphend != 3 && headmorphend != 5)
4694 targetheadmorphness = 1;
4698 if (howactive > typesleeping) {
4701 if (bloodtoggle && !bled) {
4702 terrain.MakeDecal(blooddecalslow, headpoint, .8, .5, 0);
4704 if (bloodtoggle && !bled)
4705 for (l = 0; l < terrain.patchobjectnum[whichpatchx][whichpatchz]; l++) {
4706 j = terrain.patchobjects[whichpatchx][whichpatchz][l];
4707 XYZ point = DoRotation(headpoint - objects.position[j], 0, -objects.yaw[j], 0);
4711 objects.model[j].MakeDecal(blooddecalslow, &point, &size, &opacity, &yaw);
4716 if (dead == 2 || howactive > typesleeping) {
4717 //If dead, open mouth and hands
4718 if (righthandmorphend != 0)
4719 righthandmorphness = 0;
4720 righthandmorphend = 0;
4721 targetrighthandmorphness = 1;
4723 if (lefthandmorphend != 0)
4724 lefthandmorphness = 0;
4725 lefthandmorphend = 0;
4726 targetlefthandmorphness = 1;
4728 if (headmorphend != 2)
4731 targetheadmorphness = 1;
4734 if (stunned > 0 && !dead && headmorphend != 2) {
4735 if (headmorphend != 4)
4738 targetheadmorphness = 1;
4741 if (damage > damagetolerance && !dead) {
4744 unconscioustime = 0;
4746 if (creature == wolftype) {
4747 award_bonus(0, Wolfbonus);
4752 if (weaponactive != -1) {
4753 weapons[weaponids[0]].owner = -1;
4754 weapons[weaponids[0]].velocity = velocity * scale * -.3;
4755 weapons[weaponids[0]].velocity.x += .01;
4756 weapons[weaponids[0]].tipvelocity = velocity * scale;
4757 weapons[weaponids[0]].missed = 1;
4758 weapons[weaponids[0]].hitsomething = 0;
4759 weapons[weaponids[0]].freetime = 0;
4760 weapons[weaponids[0]].firstfree = 1;
4761 weapons[weaponids[0]].physics = 1;
4764 weaponids[0] = weaponids[num_weapons];
4765 if (weaponstuck == num_weapons)
4769 for (i = 0; i < Person::players.size(); i++) {
4770 Person::players[i]->wentforweapon = 0;
4776 if ((id == 0 || distsq(&coords, &viewer) < 50) && autoslomo) {
4784 //if(dead)damage-=multiplier/4;
4786 damage -= multiplier * 13;
4787 //if(!dead&&deathbleeding<=0&&id==0)bloodloss-=multiplier*4;
4789 permanentdamage -= multiplier * 4;
4790 if (isIdle() || isCrouch()) {
4792 permanentdamage -= multiplier * 4;
4793 //if(!dead&&deathbleeding<=0&&id==0)bloodloss-=multiplier*4;
4797 if (permanentdamage < 0)
4798 permanentdamage = 0;
4799 if (superpermanentdamage < 0)
4800 superpermanentdamage = 0;
4801 if (permanentdamage < superpermanentdamage) {
4802 permanentdamage = superpermanentdamage;
4804 if (damage < permanentdamage) {
4805 damage = permanentdamage;
4807 if (dead == 1 && damage < damagetolerance) {
4811 for (i = 0; i < skeleton.num_joints; i++) {
4812 skeleton.joints[i].velocity = 0;
4815 if (permanentdamage > damagetolerance && dead != 2) {
4818 if (weaponactive != -1) {
4819 weapons[weaponids[0]].owner = -1;
4820 weapons[weaponids[0]].velocity = velocity * scale * -.3;
4821 weapons[weaponids[0]].velocity.x += .01;
4822 weapons[weaponids[0]].tipvelocity = velocity * scale;
4823 weapons[weaponids[0]].missed = 1;
4824 weapons[weaponids[0]].hitsomething = 0;
4825 weapons[weaponids[0]].freetime = 0;
4826 weapons[weaponids[0]].firstfree = 1;
4827 weapons[weaponids[0]].physics = 1;
4830 weaponids[0] = weaponids[num_weapons];
4831 if (weaponstuck == num_weapons)
4835 for (i = 0; i < Person::players.size(); i++) {
4836 Person::players[i]->wentforweapon = 0;
4842 if (!dead && creature == wolftype) {
4843 award_bonus(0, Wolfbonus);
4846 if (unconscioustime < .1 && (bonus != spinecrusher || bonustime > 1) && (bonus != FinishedBonus || bonustime > 1) && bloodloss < damagetolerance)
4847 award_bonus(id, touchofdeath);
4848 if (id != 0 && unconscioustime > .1) {
4856 emit_sound_at(breaksound, coords);
4859 if (skeleton.free == 1) {
4861 pause_sound(whooshsound);
4864 //If knocked over, open hands and close mouth
4865 if (righthandmorphend != 0)
4866 righthandmorphness = 0;
4867 righthandmorphend = 0;
4868 targetrighthandmorphness = 1;
4870 if (lefthandmorphend != 0)
4871 lefthandmorphness = 0;
4872 lefthandmorphend = 0;
4873 targetlefthandmorphness = 1;
4875 if (headmorphend != 3 && headmorphend != 5 && headmorphstart != 3 && headmorphstart != 5) {
4876 if (headmorphend != 0)
4879 targetheadmorphness = 1;
4883 skeleton.DoGravity(&scale);
4885 damageamount = skeleton.DoConstraints(&coords, &scale) * 5;
4886 if (damage > damagetolerance - damageamount && !dead && (bonus != spinecrusher || bonustime > 1) && (bonus != style || bonustime > 1) && (bonus != cannon || bonustime > 1))
4887 award_bonus(id, deepimpact);
4888 DoDamage(damageamount / ((protectionhigh + protectionhead + protectionlow) / 3));
4892 for (j = 0; j < skeleton.num_joints; j++) {
4893 average += skeleton.joints[j].position;
4897 coords += average * scale;
4898 for (j = 0; j < skeleton.num_joints; j++) {
4899 skeleton.joints[j].position -= average;
4901 average /= multiplier;
4903 //velocity=jointVel(groin)*scale;
4905 for (i = 0; i < skeleton.num_joints; i++) {
4906 velocity += skeleton.joints[i].velocity * scale;
4908 velocity /= skeleton.num_joints;
4910 if (!isnormal(velocity.x) && velocity.x) {
4914 if (findLength(&average) < 10 && dead && skeleton.free) {
4915 skeleton.longdead += (2000 - findLength(&average)) * multiplier + multiplier;
4916 if (skeleton.longdead > 2000) {
4917 if (skeleton.longdead > 6000) {
4919 pause_sound(whooshsound);
4924 if (dead == 2 && bloodloss < damagetolerance) {
4926 headpoint = (jointPos(head) + jointPos(neck)) / 2 * scale + coords;
4928 if (bloodtoggle && !bled) {
4929 terrain.MakeDecal(blooddecal, headpoint, .2 * 1.2, .5, 0);
4931 if (bloodtoggle && !bled)
4932 for (l = 0; l < terrain.patchobjectnum[whichpatchx][whichpatchz]; l++) {
4933 j = terrain.patchobjects[whichpatchx][whichpatchz][l];
4934 XYZ point = DoRotation(headpoint - objects.position[j], 0, -objects.yaw[j], 0);
4935 float size = .2 * 1.2;
4938 objects.model[j].MakeDecal(blooddecal, &point, &size, &opacity, &yaw);
4942 if (dead == 2 && bloodloss >= damagetolerance) {
4944 headpoint = (jointPos(abdomen) + jointPos(neck)) / 2 * scale + coords;
4947 if (bloodtoggle && !bled) {
4948 terrain.MakeDecal(blooddecalslow, headpoint, .8, .5, 0);
4950 if (bloodtoggle && !bled)
4951 for (l = 0; l < terrain.patchobjectnum[whichpatchx][whichpatchz]; l++) {
4952 j = terrain.patchobjects[whichpatchx][whichpatchz][l];
4953 XYZ point = DoRotation(headpoint - objects.position[j], 0, -objects.yaw[j], 0);
4957 objects.model[j].MakeDecal(blooddecalslow, &point, &size, &opacity, &yaw);
4964 if (!dead && crouchkeydown && skeleton.freetime > .5 && id == 0 && skeleton.free) {
4965 bool canrecover = 1;
4966 XYZ startpoint, endpoint, colpoint, colviewer, coltarget;
4967 startpoint = coords;
4970 if (terrain.lineTerrain(startpoint, endpoint, &colpoint) != -1)
4972 if (velocity.y < -30)
4974 for (i = 0; i < objects.numobjects; i++) {
4975 if (objects.type[i] != treeleavestype && objects.type[i] != bushtype && objects.type[i] != firetype) {
4976 colviewer = startpoint;
4977 coltarget = endpoint;
4978 if (objects.model[i].LineCheck(&colviewer, &coltarget, &colpoint, &objects.position[i], &objects.yaw[i]) != -1)
4987 terrainnormal = jointPos(groin) - jointPos(abdomen);
4988 if (joint(groin).locked && joint(abdomen).locked) {
4989 terrainnormal = jointPos(groin) - jointPos(abdomen);
4990 middle = (jointPos(groin) + jointPos(abdomen)) / 2;
4992 if (joint(abdomen).locked && joint(neck).locked) {
4993 terrainnormal = jointPos(abdomen) - jointPos(neck);
4994 middle = (jointPos(neck) + jointPos(abdomen)) / 2;
4996 if (joint(groin).locked && joint(neck).locked) {
4997 terrainnormal = jointPos(groin) - jointPos(neck);
4998 middle = (jointPos(groin) + jointPos(neck)) / 2;
5000 Normalise(&terrainnormal);
5002 targetyaw = -asin(0 - terrainnormal.x);
5003 targetyaw *= 360 / 6.28;
5004 if (terrainnormal.z < 0)
5005 targetyaw = 180 - targetyaw;
5010 animTarget = flipanim;
5011 crouchtogglekeydown = 1;
5016 animCurrent = tempanim;
5019 //tilt2=targettilt2;
5021 //if(middle.y>0)targetoffset.y=middle.y+1;
5023 for (i = 0; i < skeleton.num_joints; i++) {
5024 tempanimation.position[i][0] = skeleton.joints[i].position;
5025 tempanimation.position[i][0] = DoRotation(tempanimation.position[i][0], 0, -yaw, 0);
5030 if (findLength(&average) < 10 && !dead && skeleton.free) {
5031 skeleton.longdead += (2000 - findLength(&average)) * multiplier + multiplier;
5032 if (skeleton.longdead > (damage + 500) * 1.5) {
5034 pause_sound(whooshsound);
5040 terrainnormal = jointPos(groin) - jointPos(abdomen);
5041 if (joint(groin).locked && joint(abdomen).locked) {
5042 terrainnormal = jointPos(groin) - jointPos(abdomen);
5043 middle = (jointPos(groin) + jointPos(abdomen)) / 2;
5045 if (joint(abdomen).locked && joint(neck).locked) {
5046 terrainnormal = jointPos(abdomen) - jointPos(neck);
5047 middle = (jointPos(neck) + jointPos(abdomen)) / 2;
5049 if (joint(groin).locked && joint(neck).locked) {
5050 terrainnormal = jointPos(groin) - jointPos(neck);
5051 middle = (jointPos(groin) + jointPos(neck)) / 2;
5053 Normalise(&terrainnormal);
5055 targetyaw = -asin(0 - terrainnormal.x);
5056 targetyaw *= 360 / 6.28;
5057 if (terrainnormal.z < 0)
5058 targetyaw = 180 - targetyaw;
5061 targettilt2 = asin(terrainnormal.y) * 180 / 3.14 * -1;
5064 if (skeleton.forward.y < 0) {
5065 animTarget = getupfrombackanim;
5069 if (skeleton.forward.y > -.3) {
5070 animTarget = getupfromfrontanim;
5078 if ((Random() % 8 == 0 && id != 0 && creature == rabbittype) || (Random() % 2 == 0 && id != 0 && creature == wolftype) || (id == 0 && crouchkeydown && (forwardkeydown || backkeydown || leftkeydown || rightkeydown))) {
5079 animTarget = rollanim;
5080 targetyaw = lookyaw;
5097 if ( !leftkeydown && !rightkeydown)
5104 if (abs(targettilt2) > 50)
5106 animCurrent = tempanim;
5109 tilt2 = targettilt2;
5111 if (middle.y > 0 && animTarget != rollanim)
5112 targetoffset.y = middle.y + 1;
5114 for (i = 0; i < skeleton.num_joints; i++) {
5115 tempanimation.position[i][0] = skeleton.joints[i].position;
5116 tempanimation.position[i][0] = DoRotation(tempanimation.position[i][0], 0, -yaw, 0);
5123 if (num_weapons > 0)
5124 if (weapons[0].getType() == staff)
5126 if (!skeleton.freefall && freefall && ((jumpkeydown && jumpkeydowntime < .2) || (hasstaff && rabbitkickragdoll)) && !dead) {
5127 if (velocity.y > -30) {
5129 tempvelocity = velocity;
5130 Normalise(&tempvelocity);
5131 targetyaw = -asin(0 - tempvelocity.x);
5132 targetyaw *= 360 / 6.28;
5134 targetyaw = 180 - targetyaw;
5138 if (dotproduct(&skeleton.forward, &tempvelocity) < 0) {
5139 animTarget = rollanim;
5142 animTarget = backhandspringanim;
5148 emit_sound_at(movewhooshsound, coords, 128.);
5150 animCurrent = animTarget;
5151 frameCurrent = frameTarget - 1;
5163 if (skeleton.freefall == 0)
5168 if (aitype != passivetype || skeleton.free == 1)
5169 if (findLengthfast(&velocity) > .1)
5170 for (i = 0; i < objects.numobjects; i++) {
5171 if (objects.type[i] == firetype)
5172 if (distsqflat(&coords, &objects.position[i]) < objects.scale[i]*objects.scale[i] * 12 && distsq(&coords, &objects.position[i]) < objects.scale[i]*objects.scale[i] * 49) {
5174 if (!objects.onfire[i]) {
5175 emit_sound_at(firestartsound, objects.position[i]);
5177 objects.onfire[i] = 1;
5180 if (objects.onfire[i]) {
5185 if (objects.type[i] == bushtype)
5186 if (distsqflat(&coords, &objects.position[i]) < objects.scale[i]*objects.scale[i] * 12 && distsq(&coords, &objects.position[i]) < objects.scale[i]*objects.scale[i] * 49) {
5188 if (!objects.onfire[i]) {
5189 emit_sound_at(firestartsound, objects.position[i]);
5191 objects.onfire[i] = 1;
5195 if (objects.onfire[i]) {
5199 if (objects.messedwith[i] <= 0) {
5203 emit_sound_at(bushrustle, coords, 40 * findLength(&velocity));
5206 envsound[numenvsounds] = coords;
5207 envsoundvol[numenvsounds] = 4 * findLength(&velocity);
5208 envsoundlife[numenvsounds] = .4;
5213 if (environment == grassyenvironment)
5214 howmany = findLength(&velocity) * 4;
5215 if (environment == snowyenvironment)
5216 howmany = findLength(&velocity) * 2;
5218 if (environment != desertenvironment)
5219 for (j = 0; j < howmany; j++) {
5220 tempvel.x = float(abs(Random() % 100) - 50) / 20;
5221 tempvel.y = float(abs(Random() % 100) - 50) / 20;
5222 tempvel.z = float(abs(Random() % 100) - 50) / 20;
5225 pos.x += float(abs(Random() % 100) - 50) / 200;
5226 pos.y += float(abs(Random() % 100) - 50) / 200;
5227 pos.z += float(abs(Random() % 100) - 50) / 200;
5228 Sprite::MakeSprite(splintersprite, pos, tempvel * .5 + velocity * float(abs(Random() % 100)) / 100, 165 / 255 + float(abs(Random() % 100) - 50) / 400, 0, 0, .2 + float(abs(Random() % 100) - 50) / 1300, 1);
5229 Sprite::setLastSpriteSpecial(1);
5231 howmany = findLength(&velocity) * 4;
5233 if (environment == snowyenvironment)
5234 for (j = 0; j < howmany; j++) {
5235 tempvel.x = float(abs(Random() % 100) - 50) / 20;
5236 tempvel.y = float(abs(Random() % 100) - 50) / 20;
5237 tempvel.z = float(abs(Random() % 100) - 50) / 20;
5240 pos.x += float(abs(Random() % 100) - 50) / 200;
5241 pos.y += float(abs(Random() % 100) - 50) / 200;
5242 pos.z += float(abs(Random() % 100) - 50) / 200;
5243 Sprite::MakeSprite(splintersprite, pos, tempvel * .3 + velocity * float(abs(Random() % 100)) / 100 / 2, 1, 1, 1, .1, 1);
5244 Sprite::setLastSpriteSpecial(2);
5247 objects.rotx[i] += velocity.x * multiplier * 6;
5248 objects.roty[i] += velocity.z * multiplier * 6;
5249 objects.messedwith[i] = .5;
5252 if (objects.type[i] == treeleavestype && environment != desertenvironment) {
5253 if (objects.pitch[i] == 0)
5256 tempcoord = coords - objects.position[i];
5257 tempcoord = DoRotation(tempcoord, 0, -objects.yaw[i], 0);
5258 tempcoord = DoRotation(tempcoord, -objects.pitch[i], 0, 0);
5259 tempcoord += objects.position[i];
5261 if (distsqflat(&tempcoord, &objects.position[i]) < objects.scale[i]*objects.scale[i] * 8 && distsq(&tempcoord, &objects.position[i]) < objects.scale[i]*objects.scale[i] * 300 && tempcoord.y > objects.position[i].y + 3 * objects.scale[i]) {
5262 if (objects.messedwith[i] <= 0) {
5266 emit_sound_at(bushrustle, coords, 40 * findLength(&velocity));
5269 envsound[numenvsounds] = coords;
5270 envsoundvol[numenvsounds] = 4 * findLength(&velocity);
5271 envsoundlife[numenvsounds] = .4;
5276 if (environment == grassyenvironment)
5277 howmany = findLength(&velocity) * 4;
5278 if (environment == snowyenvironment)
5279 howmany = findLength(&velocity) * 2;
5281 if (environment != desertenvironment)
5282 for (j = 0; j < howmany; j++) {
5283 tempvel.x = float(abs(Random() % 100) - 50) / 20;
5284 tempvel.y = float(abs(Random() % 100) - 50) / 20;
5285 tempvel.z = float(abs(Random() % 100) - 50) / 20;
5287 pos += velocity * .1;
5289 pos.x += float(abs(Random() % 100) - 50) / 150;
5290 pos.y += float(abs(Random() % 100) - 50) / 150;
5291 pos.z += float(abs(Random() % 100) - 50) / 150;
5292 Sprite::MakeSprite(splintersprite, pos, tempvel * .5 + velocity * float(abs(Random() % 100)) / 100, 165 / 255 + float(abs(Random() % 100) - 50) / 400, 0, 0, .2 + float(abs(Random() % 100) - 50) / 1300, 1);
5293 Sprite::setLastSpriteSpecial(1);
5295 howmany = findLength(&velocity) * 4;
5297 if (environment == snowyenvironment)
5298 for (j = 0; j < howmany; j++) {
5299 tempvel.x = float(abs(Random() % 100) - 50) / 20;
5300 tempvel.y = float(abs(Random() % 100) - 50) / 20;
5301 tempvel.z = float(abs(Random() % 100) - 50) / 20;
5303 pos += velocity * .1;
5305 pos.x += float(abs(Random() % 100) - 50) / 150;
5306 pos.y += float(abs(Random() % 100) - 50) / 150;
5307 pos.z += float(abs(Random() % 100) - 50) / 150;
5308 Sprite::MakeSprite(splintersprite, pos, tempvel * .3 + velocity * float(abs(Random() % 100)) / 100 / 2, 1, 1, 1, .1, 1);
5309 Sprite::setLastSpriteSpecial(2);
5312 objects.messedwith[i] = .5;
5317 if (!skeleton.free) {
5320 if ((stunned > 0 || surprised > 0) && Person::players.size() > 2 && aitype != passivetype)
5323 if (aitype != passivetype && victim->skeleton.free && !victim->dead)
5325 if (tutoriallevel == 1 && id != 0)
5327 if (play && aitype != playercontrolled) {
5328 int whichsound = -1;
5329 i = abs(Random() % 4);
5330 if (speechdelay <= 0) {
5331 if (creature == rabbittype) {
5333 whichsound = rabbitchitter;
5335 whichsound = rabbitchitter2;
5337 if (creature == wolftype) {
5339 whichsound = growlsound;
5341 whichsound = growl2sound;
5346 if (whichsound != -1) {
5347 emit_sound_at(whichsound, coords);
5351 if (animTarget == staggerbackhighanim)
5353 if (animTarget == staggerbackhardanim)
5355 staggerdelay -= multiplier;
5356 if (animTarget != crouchstabanim && animTarget != swordgroundstabanim && animTarget != staffgroundsmashanim)
5358 if (velocity.y < -30 && animTarget == jumpdownanim)
5360 if (animCurrent != getIdle() && wasIdle() && animTarget != getIdle() && isIdle()) {
5361 animTarget = getIdle();
5365 weaponmissdelay -= multiplier;
5366 highreversaldelay -= multiplier;
5367 lowreversaldelay -= multiplier;
5368 lastcollide -= multiplier;
5369 skiddelay -= multiplier;
5370 if (!isnormal(velocity.x) && velocity.x) {
5373 if (!isnormal(targettilt) && targettilt) {
5376 if (!isnormal(targettilt2) && targettilt2) {
5379 if (!isnormal(targetyaw) && targetyaw) {
5383 if (animTarget == bounceidleanim || animTarget == wolfidle || animTarget == walkanim || animTarget == drawrightanim || animTarget == crouchdrawrightanim || animTarget == drawleftanim || animTarget == fightidleanim || animTarget == fightsidestep || animTarget == hanganim || isCrouch() || animTarget == backhandspringanim) {
5384 //open hands and close mouth
5385 if (righthandmorphend != 0 && righthandmorphness == targetrighthandmorphness) {
5386 righthandmorphness = 0;
5387 righthandmorphend = 0;
5388 targetrighthandmorphness = 1;
5391 if (lefthandmorphend != 0 && lefthandmorphness == targetlefthandmorphness) {
5392 lefthandmorphness = 0;
5393 lefthandmorphend = 0;
5394 targetlefthandmorphness = 1;
5397 if (headmorphend != 3 && headmorphend != 5 && headmorphstart != 3 && headmorphstart != 5 && headmorphend != 0 && headmorphness == targetheadmorphness) {
5400 targetheadmorphness = 1;
5404 if (animTarget == rollanim || animTarget == dodgebackanim || animTarget == removeknifeanim || animTarget == knifefightidleanim || animTarget == swordfightidleanim || animTarget == blockhighleftstrikeanim || animTarget == crouchremoveknifeanim || animTarget == sneakanim || animTarget == sweepanim || animTarget == spinkickreversedanim || animTarget == jumpdownanim || isWallJump() || isFlip() || animTarget == climbanim || isRun() || animTarget == getupfrombackanim || animTarget == getupfromfrontanim) {
5405 //open hands and mouth
5406 if (righthandmorphend != 0 && righthandmorphness == targetrighthandmorphness) {
5407 righthandmorphness = 0;
5408 righthandmorphend = 0;
5409 targetrighthandmorphness = 1;
5412 if (lefthandmorphend != 0 && lefthandmorphness == targetlefthandmorphness) {
5413 lefthandmorphness = 0;
5414 lefthandmorphend = 0;
5415 targetlefthandmorphness = 1;
5418 if (headmorphend != 1 && headmorphness == targetheadmorphness) {
5421 targetheadmorphness = 1;
5425 if (animTarget == jumpupanim || animTarget == crouchstabanim || animTarget == swordgroundstabanim || animTarget == swordfightidlebothanim || animTarget == blockhighleftanim || animTarget == blockhighleftanim) {
5426 //close hands and mouth
5427 if (righthandmorphend != 1 && righthandmorphness == targetrighthandmorphness) {
5428 righthandmorphness = 0;
5429 righthandmorphend = 1;
5430 targetrighthandmorphness = 1;
5433 if (lefthandmorphend != 1 && lefthandmorphness == targetlefthandmorphness) {
5434 lefthandmorphness = 0;
5435 lefthandmorphend = 1;
5436 targetlefthandmorphness = 1;
5439 if (headmorphend != 0 && headmorphness == targetheadmorphness) {
5442 targetheadmorphness = 1;
5446 if (animTarget == spinkickanim || animTarget == staffspinhitreversalanim || animTarget == staffspinhitreversedanim || animTarget == staffhitreversalanim || animTarget == staffhitreversedanim || animTarget == hurtidleanim || animTarget == winduppunchanim || animTarget == swordslashreversalanim || animTarget == swordslashreversedanim || animTarget == knifeslashreversalanim || animTarget == knifeslashreversedanim || animTarget == knifethrowanim || animTarget == knifefollowanim || animTarget == knifefollowedanim || animTarget == killanim || animTarget == dropkickanim || animTarget == upunchanim || animTarget == knifeslashstartanim || animTarget == swordslashanim || animTarget == staffhitanim || animTarget == staffspinhitanim || animTarget == staffgroundsmashanim || animTarget == spinkickreversalanim || animTarget == sweepreversalanim || animTarget == lowkickanim || animTarget == sweepreversedanim || animTarget == rabbitkickreversalanim || animTarget == rabbitkickreversedanim || animTarget == jumpreversalanim || animTarget == jumpreversedanim) {
5447 //close hands and yell
5448 if (righthandmorphend != 1 && righthandmorphness == targetrighthandmorphness) {
5449 righthandmorphness = 0;
5450 righthandmorphend = 1;
5451 targetrighthandmorphness = 1;
5454 if (lefthandmorphend != 1 && lefthandmorphness == targetlefthandmorphness) {
5455 lefthandmorphness = 0;
5456 lefthandmorphend = 1;
5457 targetlefthandmorphness = 1;
5460 if (headmorphend != 2 && headmorphness == targetheadmorphness) {
5463 targetheadmorphness = 1;
5470 if ((victim != this->shared_from_this()) && !victim->dead && (victim->aitype != passivetype) &&
5471 (victim->aitype != searchtype) && (aitype != passivetype) &&
5472 (aitype != searchtype) && (victim->id < Person::players.size()) && (aitype != passivetype)) {
5473 behind = (normaldotproduct(facing, coords - victim->coords) > 0);
5477 if (!dead && animTarget != hurtidleanim)
5478 if (behind || animTarget == killanim || animTarget == knifethrowanim || animTarget == knifefollowanim || animTarget == spinkickreversalanim || animTarget == rabbitkickreversedanim || animTarget == jumpreversedanim) {
5479 if (headmorphend != 4 || headmorphness == targetheadmorphness) {
5482 targetheadmorphness = 1;
5486 if (weaponactive != -1) {
5487 if (weapons[weaponids[weaponactive]].getType() != staff) {
5488 righthandmorphstart = 1;
5489 righthandmorphend = 1;
5491 if (weapons[weaponids[weaponactive]].getType() == staff) {
5492 righthandmorphstart = 2;
5493 righthandmorphend = 2;
5495 targetrighthandmorphness = 1;
5498 terrainnormal = terrain.getNormal(coords.x, coords.z);
5500 if (animation[animTarget].attack != reversal) {
5501 if (!isnormal(coords.x))
5509 flatfacing = DoRotation(flatfacing, 0, yaw, 0);
5510 facing = flatfacing;
5511 ReflectVector(&facing, terrainnormal);
5514 if (isRun() || animTarget == sneakanim || animTarget == rollanim || animTarget == walkanim) {
5516 targettilt2 = -facing.y * 20;
5521 if (!isRun() && !animation[animTarget].attack && animTarget != getupfromfrontanim && animTarget != getupfrombackanim && animTarget != sneakanim)
5523 if (animTarget == jumpupanim || animTarget == jumpdownanim || isFlip()) {
5524 flatvelocity = velocity;
5526 flatvelspeed = findLength(&flatvelocity);
5527 targettilt = flatvelspeed * fast_sqrt(abs(velocity.y) * .7) * normaldotproduct(DoRotation(flatfacing, 0, -90, 0), flatvelocity);
5528 targettilt2 = flatvelspeed * fast_sqrt(abs(velocity.y) * .7) * normaldotproduct(flatfacing, flatvelocity);
5533 if (targettilt > 25)
5535 if (targettilt < -25)
5539 if (targettilt2 > 45)
5541 if (targettilt2 < -45)
5543 if (abs(tilt2 - targettilt2) < multiplier * 400)
5544 tilt2 = targettilt2;
5545 else if (tilt2 > targettilt2) {
5546 tilt2 -= multiplier * 400;
5547 } else if (tilt2 < targettilt2) {
5548 tilt2 += multiplier * 400;
5550 if (!animation[animTarget].attack && animTarget != getupfrombackanim && animTarget != getupfromfrontanim) {
5557 if (!isnormal(targettilt) && targettilt) {
5560 if (!isnormal(targettilt2) && targettilt2) {
5565 //if(!creature==wolftype||animTarget==rabbitkickanim)
5566 if (animTarget == rabbittackleanim) {
5567 velocity += facing * multiplier * speed * 700 * scale;
5568 velspeed = findLength(&velocity);
5569 if (velspeed > speed * 65 * scale) {
5570 velocity /= velspeed;
5571 velspeed = speed * 65 * scale;
5572 velocity *= velspeed;
5574 velocity.y += gravity * multiplier * 20;
5575 ReflectVector(&velocity, terrain.getNormal(coords.x, coords.z));
5576 velspeed = findLength(&velocity);
5577 velocity = flatfacing * velspeed;
5579 if (animTarget != rabbitrunninganim && animTarget != wolfrunninganim) {
5580 if (isRun() || animTarget == rabbitkickanim) {
5581 velocity += facing * multiplier * speed * 700 * scale;
5582 velspeed = findLength(&velocity);
5583 if (velspeed > speed * 45 * scale) {
5584 velocity /= velspeed;
5585 velspeed = speed * 45 * scale;
5586 velocity *= velspeed;
5588 velocity.y += gravity * multiplier * 20;
5589 ReflectVector(&velocity, terrain.getNormal(coords.x, coords.z));
5590 velspeed = findLength(&velocity);
5591 if (velspeed < speed * 30 * scale)
5592 velspeed = speed * 30 * scale;
5593 velocity = flatfacing * velspeed;
5595 } else if (isRun()) {
5596 velocity += facing * multiplier * speed * 700 * scale;
5597 velspeed = findLength(&velocity);
5598 if (creature == rabbittype) {
5599 if (velspeed > speed * 55 * scale) {
5600 velocity /= velspeed;
5601 velspeed = speed * 55 * scale;
5602 velocity *= velspeed;
5605 if (creature == wolftype) {
5606 if (velspeed > speed * 75 * scale) {
5607 velocity /= velspeed;
5608 velspeed = speed * 75 * scale;
5609 velocity *= velspeed;
5612 velocity.y += gravity * multiplier * 20;
5613 ReflectVector(&velocity, terrain.getNormal(coords.x, coords.z));
5614 velspeed = findLength(&velocity);
5615 velocity = flatfacing * velspeed;
5618 if (animTarget == rollanim && animation[animTarget].label[frameTarget] != 6) {
5619 velocity += facing * multiplier * speed * 700 * scale;
5620 velspeed = findLength(&velocity);
5621 if (velspeed > speed * 45 * scale) {
5622 velocity /= velspeed;
5623 velspeed = speed * 45 * scale;
5624 velocity *= velspeed;
5626 velocity.y += gravity * multiplier * 20;
5627 ReflectVector(&velocity, terrain.getNormal(coords.x, coords.z));
5628 velspeed = findLength(&velocity);
5629 velocity = flatfacing * velspeed;
5633 /*if(animCurrent==rollanim&&(isCrouch()||isIdle())){
5634 velocity+=facing*multiplier*speed*700*scale;
5635 velspeed=findLength(&velocity);
5636 if(velspeed>speed*25*scale){
5638 velspeed=speed*25*scale;
5641 velocity.y+=gravity*multiplier*20;
5642 ReflectVector(&velocity,terrain.getNormal(coords.x,coords.z));
5643 velspeed=findLength(&velocity);
5644 velocity=flatfacing*velspeed;
5647 if (animTarget == sneakanim || animTarget == walkanim) {
5648 velocity += facing * multiplier * speed * 700 * scale;
5649 velspeed = findLength(&velocity);
5650 if (velspeed > speed * 12 * scale) {
5651 velocity /= velspeed;
5652 velspeed = speed * 12 * scale;
5653 velocity *= velspeed;
5655 velocity.y += gravity * multiplier * 20;
5656 ReflectVector(&velocity, terrain.getNormal(coords.x, coords.z));
5657 velspeed = findLength(&velocity);
5658 velocity = flatfacing * velspeed;
5661 if ((animTarget == fightidleanim || animTarget == knifefightidleanim) && (animCurrent == bounceidleanim || animCurrent == hurtidleanim)) {
5662 velocity += facing * multiplier * speed * 700 * scale;
5663 velspeed = findLength(&velocity);
5664 if (velspeed > speed * 2 * scale) {
5665 velocity /= velspeed;
5666 velspeed = speed * 2 * scale;
5667 velocity *= velspeed;
5669 velocity.y += gravity * multiplier * 20;
5670 ReflectVector(&velocity, terrain.getNormal(coords.x, coords.z));
5671 velspeed = findLength(&velocity);
5672 velocity = flatfacing * velspeed;
5676 if ((animTarget == bounceidleanim || animCurrent == hurtidleanim) && (animCurrent == fightidleanim || animCurrent == knifefightidleanim)) {
5677 velocity -= facing * multiplier * speed * 700 * scale;
5678 velspeed = findLength(&velocity);
5679 if (velspeed > speed * 2 * scale) {
5680 velocity /= velspeed;
5681 velspeed = speed * 2 * scale;
5682 velocity *= velspeed;
5684 velocity.y += gravity * multiplier * 20;
5685 ReflectVector(&velocity, terrain.getNormal(coords.x, coords.z));
5686 velspeed = findLength(&velocity);
5687 velocity = flatfacing * velspeed * -1;
5690 if (animTarget == fightsidestep) {
5691 velocity += DoRotation(facing * multiplier * speed * 700 * scale, 0, -90, 0);
5692 velspeed = findLength(&velocity);
5693 if (velspeed > speed * 12 * scale) {
5694 velocity /= velspeed;
5695 velspeed = speed * 12 * scale;
5696 velocity *= velspeed;
5698 velocity.y += gravity * multiplier * 20;
5699 ReflectVector(&velocity, terrain.getNormal(coords.x, coords.z));
5700 velspeed = findLength(&velocity);
5701 velocity = DoRotation(flatfacing * velspeed, 0, -90, 0);
5704 if (animTarget == staggerbackhighanim) {
5705 coords -= facing * multiplier * speed * 16 * scale;
5708 if (animTarget == staggerbackhardanim && animation[staggerbackhardanim].label[frameTarget] != 6) {
5709 coords -= facing * multiplier * speed * 20 * scale;
5713 if (animTarget == backhandspringanim) {
5714 //coords-=facing*multiplier*50*scale;
5715 velocity += facing * multiplier * speed * 700 * scale * -1;
5716 velspeed = findLength(&velocity);
5717 if (velspeed > speed * 50 * scale) {
5718 velocity /= velspeed;
5719 velspeed = speed * 50 * scale;
5720 velocity *= velspeed;
5722 velocity.y += gravity * multiplier * 20;
5723 ReflectVector(&velocity, terrain.getNormal(coords.x, coords.z));
5724 velspeed = findLength(&velocity);
5725 velocity = flatfacing * velspeed * -1;
5727 if (animTarget == dodgebackanim) {
5728 //coords-=facing*multiplier*50*scale;
5729 velocity += facing * multiplier * speed * 700 * scale * -1;
5730 velspeed = findLength(&velocity);
5731 if (velspeed > speed * 60 * scale) {
5732 velocity /= velspeed;
5733 velspeed = speed * 60 * scale;
5734 velocity *= velspeed;
5736 velocity.y += gravity * multiplier * 20;
5737 ReflectVector(&velocity, terrain.getNormal(coords.x, coords.z));
5738 velspeed = findLength(&velocity);
5739 velocity = flatfacing * velspeed * -1;
5742 if (animTarget == jumpupanim || animTarget == jumpdownanim || isFlip()) {
5743 velspeed = findLength(&velocity);
5747 if (animTarget == jumpupanim || animTarget == jumpdownanim || isFlip()) {
5748 velocity.y += gravity * multiplier;
5751 if (animTarget != climbanim && animTarget != hanganim && !isWallJump())
5752 coords += velocity * multiplier;
5754 if (coords.y < terrain.getHeight(coords.x, coords.z) && (animTarget == jumpdownanim || animTarget == jumpupanim || isFlip())) {
5755 if (isFlip() && animation[animTarget].label[frameTarget] == 7)
5758 if (animTarget == jumpupanim) {
5760 animTarget = getIdle();
5767 pause_sound(whooshsound);
5768 OPENAL_SetVolume(channels[whooshsound], 0);
5771 if (animTarget == jumpdownanim || isFlip()) {
5772 if (isFlip())jumppower = -4;
5773 animTarget = getLanding();
5774 emit_sound_at(landsound, coords, 128.);
5777 envsound[numenvsounds] = coords;
5778 envsoundvol[numenvsounds] = 16;
5779 envsoundlife[numenvsounds] = .4;
5785 if (animTarget != jumpupanim && animTarget != jumpdownanim && !isFlip() && animTarget != climbanim && animTarget != hanganim && !isWallJump())
5786 coords.y += gravity * multiplier * 2;
5787 if (animTarget != jumpupanim && animTarget != jumpdownanim && !isFlip() && coords.y < terrain.getHeight(coords.x, coords.z)) {
5788 coords.y = terrain.getHeight(coords.x, coords.z);
5793 if (isIdle() || animTarget == drawrightanim || animTarget == drawleftanim || animTarget == crouchdrawrightanim || animTarget == crouchstabanim || animTarget == swordgroundstabanim || isStop() || animTarget == removeknifeanim || animTarget == crouchremoveknifeanim || isLanding() || isCrouch() || animation[animTarget].attack || (animTarget == rollanim && animation[animTarget].label[frameTarget] == 6)) {
5794 velspeed = findLength(&velocity);
5796 if (velspeed < multiplier * 300 * scale) {
5799 velocity -= velocity / velspeed * multiplier * 300 * scale;
5800 if (velspeed > 5 && (isLanding() || isLandhard())) {
5801 skiddingdelay += multiplier;
5802 if (skiddelay <= 0) {
5812 velspeed = findLength(&velocity);
5814 if (velspeed < multiplier * 600 * scale) {
5817 velocity -= velocity / velspeed * multiplier * 600 * scale;
5819 if (velspeed > 5 && (isLanding() || isLandhard())) {
5820 skiddingdelay += multiplier;
5821 if (skiddelay <= 0) {
5830 if (skiddingdelay < 0)
5831 skiddingdelay += multiplier;
5832 if (skiddingdelay > .02 && !forwardkeydown && !backkeydown && !leftkeydown && !rightkeydown && !jumpkeydown && isLanding() && !landhard) {
5834 if (!onterrain || environment == grassyenvironment) {
5835 emit_sound_at(skidsound, coords, 128 * velspeed / 10);
5837 emit_sound_at(snowskidsound, coords, 128 * velspeed / 10);
5841 if (animation[animTarget].attack == normalattack && animTarget != rabbitkickanim && !victim->skeleton.free) {
5842 terrainnormal = victim->coords - coords;
5843 Normalise(&terrainnormal);
5844 targetyaw = -asin(0 - terrainnormal.x);
5845 targetyaw *= 360 / 6.28;
5846 if (terrainnormal.z < 0)
5847 targetyaw = 180 - targetyaw;
5848 targettilt2 = -asin(terrainnormal.y) * 360 / 6.28; //*-70;
5851 if (animation[animTarget].attack == reversal && animTarget != rabbittacklinganim) {
5852 targetyaw = victim->targetyaw;
5854 if (animTarget == rabbittacklinganim) {
5855 coords = victim->coords;
5858 skeleton.oldfree = skeleton.free;
5862 midterrain.x = terrain.size * terrain.scale / 2;
5863 midterrain.z = terrain.size * terrain.scale / 2;
5864 if (distsqflat(&coords, &midterrain) > (terrain.size * terrain.scale / 2 - viewdistance) * (terrain.size * terrain.scale / 2 - viewdistance)) {
5866 tempposit = coords - midterrain;
5868 Normalise(&tempposit);
5869 tempposit *= (terrain.size * terrain.scale / 2 - viewdistance);
5870 coords.x = tempposit.x + midterrain.x;
5871 coords.z = tempposit.z + midterrain.z;
5877 * inverse kinematics helper function
5879 void IKHelper(Person *p, float interp)
5881 XYZ point, newpoint, change, change2;
5882 float heightleft, heightright;
5884 // TODO: implement localToWorld and worldToLocal
5885 // but keep in mind it won't be the same math if player is ragdolled or something
5886 // - localToWorldStanding / worldToLocalStanding (or crouching or...?)
5887 // then comb through code for places where to use it
5889 // point = localToWorld(jointPos(leftfoot))
5890 point = DoRotation(p->jointPos(leftfoot), 0, p->yaw, 0) * p->scale + p->coords;
5891 // adjust height of foot
5892 heightleft = terrain.getHeight(point.x, point.z) + .04;
5893 point.y = heightleft;
5894 change = p->jointPos(leftankle) - p->jointPos(leftfoot);
5895 change2 = p->jointPos(leftknee) - p->jointPos(leftfoot);
5896 // jointPos(leftfoot) = interpolate(worldToLocal(point), jointPos(leftfoot), interp)
5897 p->jointPos(leftfoot) = DoRotation((point - p->coords) / p->scale, 0, -p->yaw, 0) * interp + p->jointPos(leftfoot) * (1 - interp);
5898 // move ankle along with foot
5899 p->jointPos(leftankle) = p->jointPos(leftfoot) + change;
5900 // average knee pos between old and new pos
5901 p->jointPos(leftknee) = (p->jointPos(leftfoot) + change2) / 2 + (p->jointPos(leftknee)) / 2;
5903 // do same as above for right leg
5904 point = DoRotation(p->jointPos(rightfoot), 0, p->yaw, 0) * p->scale + p->coords;
5905 heightright = terrain.getHeight(point.x, point.z) + .04;
5906 point.y = heightright;
5907 change = p->jointPos(rightankle) - p->jointPos(rightfoot);
5908 change2 = p->jointPos(rightknee) - p->jointPos(rightfoot);
5909 p->jointPos(rightfoot) = DoRotation((point - p->coords) / p->scale, 0, -p->yaw, 0) * interp + p->jointPos(rightfoot) * (1 - interp);
5910 p->jointPos(rightankle) = p->jointPos(rightfoot) + change;
5911 p->jointPos(rightknee) = (p->jointPos(rightfoot) + change2) / 2 + (p->jointPos(rightknee)) / 2;
5913 // fix up skeleton now that we've moved body parts?
5914 p->skeleton.DoConstraints(&p->coords, &p->scale);
5921 int Person::DrawSkeleton()
5923 int oldplayerdetail;
5924 if ((frustum.SphereInFrustum(coords.x, coords.y + scale * 3, coords.z, scale * 8) && distsq(&viewer, &coords) < viewdistance * viewdistance) || skeleton.free == 3) {
5925 if (onterrain && (isIdle() || isCrouch() || wasIdle() || wasCrouch()) && !skeleton.free) {
5935 glAlphaFunc(GL_GREATER, 0.0001);
5937 float terrainheight;
5941 if (!isnormal(tilt))
5943 if (!isnormal(tilt2))
5945 oldplayerdetail = playerdetail;
5947 if (distsq(&viewer, &coords) < viewdistance * viewdistance / 32 && detail == 2) {
5950 if (distsq(&viewer, &coords) < viewdistance * viewdistance / 128 && detail == 1) {
5953 if (distsq(&viewer, &coords) < viewdistance * viewdistance / 256 && (detail != 1 && detail != 2)) {
5958 if (playerdetail != oldplayerdetail) {
5960 normalsupdatedelay = 0;
5962 static float updatedelaychange;
5963 static float morphness;
5964 static float framemult;
5966 skeleton.FindForwards();
5967 if (howactive == typesittingwall) {
5968 skeleton.specialforward[1] = 0;
5969 skeleton.specialforward[1].z = 1;
5975 static int weaponattachmuscle;
5976 static int weaponrotatemuscle;
5977 static XYZ weaponpoint;
5978 static int start, endthing;
5979 if ((dead != 2 || skeleton.free != 2) && updatedelay <= 0) {
5980 if (!isSleeping() && !isSitting()) {
5981 // TODO: give these meaningful names
5982 const bool cond1 = (isIdle() || isCrouch() || isLanding() || isLandhard()
5983 || animTarget == drawrightanim || animTarget == drawleftanim || animTarget == crouchdrawrightanim);
5984 const bool cond2 = (wasIdle() || wasCrouch() || wasLanding() || wasLandhard()
5985 || animCurrent == drawrightanim || animCurrent == drawleftanim || animCurrent == crouchdrawrightanim);
5987 if (onterrain && (cond1 && cond2) && !skeleton.free) {
5989 if (creature == wolftype)
5993 if (onterrain && (cond1 && !cond2) && !skeleton.free) {
5994 IKHelper(this, target);
5995 if (creature == wolftype)
5996 IKHelper(this, target);
5999 if (onterrain && (!cond1 && cond2) && !skeleton.free) {
6000 IKHelper(this, 1 - target);
6001 if (creature == wolftype)
6002 IKHelper(this, 1 - target);
6006 if (!skeleton.free && (!animation[animTarget].attack && animTarget != getupfrombackanim && ((animTarget != rollanim && !isFlip()) || animation[animTarget].label[frameTarget] == 6) && animTarget != getupfromfrontanim && animTarget != wolfrunninganim && animTarget != rabbitrunninganim && animTarget != backhandspringanim && animTarget != walljumpfrontanim && animTarget != hurtidleanim && !isLandhard() && !isSleeping()))
6009 targetheadyaw = -targetyaw;
6010 targetheadpitch = 0;
6011 if (animation[animTarget].attack == 3)
6012 targetheadyaw += 180;
6014 for (i = 0; i < skeleton.drawmodel.vertexNum; i++) {
6015 skeleton.drawmodel.vertex[i] = 0;
6016 skeleton.drawmodel.vertex[i].y = 999;
6018 for (i = 0; i < skeleton.drawmodellow.vertexNum; i++) {
6019 skeleton.drawmodellow.vertex[i] = 0;
6020 skeleton.drawmodellow.vertex[i].y = 999;
6022 for (i = 0; i < skeleton.drawmodelclothes.vertexNum; i++) {
6023 skeleton.drawmodelclothes.vertex[i] = 0;
6024 skeleton.drawmodelclothes.vertex[i].y = 999;
6026 for (i = 0; i < skeleton.num_muscles; i++) {
6027 // convenience renames
6028 const int p1 = skeleton.muscles[i].parent1->label;
6029 const int p2 = skeleton.muscles[i].parent2->label;
6031 if ((skeleton.muscles[i].numvertices > 0 && playerdetail) || (skeleton.muscles[i].numverticeslow > 0 && !playerdetail)) {
6036 if (p1 == righthand || p2 == righthand) {
6037 morphness = righthandmorphness;
6038 start = righthandmorphstart;
6039 endthing = righthandmorphend;
6041 if (p1 == lefthand || p2 == lefthand) {
6042 morphness = lefthandmorphness;
6043 start = lefthandmorphstart;
6044 endthing = lefthandmorphend;
6046 if (p1 == head || p2 == head) {
6047 morphness = headmorphness;
6048 start = headmorphstart;
6049 endthing = headmorphend;
6051 if ((p1 == neck && p2 == abdomen) || (p2 == neck && p1 == abdomen)) {
6052 morphness = chestmorphness;
6053 start = chestmorphstart;
6054 endthing = chestmorphend;
6056 if ((p1 == groin && p2 == abdomen) || (p2 == groin && p1 == abdomen)) {
6057 morphness = tailmorphness;
6058 start = tailmorphstart;
6059 endthing = tailmorphend;
6062 skeleton.FindRotationMuscle(i, animTarget);
6063 mid = (skeleton.muscles[i].parent1->position + skeleton.muscles[i].parent2->position) / 2;
6064 glMatrixMode(GL_MODELVIEW);
6068 glRotatef(tilt2, 1, 0, 0);
6070 glRotatef(tilt, 0, 0, 1);
6073 glTranslatef(mid.x, mid.y, mid.z);
6075 skeleton.muscles[i].lastrotate1 = skeleton.muscles[i].rotate1;
6076 glRotatef(-skeleton.muscles[i].lastrotate1 + 90, 0, 1, 0);
6078 skeleton.muscles[i].lastrotate2 = skeleton.muscles[i].rotate2;
6079 glRotatef(-skeleton.muscles[i].lastrotate2 + 90, 0, 0, 1);
6081 skeleton.muscles[i].lastrotate3 = skeleton.muscles[i].rotate3;
6082 glRotatef(-skeleton.muscles[i].lastrotate3, 0, 1, 0);
6084 if (playerdetail || skeleton.free == 3) {
6085 for (j = 0; j < skeleton.muscles[i].numvertices; j++) {
6086 XYZ &v0 = skeleton.model[start].vertex[skeleton.muscles[i].vertices[j]];
6087 XYZ &v1 = skeleton.model[endthing].vertex[skeleton.muscles[i].vertices[j]];
6088 glMatrixMode(GL_MODELVIEW);
6090 if (p1 == abdomen || p2 == abdomen)
6091 glTranslatef((v0.x * (1 - morphness) + v1.x * morphness) * proportionbody.x,
6092 (v0.y * (1 - morphness) + v1.y * morphness) * proportionbody.y,
6093 (v0.z * (1 - morphness) + v1.z * morphness) * proportionbody.z);
6094 if (p1 == lefthand || p1 == righthand || p1 == leftwrist || p1 == rightwrist || p1 == leftelbow || p1 == rightelbow || p2 == leftelbow || p2 == rightelbow)
6095 glTranslatef((v0.x * (1 - morphness) + v1.x * morphness) * proportionarms.x,
6096 (v0.y * (1 - morphness) + v1.y * morphness) * proportionarms.y,
6097 (v0.z * (1 - morphness) + v1.z * morphness) * proportionarms.z);
6098 if (p1 == leftfoot || p1 == rightfoot || p1 == leftankle || p1 == rightankle || p1 == leftknee || p1 == rightknee || p2 == leftknee || p2 == rightknee)
6099 glTranslatef((v0.x * (1 - morphness) + v1.x * morphness) * proportionlegs.x,
6100 (v0.y * (1 - morphness) + v1.y * morphness) * proportionlegs.y,
6101 (v0.z * (1 - morphness) + v1.z * morphness) * proportionlegs.z);
6102 if (p1 == head || p2 == head)
6103 glTranslatef((v0.x * (1 - morphness) + v1.x * morphness) * proportionhead.x,
6104 (v0.y * (1 - morphness) + v1.y * morphness) * proportionhead.y,
6105 (v0.z * (1 - morphness) + v1.z * morphness) * proportionhead.z);
6106 glGetFloatv(GL_MODELVIEW_MATRIX, M);
6107 //if(!isnormal(M[12])||!isnormal(M[13])||!isnormal(M[14]))test=0;
6108 //if(!isnormal(scale))test=1;
6109 skeleton.drawmodel.vertex[skeleton.muscles[i].vertices[j]].x = M[12] * scale;
6110 skeleton.drawmodel.vertex[skeleton.muscles[i].vertices[j]].y = M[13] * scale;
6111 skeleton.drawmodel.vertex[skeleton.muscles[i].vertices[j]].z = M[14] * scale;
6116 if (!playerdetail || skeleton.free == 3) {
6117 for (j = 0; j < skeleton.muscles[i].numverticeslow; j++) {
6118 XYZ &v0 = skeleton.modellow.vertex[skeleton.muscles[i].verticeslow[j]];
6119 glMatrixMode(GL_MODELVIEW);
6121 if (p1 == abdomen || p2 == abdomen)
6122 glTranslatef(v0.x * proportionbody.x,
6123 v0.y * proportionbody.y,
6124 v0.z * proportionbody.z);
6125 if (p1 == lefthand || p1 == righthand || p1 == leftwrist || p1 == rightwrist || p1 == leftelbow || p1 == rightelbow || p2 == leftelbow || p2 == rightelbow)
6126 glTranslatef(v0.x * proportionarms.x,
6127 v0.y * proportionarms.y,
6128 v0.z * proportionarms.z);
6129 if (p1 == leftfoot || p1 == rightfoot || p1 == leftankle || p1 == rightankle || p1 == leftknee || p1 == rightknee || p2 == leftknee || p2 == rightknee)
6130 glTranslatef(v0.x * proportionlegs.x,
6131 v0.y * proportionlegs.y,
6132 v0.z * proportionlegs.z);
6133 if (p1 == head || p2 == head)
6134 glTranslatef(v0.x * proportionhead.x,
6135 v0.y * proportionhead.y,
6136 v0.z * proportionhead.z);
6138 glGetFloatv(GL_MODELVIEW_MATRIX, M);
6139 skeleton.drawmodellow.vertex[skeleton.muscles[i].verticeslow[j]].x = M[12] * scale;
6140 skeleton.drawmodellow.vertex[skeleton.muscles[i].verticeslow[j]].y = M[13] * scale;
6141 skeleton.drawmodellow.vertex[skeleton.muscles[i].verticeslow[j]].z = M[14] * scale;
6147 if (skeleton.clothes && skeleton.muscles[i].numverticesclothes > 0) {
6148 mid = (skeleton.muscles[i].parent1->position + skeleton.muscles[i].parent2->position) / 2;
6150 glMatrixMode(GL_MODELVIEW);
6154 glRotatef(tilt2, 1, 0, 0);
6156 glRotatef(tilt, 0, 0, 1);
6157 glTranslatef(mid.x, mid.y, mid.z);
6158 skeleton.muscles[i].lastrotate1 = skeleton.muscles[i].rotate1;
6159 glRotatef(-skeleton.muscles[i].lastrotate1 + 90, 0, 1, 0);
6161 skeleton.muscles[i].lastrotate2 = skeleton.muscles[i].rotate2;
6162 glRotatef(-skeleton.muscles[i].lastrotate2 + 90, 0, 0, 1);
6164 skeleton.muscles[i].lastrotate3 = skeleton.muscles[i].rotate3;
6165 glRotatef(-skeleton.muscles[i].lastrotate3, 0, 1, 0);
6167 for (j = 0; j < skeleton.muscles[i].numverticesclothes; j++) {
6168 XYZ &v0 = skeleton.modelclothes.vertex[skeleton.muscles[i].verticesclothes[j]];
6169 glMatrixMode(GL_MODELVIEW);
6171 if (p1 == abdomen || p2 == abdomen)
6172 glTranslatef(v0.x * proportionbody.x,
6173 v0.y * proportionbody.y,
6174 v0.z * proportionbody.z);
6175 if (p1 == lefthand || p1 == righthand || p1 == leftwrist || p1 == rightwrist || p1 == leftelbow || p1 == rightelbow || p2 == leftelbow || p2 == rightelbow)
6176 glTranslatef(v0.x * proportionarms.x,
6177 v0.y * proportionarms.y,
6178 v0.z * proportionarms.z);
6179 if (p1 == leftfoot || p1 == rightfoot || p1 == leftankle || p1 == rightankle || p1 == leftknee || p1 == rightknee || p2 == leftknee || p2 == rightknee)
6180 glTranslatef(v0.x * proportionlegs.x,
6181 v0.y * proportionlegs.y,
6182 v0.z * proportionlegs.z);
6183 if (p1 == head || p2 == head)
6184 glTranslatef(v0.x * proportionhead.x,
6185 v0.y * proportionhead.y,
6186 v0.z * proportionhead.z);
6187 glGetFloatv(GL_MODELVIEW_MATRIX, M);
6188 skeleton.drawmodelclothes.vertex[skeleton.muscles[i].verticesclothes[j]].x = M[12] * scale;
6189 skeleton.drawmodelclothes.vertex[skeleton.muscles[i].verticesclothes[j]].y = M[13] * scale;
6190 skeleton.drawmodelclothes.vertex[skeleton.muscles[i].verticesclothes[j]].z = M[14] * scale;
6195 updatedelay = 1 + (float)(Random() % 100) / 1000;
6197 if (skeleton.free != 2 && (skeleton.free == 1 || skeleton.free == 3 || id == 0 || (normalsupdatedelay <= 0) || animTarget == getupfromfrontanim || animTarget == getupfrombackanim || animCurrent == getupfromfrontanim || animCurrent == getupfrombackanim)) {
6198 normalsupdatedelay = 1;
6199 if (playerdetail || skeleton.free == 3)
6200 skeleton.drawmodel.CalculateNormals(0);
6201 if (!playerdetail || skeleton.free == 3)
6202 skeleton.drawmodellow.CalculateNormals(0);
6203 if (skeleton.clothes)
6204 skeleton.drawmodelclothes.CalculateNormals(0);
6206 if (playerdetail || skeleton.free == 3)
6207 skeleton.drawmodel.UpdateVertexArrayNoTexNoNorm();
6208 if (!playerdetail || skeleton.free == 3)
6209 skeleton.drawmodellow.UpdateVertexArrayNoTexNoNorm();
6210 if (skeleton.clothes) {
6211 skeleton.drawmodelclothes.UpdateVertexArrayNoTexNoNorm();
6216 updatedelaychange = -framemult * 4 * (45 - findDistance(&viewer, &coords) * 1);
6217 if (updatedelaychange > -realmultiplier * 30)
6218 updatedelaychange = -realmultiplier * 30;
6219 if (updatedelaychange > -framemult * 4)
6220 updatedelaychange = -framemult * 4;
6221 if (skeleton.free == 1)
6222 updatedelaychange *= 6;
6224 updatedelaychange *= 8;
6225 updatedelay += updatedelaychange;
6227 glMatrixMode(GL_MODELVIEW);
6230 glTranslatef(coords.x, coords.y - .02, coords.z);
6232 glTranslatef(coords.x, coords.y - .02, coords.z);
6234 glTranslatef(offset.x * scale, offset.y * scale, offset.z * scale);
6236 glRotatef(yaw, 0, 1, 0);
6239 glColor4f(.4, 1, .4, 1);
6240 glDisable(GL_LIGHTING);
6241 glDisable(GL_TEXTURE_2D);
6244 for (i = 0; i < skeleton.drawmodel.vertexNum; i++) {
6245 XYZ &v0 = skeleton.drawmodel.vertex[i];
6246 glVertex3f(v0.x, v0.y, v0.z);
6252 for (i = 0; i < skeleton.drawmodel.TriangleNum; i++) {
6253 XYZ &v0 = skeleton.drawmodel.vertex[skeleton.drawmodel.Triangles[i].vertex[0]];
6254 XYZ &v1 = skeleton.drawmodel.vertex[skeleton.drawmodel.Triangles[i].vertex[1]];
6255 XYZ &v2 = skeleton.drawmodel.vertex[skeleton.drawmodel.Triangles[i].vertex[2]];
6256 glVertex3f(v0.x, v0.y, v0.z);
6257 glVertex3f(v1.x, v1.y, v1.z);
6258 glVertex3f(v1.x, v1.y, v1.z);
6259 glVertex3f(v2.x, v2.y, v2.z);
6260 glVertex3f(v2.x, v2.y, v2.z);
6261 glVertex3f(v0.x, v0.y, v0.z);
6267 terrainlight = terrain.getLighting(coords.x, coords.z);
6268 distance = distsq(&viewer, &coords);
6269 distance = (viewdistance * viewdistance - (distance - (viewdistance * viewdistance * fadestart)) * (1 / (1 - fadestart))) / viewdistance / viewdistance;
6273 terrainheight = (coords.y - terrain.getHeight(coords.x, coords.z)) / 3 + 1;
6274 if (terrainheight < 1)
6276 if (terrainheight > 1.7)
6277 terrainheight = 1.7;
6280 glColor4f((1 - (1 - terrainlight.x) / terrainheight) - burnt, (1 - (1 - terrainlight.y) / terrainheight) - burnt, (1 - (1 - terrainlight.z) / terrainheight) - burnt, distance);
6281 glDisable(GL_BLEND);
6282 glAlphaFunc(GL_GREATER, 0.0001);
6283 glEnable(GL_TEXTURE_2D);
6285 glDisable(GL_TEXTURE_2D);
6286 glColor4f(.7, .35, 0, .5);
6288 glEnable(GL_LIGHTING);
6291 if (tutoriallevel && id != 0) {
6292 //glDisable(GL_TEXTURE_2D);
6293 glColor4f(.7, .7, .7, 0.6);
6295 glEnable(GL_LIGHTING);
6297 if (canattack && cananger)
6298 if (animation[animTarget].attack == normalattack || animation[animTarget].attack == reversed) {
6299 glDisable(GL_TEXTURE_2D);
6300 glColor4f(1, 0, 0, 0.8);
6302 glMatrixMode(GL_TEXTURE);
6304 glTranslatef(0, -smoketex, 0);
6305 glTranslatef(-smoketex, 0, 0);
6309 if ((tutoriallevel && id != 0))
6310 skeleton.drawmodel.drawdifftex(Sprite::cloudimpacttexture);
6312 skeleton.drawmodel.draw();
6315 if (!playerdetail) {
6316 if ((tutoriallevel && id != 0))
6317 skeleton.drawmodellow.drawdifftex(Sprite::cloudimpacttexture);
6319 skeleton.drawmodellow.drawdifftex(skeleton.drawmodel.textureptr);
6322 if (!(animation[animTarget].attack == normalattack || animation[animTarget].attack == reversed))
6323 if (tutoriallevel && id != 0) {
6325 glMatrixMode(GL_MODELVIEW);
6326 glEnable(GL_TEXTURE_2D);
6327 glColor4f(.7, .7, .7, 0.6);
6329 glEnable(GL_LIGHTING);
6331 if (canattack && cananger)
6332 if (animation[animTarget].attack == normalattack || animation[animTarget].attack == reversed) {
6333 glDisable(GL_TEXTURE_2D);
6334 glColor4f(1, 0, 0, 0.8);
6336 glMatrixMode(GL_TEXTURE);
6338 glTranslatef(0, -smoketex * .6, 0);
6339 glTranslatef(smoketex * .6, 0, 0);
6342 if ((tutoriallevel && id != 0))
6343 skeleton.drawmodel.drawdifftex(Sprite::cloudimpacttexture);
6345 skeleton.drawmodel.draw();
6348 if (!playerdetail) {
6349 if ((tutoriallevel && id != 0))
6350 skeleton.drawmodellow.drawdifftex(Sprite::cloudimpacttexture);
6352 skeleton.drawmodellow.drawdifftex(skeleton.drawmodel.textureptr);
6357 if (tutoriallevel && id != 0) {
6359 glMatrixMode(GL_MODELVIEW);
6360 glEnable(GL_TEXTURE_2D);
6362 if (skeleton.clothes) {
6366 skeleton.drawmodelclothes.draw();
6368 skeleton.drawmodelclothes.drawimmediate();
6374 if (num_weapons > 0) {
6375 for (k = 0; k < num_weapons; k++) {
6377 if (weaponactive == k) {
6378 if (weapons[i].getType() != staff) {
6379 for (j = 0; j < skeleton.num_muscles; j++) {
6380 if ((skeleton.muscles[j].parent1->label == righthand || skeleton.muscles[j].parent2->label == righthand) && skeleton.muscles[j].numvertices > 0) {
6381 weaponattachmuscle = j;
6384 for (j = 0; j < skeleton.num_muscles; j++) {
6385 if ((skeleton.muscles[j].parent1->label == rightwrist || skeleton.muscles[j].parent2->label == rightwrist) && (skeleton.muscles[j].parent1->label != righthand && skeleton.muscles[j].parent2->label != righthand) && skeleton.muscles[j].numvertices > 0) {
6386 weaponrotatemuscle = j;
6389 weaponpoint = (skeleton.muscles[weaponattachmuscle].parent1->position + skeleton.muscles[weaponattachmuscle].parent2->position) / 2;
6390 if (creature == wolftype)
6391 weaponpoint = (jointPos(rightwrist) * .7 + jointPos(righthand) * .3);
6393 if (weapons[i].getType() == staff) {
6394 for (j = 0; j < skeleton.num_muscles; j++) {
6395 if ((skeleton.muscles[j].parent1->label == righthand || skeleton.muscles[j].parent2->label == righthand) && skeleton.muscles[j].numvertices > 0) {
6396 weaponattachmuscle = j;
6399 for (j = 0; j < skeleton.num_muscles; j++) {
6400 if ((skeleton.muscles[j].parent1->label == rightelbow || skeleton.muscles[j].parent2->label == rightelbow) && (skeleton.muscles[j].parent1->label != rightshoulder && skeleton.muscles[j].parent2->label != rightshoulder) && skeleton.muscles[j].numvertices > 0) {
6401 weaponrotatemuscle = j;
6404 //weaponpoint=jointPos(rightwrist);
6405 weaponpoint = (skeleton.muscles[weaponattachmuscle].parent1->position + skeleton.muscles[weaponattachmuscle].parent2->position) / 2;
6406 //weaponpoint+=skeleton.specialforward[1]*.1+(jointPos(rightwrist)-jointPos(rightelbow));
6407 XYZ tempnormthing, vec1, vec2;
6408 vec1 = (jointPos(rightwrist) - jointPos(rightelbow));
6409 vec2 = (jointPos(rightwrist) - jointPos(rightshoulder));
6410 CrossProduct(&vec1, &vec2, &tempnormthing);
6411 Normalise(&tempnormthing);
6412 if (animTarget != staffhitanim && animCurrent != staffhitanim && animTarget != staffgroundsmashanim && animCurrent != staffgroundsmashanim && animTarget != staffspinhitanim && animCurrent != staffspinhitanim)
6413 weaponpoint += tempnormthing * .1 - skeleton.specialforward[1] * .3 + (jointPos(rightwrist) - jointPos(rightelbow));
6416 if (weaponactive != k && weaponstuck != k) {
6417 if (weapons[i].getType() == knife)
6418 weaponpoint = jointPos(abdomen) + (jointPos(righthip) - jointPos(lefthip)) * .1 + (jointPos(rightshoulder) - jointPos(leftshoulder)) * .35;
6419 if (weapons[i].getType() == sword)
6420 weaponpoint = jointPos(abdomen) + (jointPos(lefthip) - jointPos(righthip)) * .09 + (jointPos(leftshoulder) - jointPos(rightshoulder)) * .33;
6421 if (weapons[i].getType() == staff)
6422 weaponpoint = jointPos(abdomen) + (jointPos(lefthip) - jointPos(righthip)) * .09 + (jointPos(leftshoulder) - jointPos(rightshoulder)) * .33;
6423 for (j = 0; j < skeleton.num_muscles; j++) {
6424 if ((skeleton.muscles[j].parent1->label == abdomen || skeleton.muscles[j].parent2->label == abdomen) && (skeleton.muscles[j].parent1->label == neck || skeleton.muscles[j].parent2->label == neck) && skeleton.muscles[j].numvertices > 0) {
6425 weaponrotatemuscle = j;
6429 if (weaponstuck == k) {
6430 if (weaponstuckwhere == 0)
6431 weaponpoint = jointPos(abdomen) * .5 + jointPos(neck) * .5 - skeleton.forward * .8;
6433 weaponpoint = jointPos(abdomen) * .5 + jointPos(neck) * .5 + skeleton.forward * .8;
6434 for (j = 0; j < skeleton.num_muscles; j++) {
6435 if ((skeleton.muscles[j].parent1->label == abdomen || skeleton.muscles[j].parent2->label == abdomen) && (skeleton.muscles[j].parent1->label == neck || skeleton.muscles[j].parent2->label == neck) && skeleton.muscles[j].numvertices > 0) {
6436 weaponrotatemuscle = j;
6440 if (skeleton.free) {
6441 weapons[i].position = weaponpoint * scale + coords;
6442 weapons[i].bigrotation = 0;
6443 weapons[i].bigtilt = 0;
6444 weapons[i].bigtilt2 = 0;
6446 weapons[i].position = DoRotation(DoRotation(DoRotation(weaponpoint, 0, 0, tilt), tilt2, 0, 0), 0, yaw, 0) * scale + coords + currentoffset * (1 - target) * scale + targetoffset * target * scale;
6447 weapons[i].bigrotation = yaw;
6448 weapons[i].bigtilt = tilt;
6449 weapons[i].bigtilt2 = tilt2;
6451 weapons[i].rotation1 = skeleton.muscles[weaponrotatemuscle].lastrotate1;
6452 weapons[i].rotation2 = skeleton.muscles[weaponrotatemuscle].lastrotate2;
6453 weapons[i].rotation3 = skeleton.muscles[weaponrotatemuscle].lastrotate3;
6454 if (weaponactive == k) {
6455 if (weapons[i].getType() == knife) {
6456 weapons[i].smallrotation = 180;
6457 weapons[i].smallrotation2 = 0;
6458 if (isCrouch() || wasCrouch()) {
6459 weapons[i].smallrotation2 = 20;
6461 if (animTarget == hurtidleanim) {
6462 weapons[i].smallrotation2 = 50;
6464 if ((animCurrent == crouchstabanim && animTarget == crouchstabanim) || (animCurrent == backhandspringanim && animTarget == backhandspringanim)) {
6465 XYZ temppoint1, temppoint2, tempforward;
6468 temppoint1 = jointPos(righthand);
6469 temppoint2 = animation[animCurrent].weapontarget[frameCurrent] * (1 - target) + animation[animTarget].weapontarget[frameTarget] * (target);
6470 distance = findDistance(&temppoint1, &temppoint2);
6471 weapons[i].rotation2 = asin((temppoint1.y - temppoint2.y) / distance);
6472 weapons[i].rotation2 *= 360 / 6.28;
6475 weapons[i].rotation1 = acos((temppoint1.z - temppoint2.z) / findDistance(&temppoint1, &temppoint2));
6476 weapons[i].rotation1 *= 360 / 6.28;
6477 weapons[i].rotation3 = 0;
6478 weapons[i].smallrotation = -90;
6479 weapons[i].smallrotation2 = 0;
6480 if (temppoint1.x > temppoint2.x)
6481 weapons[i].rotation1 = 360 - weapons[i].rotation1;
6483 if ((animCurrent == knifeslashreversalanim && animTarget == knifeslashreversalanim) || (animCurrent == knifeslashreversedanim && animTarget == knifeslashreversedanim)) {
6484 XYZ temppoint1, temppoint2, tempforward;
6487 temppoint1 = jointPos(righthand);
6488 temppoint2 = animation[animCurrent].weapontarget[frameCurrent] * (1 - target) + animation[animTarget].weapontarget[frameTarget] * (target);
6489 distance = findDistance(&temppoint1, &temppoint2);
6490 weapons[i].rotation2 = asin((temppoint1.y - temppoint2.y) / distance);
6491 weapons[i].rotation2 *= 360 / 6.28;
6494 weapons[i].rotation1 = acos((temppoint1.z - temppoint2.z) / findDistance(&temppoint1, &temppoint2));
6495 weapons[i].rotation1 *= 360 / 6.28;
6496 weapons[i].rotation3 = 0;
6497 weapons[i].smallrotation = 90;
6498 weapons[i].smallrotation2 = 0;
6499 if (temppoint1.x > temppoint2.x)
6500 weapons[i].rotation1 = 360 - weapons[i].rotation1;
6502 if (animTarget == knifethrowanim) {
6503 weapons[i].smallrotation = 90;
6504 //weapons[i].smallrotation2=-90;
6505 weapons[i].smallrotation2 = 0;
6506 weapons[i].rotation1 = 0;
6507 weapons[i].rotation2 = 0;
6508 weapons[i].rotation3 = 0;
6510 if (animTarget == knifesneakattackanim && frameTarget < 5) {
6511 weapons[i].smallrotation = -90;
6512 weapons[i].rotation1 = 0;
6513 weapons[i].rotation2 = 0;
6514 weapons[i].rotation3 = 0;
6517 if (weapons[i].getType() == sword) {
6518 weapons[i].smallrotation = 0;
6519 weapons[i].smallrotation2 = 0;
6520 if (animTarget == knifethrowanim) {
6521 weapons[i].smallrotation = -90;
6522 weapons[i].smallrotation2 = 0;
6523 weapons[i].rotation1 = 0;
6524 weapons[i].rotation2 = 0;
6525 weapons[i].rotation3 = 0;
6527 if ((animTarget == swordgroundstabanim && animCurrent == swordgroundstabanim) || (animTarget == swordsneakattackanim && animCurrent == swordsneakattackanim) || (animTarget == swordslashparryanim && animCurrent == swordslashparryanim) || (animTarget == swordslashparriedanim && animCurrent == swordslashparriedanim) || (animTarget == swordslashreversalanim && animCurrent == swordslashreversalanim) || (animTarget == swordslashreversedanim && animCurrent == swordslashreversedanim) || (animTarget == knifeslashreversalanim && animCurrent == knifeslashreversalanim) || (animTarget == knifeslashreversedanim && animCurrent == knifeslashreversedanim) || (animTarget == swordslashanim && animCurrent == swordslashanim) || (animTarget == drawleftanim && animCurrent == drawleftanim) || (animCurrent == backhandspringanim && animTarget == backhandspringanim)) {
6528 XYZ temppoint1, temppoint2, tempforward;
6531 temppoint1 = animation[animCurrent].position[skeleton.jointlabels[righthand]][frameCurrent] * (1 - target) + animation[animTarget].position[skeleton.jointlabels[righthand]][frameTarget] * (target); //jointPos(righthand);
6532 temppoint2 = animation[animCurrent].weapontarget[frameCurrent] * (1 - target) + animation[animTarget].weapontarget[frameTarget] * (target);
6533 distance = findDistance(&temppoint1, &temppoint2);
6534 weapons[i].rotation2 = asin((temppoint1.y - temppoint2.y) / distance);
6535 weapons[i].rotation2 *= 360 / 6.28;
6538 weapons[i].rotation1 = acos((temppoint1.z - temppoint2.z) / findDistance(&temppoint1, &temppoint2));
6539 weapons[i].rotation1 *= 360 / 6.28;
6540 weapons[i].rotation3 = 0;
6541 weapons[i].smallrotation = 90;
6542 weapons[i].smallrotation2 = 0;
6543 if (temppoint1.x > temppoint2.x)
6544 weapons[i].rotation1 = 360 - weapons[i].rotation1;
6547 if (weapons[i].getType() == staff) {
6548 weapons[i].smallrotation = 100;
6549 weapons[i].smallrotation2 = 0;
6550 if ((animTarget == staffhitanim && animCurrent == staffhitanim) || (animTarget == staffhitreversedanim && animCurrent == staffhitreversedanim) || (animTarget == staffspinhitreversedanim && animCurrent == staffspinhitreversedanim) || (animTarget == staffgroundsmashanim && animCurrent == staffgroundsmashanim) || (animTarget == staffspinhitanim && animCurrent == staffspinhitanim)) {
6551 XYZ temppoint1, temppoint2, tempforward;
6554 temppoint1 = animation[animCurrent].position[skeleton.jointlabels[righthand]][frameCurrent] * (1 - target) + animation[animTarget].position[skeleton.jointlabels[righthand]][frameTarget] * (target); //jointPos(righthand);
6555 temppoint2 = animation[animCurrent].weapontarget[frameCurrent] * (1 - target) + animation[animTarget].weapontarget[frameTarget] * (target);
6556 distance = findDistance(&temppoint1, &temppoint2);
6557 weapons[i].rotation2 = asin((temppoint1.y - temppoint2.y) / distance);
6558 weapons[i].rotation2 *= 360 / 6.28;
6561 weapons[i].rotation1 = acos((temppoint1.z - temppoint2.z) / findDistance(&temppoint1, &temppoint2));
6562 weapons[i].rotation1 *= 360 / 6.28;
6563 weapons[i].rotation3 = 0;
6564 weapons[i].smallrotation = 90;
6565 weapons[i].smallrotation2 = 0;
6566 if (temppoint1.x > temppoint2.x)
6567 weapons[i].rotation1 = 360 - weapons[i].rotation1;
6571 if (weaponactive != k && weaponstuck != k) {
6572 if (weapons[i].getType() == knife) {
6573 weapons[i].smallrotation = -70;
6574 weapons[i].smallrotation2 = 10;
6576 if (weapons[i].getType() == sword) {
6577 weapons[i].smallrotation = -100;
6578 weapons[i].smallrotation2 = -8;
6580 if (weapons[i].getType() == staff) {
6581 weapons[i].smallrotation = -100;
6582 weapons[i].smallrotation2 = -8;
6585 if (weaponstuck == k) {
6586 if (weaponstuckwhere == 0)
6587 weapons[i].smallrotation = 180;
6589 weapons[i].smallrotation = 0;
6590 weapons[i].smallrotation2 = 10;
6599 if (animation[animTarget].attack || isRun() || animTarget == staggerbackhardanim || isFlip() || animTarget == climbanim || animTarget == sneakanim || animTarget == rollanim || animTarget == walkanim || animTarget == backhandspringanim || isFlip() || isWallJump())
6601 if (animCurrent != animTarget)
6603 //if(id==0)calcrot=1;
6604 if (skeleton.free == 2)
6613 int Person::SphereCheck(XYZ *p1, float radius, XYZ *p, XYZ *move, float *rotate, Model *model)
6616 static float distance;
6617 static float olddistance;
6618 static int intersecting;
6619 static int firstintersecting;
6622 static XYZ start, end;
6623 static float slopethreshold = -.4;
6625 firstintersecting = -1;
6629 if (distsq(p1, &model->boundingspherecenter) > radius * radius + model->boundingsphereradius * model->boundingsphereradius)
6632 *p1 = DoRotation(*p1, 0, -*rotate, 0);
6633 for (i = 0; i < 4; i++) {
6634 for (j = 0; j < model->TriangleNum; j++) {
6635 if (model->facenormals[j].y <= slopethreshold) {
6637 distance = abs((model->facenormals[j].x * p1->x) + (model->facenormals[j].y * p1->y) + (model->facenormals[j].z * p1->z) - ((model->facenormals[j].x * model->vertex[model->Triangles[j].vertex[0]].x) + (model->facenormals[j].y * model->vertex[model->Triangles[j].vertex[0]].y) + (model->facenormals[j].z * model->vertex[model->Triangles[j].vertex[0]].z)));
6638 if (distance < radius) {
6639 point = *p1 - model->facenormals[j] * distance;
6640 if (PointInTriangle( &point, model->facenormals[j], &model->vertex[model->Triangles[j].vertex[0]], &model->vertex[model->Triangles[j].vertex[1]], &model->vertex[model->Triangles[j].vertex[2]]))
6643 intersecting = sphere_line_intersection(&model->vertex[model->Triangles[j].vertex[0]],
6644 &model->vertex[model->Triangles[j].vertex[1]],
6647 intersecting = sphere_line_intersection(&model->vertex[model->Triangles[j].vertex[1]],
6648 &model->vertex[model->Triangles[j].vertex[2]],
6651 intersecting = sphere_line_intersection(&model->vertex[model->Triangles[j].vertex[0]],
6652 &model->vertex[model->Triangles[j].vertex[2]],
6655 if (dotproduct(&model->facenormals[j], &end) > 0 && intersecting) {
6659 if (LineFacetd(&start, &end, &model->vertex[model->Triangles[j].vertex[0]], &model->vertex[model->Triangles[j].vertex[1]], &model->vertex[model->Triangles[j].vertex[2]], &model->facenormals[j], &point)) {
6660 p1->y = point.y + radius;
6661 if ((animTarget == jumpdownanim || isFlip())) {
6662 if (isFlip() && (frameTarget < 5 || animation[animTarget].label[frameTarget] == 7 || animation[animTarget].label[frameTarget] == 4))
6665 if (animTarget == jumpupanim) {
6667 animTarget = getIdle();
6674 pause_sound(whooshsound);
6675 OPENAL_SetVolume(channels[whooshsound], 0);
6678 if ((animTarget == jumpdownanim || isFlip()) && !wasLanding() && !wasLandhard()) {
6681 animTarget = getLanding();
6682 emit_sound_at(landsound, coords, 128.);
6685 envsound[numenvsounds] = coords;
6686 envsoundvol[numenvsounds] = 16;
6687 envsoundlife[numenvsounds] = .4;
6695 if ((distance < olddistance || firstintersecting == -1) && intersecting) {
6696 olddistance = distance;
6697 firstintersecting = j;
6702 for (j = 0; j < model->TriangleNum; j++) {
6703 if (model->facenormals[j].y > slopethreshold) {
6706 start.y -= radius / 4;
6707 XYZ &v0 = model->vertex[model->Triangles[j].vertex[0]];
6708 XYZ &v1 = model->vertex[model->Triangles[j].vertex[1]];
6709 XYZ &v2 = model->vertex[model->Triangles[j].vertex[2]];
6710 distance = abs((model->facenormals[j].x * start.x)
6711 + (model->facenormals[j].y * start.y)
6712 + (model->facenormals[j].z * start.z)
6713 - ((model->facenormals[j].x * v0.x)
6714 + (model->facenormals[j].y * v0.y)
6715 + (model->facenormals[j].z * v0.z)));
6716 if (distance < radius * .5) {
6717 point = start - model->facenormals[j] * distance;
6718 if (PointInTriangle( &point, model->facenormals[j], &v0, &v1, &v2))
6721 intersecting = sphere_line_intersection(v0.x, v0.y, v0.z, v1.x, v1.y, v1.z, p1->x, p1->y, p1->z, radius / 2);
6723 intersecting = sphere_line_intersection(v1.x, v1.y, v1.z, v2.x, v2.y, v2.z, p1->x, p1->y, p1->z, radius / 2);
6725 intersecting = sphere_line_intersection(v0.x, v0.y, v0.z, v2.x, v2.y, v2.z, p1->x, p1->y, p1->z, radius / 2);
6727 if (dotproduct(&model->facenormals[j], &end) > 0 && intersecting) {
6728 if ((animTarget == jumpdownanim || animTarget == jumpupanim || isFlip())) {
6730 velocity -= DoRotation(model->facenormals[j], 0, *rotate, 0) * findLength(&velocity) * abs(normaldotproduct(velocity, DoRotation(model->facenormals[j], 0, *rotate, 0))); //(distance-radius*.5)/multiplier;
6731 if (findLengthfast(&start) < findLengthfast(&velocity))
6734 *p1 += model->facenormals[j] * (distance - radius * .5);
6737 if ((distance < olddistance || firstintersecting == -1) && intersecting) {
6738 olddistance = distance;
6739 firstintersecting = j;
6746 *p = DoRotation(*p, 0, *rotate, 0);
6749 *p1 = DoRotation(*p1, 0, *rotate, 0);
6751 return firstintersecting;