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 Person player[maxplayers];
88 /* convenience functions
90 Joint& Person::joint(int bodypart) { return skeleton.joints[skeleton.jointlabels[bodypart]]; }
91 XYZ& Person::jointPos(int bodypart) { return joint(bodypart).position; }
92 XYZ& Person::jointVel(int bodypart) { return joint(bodypart).velocity; }
97 * GameTick/doPlayerCollisions
99 void Person::CheckKick()
102 && (animTarget == rabbitkickanim
106 && animCurrent == rabbitkickanim)
107 && distsq(&coords, &victim->coords) < 1.2
108 && !victim->skeleton.free))
111 if (animation[victim->animTarget].height != lowheight) {
112 float damagemult = (creature == wolftype ? 2.5 : 1.) * power * power;
113 XYZ relative = velocity;
115 Normalise(&relative);
119 if (tutoriallevel != 1)
120 emit_sound_at(heavyimpactsound, victim->coords);
122 for (int i = 0; i < victim->skeleton.num_joints; i++) {
123 victim->skeleton.joints[i].velocity += relative * 120 * damagemult;
126 victim->DoDamage(100 * damagemult / victim->protectionhigh);
132 animTarget = backflipanim;
134 velocity = facing * -10;
138 resume_stream(whooshsound);
140 award_bonus(id, cannon);
141 } else if (victim->isCrouch()) {
142 animTarget = rabbitkickreversedanim;
143 animCurrent = rabbitkickreversedanim;
144 victim->animCurrent = rabbitkickreversalanim;
145 victim->animTarget = rabbitkickreversalanim;
151 victim->oldcoords = victim->coords;
152 coords = victim->coords;
153 victim->targetyaw = targetyaw;
154 victim->victim = this;
161 * GameTick/doPlayerCollisions - spread fire between players
162 * GameTick/doDebugKeys - press f to ignite
163 * Person::DoStuff - spread fire from lit campfires and bushes
165 void Person::CatchFire()
167 XYZ flatfacing, flatvelocity;
169 for (int i = 0; i < 10; i++) {
170 howmany = abs(Random() % (skeleton.num_joints));
172 flatvelocity = velocity;
174 flatvelocity = skeleton.joints[howmany].velocity;
176 flatfacing = DoRotation(DoRotation(DoRotation(skeleton.joints[howmany].position, 0, 0, tilt), tilt2, 0, 0), 0, yaw, 0) * scale + coords;
178 flatfacing = skeleton.joints[howmany].position * scale + coords;
179 Sprite::MakeSprite(flamesprite, flatfacing, flatvelocity, 1, 1, 1, 2, 1);
184 emit_sound_at(firestartsound, coords);
186 emit_stream_at(stream_firesound, coords);
194 * idle animation for this creature (depending on status)
196 int Person::getIdle()
198 if (indialogue != -1 && howactive == typeactive && creature == rabbittype)
200 if (hasvictim && victim != this/*||(id==0&&attackkeydown)*/)
201 if (/*(id==0&&attackkeydown)||*/(!victim->dead && victim->aitype != passivetype && victim->aitype != searchtype && aitype != passivetype && aitype != searchtype && victim->id < numplayers)) {
202 if ((aitype == playercontrolled && stunned <= 0 && weaponactive == -1) || pause) {
203 if (creature == rabbittype)
204 return fightidleanim;
205 if (creature == wolftype)
208 if (aitype == playercontrolled && stunned <= 0 && weaponactive != -1) {
209 if (weapons[weaponids[weaponactive]].getType() == knife)
210 return knifefightidleanim;
211 if (weapons[weaponids[weaponactive]].getType() == sword && victim->weaponactive != -1)
212 return swordfightidlebothanim;
213 if (weapons[weaponids[weaponactive]].getType() == sword)
214 return swordfightidleanim;
215 if (weapons[weaponids[weaponactive]].getType() == staff)
216 return swordfightidleanim;
218 if (aitype != playercontrolled && stunned <= 0 && creature != wolftype && !pause)
219 return fightsidestep;
221 if ((damage > permanentdamage || damage > damagetolerance * .8 || deathbleeding > 0) && creature != wolftype)
223 if (howactive == typesitting) return sitanim;
224 if (howactive == typesittingwall) return sitwallanim;
225 if (howactive == typesleeping) return sleepanim;
226 if (howactive == typedead1) return dead1anim;
227 if (howactive == typedead2) return dead2anim;
228 if (howactive == typedead3) return dead3anim;
229 if (howactive == typedead4) return dead4anim;
230 if (creature == rabbittype) return bounceidleanim;
231 if (creature == wolftype) return wolfidle;
236 * crouch animation for this creature
238 int Person::getCrouch()
240 if (creature == rabbittype)
242 if (creature == wolftype)
243 return wolfcrouchanim;
248 * running animation for this creature (can be upright or all fours)
252 if (creature == rabbittype && (!superruntoggle || weaponactive != -1))
254 if (creature == wolftype && (!superruntoggle))
257 if (creature == rabbittype && (superruntoggle && weaponactive == -1))
258 return rabbitrunninganim;
259 if (creature == wolftype && (superruntoggle))
260 return wolfrunninganim;
266 int Person::getStop()
268 if (creature == rabbittype)
270 if (creature == wolftype)
277 int Person::getLanding()
279 if (creature == rabbittype)
281 if (creature == wolftype)
288 int Person::getLandhard()
290 if (creature == rabbittype)
292 if (creature == wolftype)
293 return wolflandhardanim;
300 * Person::DoAnimations
303 SolidHitBonus(int playerid)
305 if (bonustime < 1.5 && bonus >= solidhit && bonus <= megacombo)
306 award_bonus(playerid, bonus == megacombo ? bonus : bonus + 1);
308 award_bonus(playerid, solidhit);
312 * spawns blood effects
314 void Person::DoBlood(float howmuch, int which)
316 // FIXME: should abstract out inputs
317 static int bleedxint, bleedyint;
319 //if(howmuch&&id==0)blooddimamount=1;
320 if (bloodtoggle && tutoriallevel != 1) {
321 if (bleeding <= 0 && spurt) {
323 for (int i = 0; i < 3; i++) {
324 // emit blood particles
326 if (!skeleton.free) {
328 bloodvel = DoRotation(bloodvel, ((float)(Random() % 100)) / 4, yaw + ((float)(Random() % 100)) / 4, 0) * scale;
331 bloodvel -= DoRotation(skeleton.forward * 10 * scale, ((float)(Random() % 100)) / 4, ((float)(Random() % 100)) / 4, 0);
334 bloodvel += DoRotation(jointVel(head), ((float)(Random() % 100)) / 4, yaw + ((float)(Random() % 100)) / 4, 0) * scale;
336 bloodvel += DoRotation(velocity, ((float)(Random() % 100)) / 4, ((float)(Random() % 100)) / 4, 0) * scale;
338 Sprite::MakeSprite(bloodsprite, jointPos(head) * scale + coords, bloodvel, 1, 1, 1, .05, 1);
339 Sprite::MakeSprite(bloodflamesprite, jointPos(head) * scale + coords, bloodvel, 1, 1, 1, .3, 1);
341 if (!skeleton.free) {
342 Sprite::MakeSprite(bloodsprite, DoRotation((jointPos(head) + jointPos(neck)) / 2, 0, yaw, 0)*scale + coords, bloodvel, 1, 1, 1, .05, 1);
343 Sprite::MakeSprite(bloodflamesprite, DoRotation((jointPos(head) + jointPos(neck)) / 2, 0, yaw, 0)*scale + coords, bloodvel, 1, 1, 1, .3, 1);
346 if (Random() % 2 == 0) // 50% chance
347 for (int i = 0; i < 3; i++) {
348 if (Random() % 2 != 0) {
349 // emit teeth particles
352 bloodvel -= DoRotation(skeleton.forward * 10 * scale, ((float)(Random() % 100)) / 4, ((float)(Random() % 100)) / 4, 0);
353 bloodvel += DoRotation(jointVel(head), ((float)(Random() % 100)) / 4, yaw + ((float)(Random() % 100)) / 4, 0) * scale;
356 bloodvel = DoRotation(bloodvel, ((float)(Random() % 100)) / 4, yaw + ((float)(Random() % 100)) / 4, 0) * scale;
357 bloodvel += DoRotation(velocity, ((float)(Random() % 100)) / 4, ((float)(Random() % 100)) / 4, 0) * scale;
361 Sprite::MakeSprite(splintersprite, jointPos(head) * scale + coords, bloodvel, 1, 1, 1, .05, 1);
363 Sprite::MakeSprite(splintersprite, DoRotation((jointPos(head) + jointPos(neck)) / 2, 0, yaw, 0)*scale + coords, bloodvel, 1, 1, 1, .05, 1);
365 Sprite::setLastSpriteSpecial(3); // sets it to teeth
370 // FIXME: manipulating attributes
371 bleeding = howmuch + (float)abs(Random() % 100) / 200 - .25;
374 if (creature == rabbittype)
375 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) {
376 bleedxint = abs(Random() % 512);
377 bleedyint = abs(Random() % 512);
379 if (creature == wolftype)
380 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) {
381 bleedxint = abs(Random() % 512);
382 bleedyint = abs(Random() % 512);
386 bleedy /= realtexdetail;
387 bleedx /= realtexdetail;
388 direction = abs(Random() % 2) * 2 - 1;
397 * spawns big blood effects and ???
398 * modifies character's skin texture
400 void Person::DoBloodBig(float howmuch, int which)
402 static int bleedxint, bleedyint, i, j;
404 if (howmuch && id == 0)
407 if (tutoriallevel != 1 || id == 0)
408 if (aitype != playercontrolled && howmuch > 0) {
412 // FIXME: seems to be spawning sounds by manipulating attributes... MESSY!
413 if (creature == wolftype) {
414 int i = abs(Random() % 2);
416 whichsound = snarlsound;
418 whichsound = snarl2sound;
419 envsound[numenvsounds] = coords;
420 envsoundvol[numenvsounds] = 16;
421 envsoundlife[numenvsounds] = .4;
424 if (creature == rabbittype) {
425 int i = abs(Random() % 2);
427 whichsound = rabbitpainsound;
428 if (i == 1 && howmuch >= 2)
429 whichsound = rabbitpain1sound;
430 envsound[numenvsounds] = coords;
431 envsoundvol[numenvsounds] = 16;
432 envsoundlife[numenvsounds] = .4;
434 //if(i==2)whichsound=rabbitpain2sound;
437 if (whichsound != -1)
438 emit_sound_at(whichsound, coords);
441 if (id == 0 && howmuch > 0) {
442 // FIXME: manipulating attributes
450 if (bloodtoggle && decals && tutoriallevel != 1) {
451 if (bleeding <= 0 && spurt) {
453 for (int i = 0; i < 3; i++) {
454 // emit blood particles
455 // FIXME: copypaste from above
457 if (!skeleton.free) {
459 bloodvel = DoRotation(bloodvel, ((float)(Random() % 100)) / 4, yaw + ((float)(Random() % 100)) / 4, 0) * scale;
462 bloodvel -= DoRotation(skeleton.forward * 10 * scale, ((float)(Random() % 100)) / 4, ((float)(Random() % 100)) / 4, 0);
465 bloodvel += DoRotation(jointVel(head), ((float)(Random() % 100)) / 4, yaw + ((float)(Random() % 100)) / 4, 0) * scale;
467 bloodvel += DoRotation(velocity, ((float)(Random() % 100)) / 4, ((float)(Random() % 100)) / 4, 0) * scale;
469 Sprite::MakeSprite(bloodsprite, jointPos(head) * scale + coords, bloodvel, 1, 1, 1, .05, 1);
470 Sprite::MakeSprite(bloodflamesprite, jointPos(head) * scale + coords, bloodvel, 1, 1, 1, .3, 1);
472 if (!skeleton.free) {
473 Sprite::MakeSprite(bloodsprite, DoRotation((jointPos(head) + jointPos(neck)) / 2, 0, yaw, 0)*scale + coords, bloodvel, 1, 1, 1, .05, 1);
474 Sprite::MakeSprite(bloodflamesprite, DoRotation((jointPos(head) + jointPos(neck)) / 2, 0, yaw, 0)*scale + coords, bloodvel, 1, 1, 1, .3, 1);
479 // weird texture manipulation code follows.
480 // looks like this is painting blood onto the character's skin texture
481 // FIXME: surely there's a better way
483 int offsetx = 0, offsety = 0;
485 offsety = Random() % 40;
486 offsetx = abs(Random() % 60);
488 if (which == 190 || which == 185) {
489 offsety = Random() % 40;
490 offsetx = abs(Random() % 100) - 20;
493 offsety = Random() % 10;
494 offsetx = Random() % 10;
497 offsety = Random() % 20;
498 offsetx = Random() % 20;
500 if (which == 220 || which == 215) {
510 if (creature == rabbittype)
511 for (i = 0; i < 512; i++) {
512 for (j = 0; j < 512; j++) {
513 if (bloodText[i*512*3 + j*3 + 0] <= which + 4 && bloodText[i*512*3 + j*3 + 0] >= which - 4) {
514 if (i < startx) startx = i;
515 if (j < starty) starty = j;
516 if (i > endx) endx = i;
517 if (j > endy) endy = j;
521 if (creature == wolftype)
522 for (i = 0; i < 512; i++) {
523 for (j = 0; j < 512; j++) {
524 if (wolfbloodText[i*512*3 + j*3 + 0] <= which + 4 && wolfbloodText[i*512*3 + j*3 + 0] >= which - 4) {
525 if (i < startx) startx = i;
526 if (j < starty) starty = j;
527 if (i > endx) endx = i;
528 if (j > endy) endy = j;
538 if (startx < 0) startx = 0;
539 if (starty < 0) starty = 0;
540 if (endx > 512 - 1) endx = 512 - 1;
541 if (endy > 512 - 1) endy = 512 - 1;
542 if (endx < startx) endx = startx;
543 if (endy < starty) endy = starty;
545 startx /= realtexdetail;
546 starty /= realtexdetail;
547 endx /= realtexdetail;
548 endy /= realtexdetail;
550 int texdetailint = realtexdetail;
552 if (creature == rabbittype)
553 for (i = startx; i < endx; i++) {
554 for (j = starty; j < endy; j++) {
555 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) {
556 color = Random() % 85 + 170;
557 where = i * skeleton.skinsize * 3 + j * 3;
558 if (skeleton.skinText[where + 0] > color / 2)
559 skeleton.skinText[where + 0] = color / 2;
560 skeleton.skinText[where + 1] = 0;
561 skeleton.skinText[where + 2] = 0;
565 if (creature == wolftype)
566 for (i = startx; i < endx; i++) {
567 for (j = starty; j < endy; j++) {
568 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) {
569 color = Random() % 85 + 170;
570 where = i * skeleton.skinsize * 3 + j * 3;
571 if (skeleton.skinText[where + 0] > color / 2)
572 skeleton.skinText[where + 0] = color / 2;
573 skeleton.skinText[where + 1] = 0;
574 skeleton.skinText[where + 2] = 0;
578 skeleton.drawmodel.textureptr.bind();
583 if (creature == rabbittype)
584 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) {
585 bleedxint = abs(Random() % 512);
586 bleedyint = abs(Random() % 512);
588 if (creature == wolftype)
589 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) {
590 bleedxint = abs(Random() % 512);
591 bleedyint = abs(Random() % 512);
593 bleedy = bleedxint + offsetx;
594 bleedx = bleedyint + offsety;
595 bleedy /= realtexdetail;
596 bleedx /= realtexdetail;
601 if (bleedx > skeleton.skinsize - 1)
602 bleedx = skeleton.skinsize - 1;
603 if (bleedy > skeleton.skinsize - 1)
604 bleedy = skeleton.skinsize - 1;
605 direction = abs(Random() % 2) * 2 - 1;
608 bleeding = howmuch + (float)abs(Random() % 100) / 200 - .25;
609 deathbleeding += bleeding;
610 bloodloss += bleeding * 3;
612 if (tutoriallevel != 1 && aitype != playercontrolled && bloodloss > damagetolerance * 2 / 3 && bloodloss < damagetolerance && creature == rabbittype) {
613 if (abs(Random() % 2) == 0) {
614 aitype = gethelptype;
617 aitype = attacktypecutoff;
625 * similar to DoBloodBig
627 bool Person::DoBloodBigWhere(float howmuch, int which, XYZ where)
631 static XYZ startpoint, endpoint, colpoint, movepoint;
632 static float rotationpoint;
634 static XYZ p1, p2, p3, p0;
638 float coordsx, coordsy;
641 if (bloodtoggle && decals && tutoriallevel != 1) {
644 where = DoRotation(where, 0, -yaw, 0);
652 // ray testing for a tri in the character model
653 whichtri = skeleton.drawmodel.LineCheck(&startpoint, &endpoint, &colpoint, &movepoint, &rotationpoint);
654 if (whichtri != -1) {
655 // low level geometry math
657 p1 = skeleton.drawmodel.vertex[skeleton.drawmodel.Triangles[whichtri].vertex[0]];
658 p2 = skeleton.drawmodel.vertex[skeleton.drawmodel.Triangles[whichtri].vertex[1]];
659 p3 = skeleton.drawmodel.vertex[skeleton.drawmodel.Triangles[whichtri].vertex[2]];
661 CrossProduct(p2-p1,p3-p1,&N);
662 CrossProduct(p0-p1,p3-p1,&temp);
663 s = dotproduct(&temp,&N)/findLength(&N);
664 CrossProduct(p2-p1,p1-p0,&temp);
665 t = dotproduct(&temp,&N)/findLength(&N);
668 bary.x = distsq(&p0, &p1);
669 bary.y = distsq(&p0, &p2);
670 bary.z = distsq(&p0, &p3);
672 total = bary.x + bary.y + bary.z;
681 total = bary.x + bary.y + bary.z;
687 gxx.x = skeleton.drawmodel.Triangles[whichtri].gx[0];
688 gxx.y = skeleton.drawmodel.Triangles[whichtri].gx[1];
689 gxx.z = skeleton.drawmodel.Triangles[whichtri].gx[2];
690 gyy.x = skeleton.drawmodel.Triangles[whichtri].gy[0];
691 gyy.y = skeleton.drawmodel.Triangles[whichtri].gy[1];
692 gyy.z = skeleton.drawmodel.Triangles[whichtri].gy[2];
693 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;
694 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;
696 //coordsx=skeleton.drawmodel.Triangles[whichtri].gx[1];
697 //coordsy=skeleton.drawmodel.Triangles[whichtri].gy[1];
699 if (bleeding <= 0 && spurt) {
701 for (int i = 0; i < 3; i++) {
702 // emit blood particles
703 // FIXME: more copypaste code
705 if (!skeleton.free) {
707 bloodvel = DoRotation(bloodvel, ((float)(Random() % 100)) / 4, yaw + ((float)(Random() % 100)) / 4, 0) * scale;
710 bloodvel -= DoRotation(skeleton.forward * 10 * scale, ((float)(Random() % 100)) / 4, ((float)(Random() % 100)) / 4, 0);
713 bloodvel += DoRotation(jointVel(head), ((float)(Random() % 100)) / 4, yaw + ((float)(Random() % 100)) / 4, 0) * scale;
715 bloodvel += DoRotation(velocity, ((float)(Random() % 100)) / 4, ((float)(Random() % 100)) / 4, 0) * scale;
717 Sprite::MakeSprite(bloodsprite, jointPos(head) * scale + coords, bloodvel, 1, 1, 1, .05, 1);
718 Sprite::MakeSprite(bloodflamesprite, jointPos(head) * scale + coords, bloodvel, 1, 1, 1, .3, 1);
720 if (!skeleton.free) {
721 Sprite::MakeSprite(bloodsprite, DoRotation((jointPos(head) + jointPos(neck)) / 2, 0, yaw, 0)*scale + coords, bloodvel, 1, 1, 1, .05, 1);
722 Sprite::MakeSprite(bloodflamesprite, DoRotation((jointPos(head) + jointPos(neck)) / 2, 0, yaw, 0)*scale + coords, bloodvel, 1, 1, 1, .3, 1);
727 // texture manipulation follows
729 int offsetx = 0, offsety = 0;
732 offsetx=abs(Random()%120);
734 if(which==220||which==215){
736 offsetx=abs(Random()%80);
739 offsetx = (1 + coordsy) * 512 - 291;
740 offsety = coordsx * 512 - 437;
747 if (creature == rabbittype)
748 for (i = 0; i < 512; i++) {
749 for (j = 0; j < 512; j++) {
750 if (bloodText[i * 512 * 3 + j * 3 + 0] <= which + 4 && bloodText[i * 512 * 3 + j * 3 + 0] >= which - 4) {
751 if (i < startx) startx = i;
752 if (j < starty) starty = j;
753 if (i > endx) endx = i;
754 if (j > endy) endy = j;
758 if (creature == wolftype)
759 for (i = 0; i < 512; i++) {
760 for (j = 0; j < 512; j++) {
761 if (wolfbloodText[i * 512 * 3 + j * 3 + 0] <= which + 4 && wolfbloodText[i * 512 * 3 + j * 3 + 0] >= which - 4) {
762 if (i < startx) startx = i;
763 if (j < starty) starty = j;
764 if (i > endx) endx = i;
765 if (j > endy) endy = j;
774 if (startx < 0) startx = 0;
775 if (starty < 0) starty = 0;
776 if (endx > 512 - 1) endx = 512 - 1;
777 if (endy > 512 - 1) endy = 512 - 1;
778 if (endx < startx) endx = startx;
779 if (endy < starty) endy = starty;
781 startx /= realtexdetail;
782 starty /= realtexdetail;
783 endx /= realtexdetail;
784 endy /= realtexdetail;
786 int texdetailint = realtexdetail;
788 if (creature == rabbittype)
789 for (i = startx; i < endx; i++) {
790 for (j = starty; j < endy; j++) {
791 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) {
792 color = Random() % 85 + 170;
793 where = i * skeleton.skinsize * 3 + j * 3;
794 if (skeleton.skinText[where + 0] > color / 2)
795 skeleton.skinText[where + 0] = color / 2;
796 skeleton.skinText[where + 1] = 0;
797 skeleton.skinText[where + 2] = 0;
798 } 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) {
799 color = Random() % 85 + 170;
800 where = i * skeleton.skinsize * 3 + j * 3;
801 if (skeleton.skinText[where + 0] > color / 2)
802 skeleton.skinText[where + 0] = color / 2;
803 skeleton.skinText[where + 1] = 0;
804 skeleton.skinText[where + 2] = 0;
808 if (creature == wolftype)
809 for (i = startx; i < endx; i++) {
810 for (j = starty; j < endy; j++) {
811 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) {
812 color = Random() % 85 + 170;
813 where = i * skeleton.skinsize * 3 + j * 3;
814 if (skeleton.skinText[where + 0] > color / 2)
815 skeleton.skinText[where + 0] = color / 2;
816 skeleton.skinText[where + 1] = 0;
817 skeleton.skinText[where + 2] = 0;
818 } 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) {
819 color = Random() % 85 + 170;
820 where = i * skeleton.skinsize * 3 + j * 3;
821 if (skeleton.skinText[where + 0] > color / 2)
822 skeleton.skinText[where + 0] = color / 2;
823 skeleton.skinText[where + 1] = 0;
824 skeleton.skinText[where + 2] = 0;
828 skeleton.drawmodel.textureptr.bind();
831 bleedy = (1 + coordsy) * 512;
832 bleedx = coordsx * 512;
833 bleedy /= realtexdetail;
834 bleedx /= realtexdetail;
839 if (bleedx > skeleton.skinsize - 1)
840 bleedx = skeleton.skinsize - 1;
841 if (bleedy > skeleton.skinsize - 1)
842 bleedy = skeleton.skinsize - 1;
843 direction = abs(Random() % 2) * 2 - 1;
848 bleeding = howmuch + (float)abs(Random() % 100) / 200 - .25;
849 deathbleeding += bleeding;
850 bloodloss += bleeding * 3;
852 if (tutoriallevel != 1 && aitype != playercontrolled && bloodloss > damagetolerance * 2 / 3 && bloodloss < damagetolerance && creature == rabbittype) {
853 if (abs(Random() % 2) == 0) {
854 aitype = gethelptype;
857 aitype = attacktypecutoff;
868 * guessing this performs a reversal
870 void Person::Reverse()
872 if (!((victim->aitype == playercontrolled
874 || staggerdelay <= 0)
875 && victim->animTarget != jumpupanim
876 && victim->animTarget != jumpdownanim
877 && (tutoriallevel != 1 || cananger)
881 if (normaldotproduct (victim->facing, victim->coords - coords) > 0
882 && (victim->id != 0 || difficulty >= 2)
883 && (creature != wolftype || victim->creature == wolftype))
886 if (animTarget == sweepanim) {
887 animTarget = sweepreversedanim;
888 animCurrent = sweepreversedanim;
889 victim->animCurrent = sweepreversalanim;
890 victim->animTarget = sweepreversalanim;
892 if (animTarget == spinkickanim) {
893 animTarget = spinkickreversedanim;
894 animCurrent = spinkickreversedanim;
895 victim->animCurrent = spinkickreversalanim;
896 victim->animTarget = spinkickreversalanim;
898 if (animTarget == upunchanim || animTarget == rabbittacklinganim) {
899 if (animTarget == rabbittacklinganim) {
902 victim->frameCurrent = 6;
903 victim->frameTarget = 7;
905 animTarget = upunchreversedanim;
906 animCurrent = upunchreversedanim;
907 victim->animCurrent = upunchreversalanim;
908 victim->animTarget = upunchreversalanim;
910 if (animTarget == staffhitanim && distsq(&victim->coords, &coords) < 2 && ((victim->id == 0 && victim->crouchkeydown) || Random() % 4 == 0)) {
911 if (victim->weaponactive != -1) {
912 victim->throwtogglekeydown = 1;
913 weapons[victim->weaponids[0]].owner = -1;
914 weapons[victim->weaponids[0]].velocity = victim->velocity * .2;
915 if (weapons[victim->weaponids[0]].velocity.x == 0)
916 weapons[victim->weaponids[0]].velocity.x = .1;
917 weapons[victim->weaponids[0]].tipvelocity = weapons[victim->weaponids[0]].velocity;
918 weapons[victim->weaponids[0]].missed = 1;
919 weapons[victim->weaponids[0]].freetime = 0;
920 weapons[victim->weaponids[0]].firstfree = 1;
921 weapons[victim->weaponids[0]].physics = 1;
922 victim->num_weapons--;
923 if (victim->num_weapons) {
924 victim->weaponids[0] = victim->weaponids[victim->num_weapons];
925 if (victim->weaponstuck == victim->num_weapons)
926 victim->weaponstuck = 0;
929 victim->weaponactive = -1;
930 for (int j = 0; j < numplayers; j++) {
931 player[j].wentforweapon = 0;
935 animTarget = staffhitreversedanim;
936 animCurrent = staffhitreversedanim;
937 victim->animCurrent = staffhitreversalanim;
938 victim->animTarget = staffhitreversalanim;
940 if (animTarget == staffspinhitanim && distsq(&victim->coords, &coords) < 2 && ((victim->id == 0 && victim->crouchkeydown) || Random() % 2 == 0)) {
941 if (victim->weaponactive != -1) {
942 victim->throwtogglekeydown = 1;
943 weapons[victim->weaponids[0]].owner = -1;
944 weapons[victim->weaponids[0]].velocity = victim->velocity * .2;
945 if (weapons[victim->weaponids[0]].velocity.x == 0)
946 weapons[victim->weaponids[0]].velocity.x = .1;
947 weapons[victim->weaponids[0]].tipvelocity = weapons[victim->weaponids[0]].velocity;
948 weapons[victim->weaponids[0]].missed = 1;
949 weapons[victim->weaponids[0]].freetime = 0;
950 weapons[victim->weaponids[0]].firstfree = 1;
951 weapons[victim->weaponids[0]].physics = 1;
952 victim->num_weapons--;
953 if (victim->num_weapons) {
954 victim->weaponids[0] = victim->weaponids[victim->num_weapons];
955 if (victim->weaponstuck == victim->num_weapons)
956 victim->weaponstuck = 0;
959 victim->weaponactive = -1;
960 for (int j = 0; j < numplayers; j++) {
961 player[j].wentforweapon = 0;
964 animTarget = staffspinhitreversedanim;
965 animCurrent = staffspinhitreversedanim;
966 victim->animCurrent = staffspinhitreversalanim;
967 victim->animTarget = staffspinhitreversalanim;
969 if (animTarget == swordslashanim && distsq(&victim->coords, &coords) < 2 && ((victim->id == 0 && victim->crouchkeydown) || Random() % 4 == 0)) {
970 if (victim->weaponactive != -1) {
971 victim->throwtogglekeydown = 1;
972 weapons[victim->weaponids[0]].owner = -1;
973 weapons[victim->weaponids[0]].velocity = victim->velocity * .2;
974 if (weapons[victim->weaponids[0]].velocity.x == 0)
975 weapons[victim->weaponids[0]].velocity.x = .1;
976 weapons[victim->weaponids[0]].tipvelocity = weapons[victim->weaponids[0]].velocity;
977 weapons[victim->weaponids[0]].missed = 1;
978 weapons[victim->weaponids[0]].freetime = 0;
979 weapons[victim->weaponids[0]].firstfree = 1;
980 weapons[victim->weaponids[0]].physics = 1;
981 victim->num_weapons--;
982 if (victim->num_weapons) {
983 victim->weaponids[0] = victim->weaponids[victim->num_weapons];
984 if (victim->weaponstuck == victim->num_weapons)
985 victim->weaponstuck = 0;
988 victim->weaponactive = -1;
989 for (int j = 0; j < numplayers; j++) {
990 player[j].wentforweapon = 0;
993 animTarget = swordslashreversedanim;
994 animCurrent = swordslashreversedanim;
995 victim->animCurrent = swordslashreversalanim;
996 victim->animTarget = swordslashreversalanim;
998 if (animTarget == knifeslashstartanim && distsq(&victim->coords, &coords) < 2 && (victim->id == 0 || Random() % 4 == 0)) {
999 if (victim->weaponactive != -1) {
1000 victim->throwtogglekeydown = 1;
1001 weapons[victim->weaponids[0]].owner = -1;
1002 weapons[victim->weaponids[0]].velocity = victim->velocity * .2;
1003 if (weapons[victim->weaponids[0]].velocity.x == 0)
1004 weapons[victim->weaponids[0]].velocity.x = .1;
1005 weapons[victim->weaponids[0]].tipvelocity = weapons[victim->weaponids[0]].velocity;
1006 weapons[victim->weaponids[0]].missed = 1;
1007 weapons[victim->weaponids[0]].freetime = 0;
1008 weapons[victim->weaponids[0]].firstfree = 1;
1009 weapons[victim->weaponids[0]].physics = 1;
1010 victim->num_weapons--;
1011 if (victim->num_weapons) {
1012 victim->weaponids[0] = victim->weaponids[victim->num_weapons];
1013 if (victim->weaponstuck == victim->num_weapons)
1014 victim->weaponstuck = 0;
1017 victim->weaponactive = -1;
1018 for (int j = 0; j < numplayers; j++) {
1019 player[j].wentforweapon = 0;
1022 animTarget = knifeslashreversedanim;
1023 animCurrent = knifeslashreversedanim;
1024 victim->animCurrent = knifeslashreversalanim;
1025 victim->animTarget = knifeslashreversalanim;
1027 if (animTarget != knifeslashstartanim && animTarget != staffhitanim && animTarget != staffspinhitanim && animTarget != winduppunchanim && animTarget != wolfslapanim && animTarget != swordslashanim && animTarget != swordslashanim) {
1028 victim->targettilt2 = targettilt2;
1029 victim->frameCurrent = frameCurrent;
1030 victim->frameTarget = frameTarget;
1031 victim->target = target;
1032 victim->velocity = 0;
1033 victim->oldcoords = victim->coords;
1034 victim->coords = coords;
1035 victim->targetyaw = targetyaw;
1036 victim->yaw = targetyaw;
1037 victim->victim = this;
1039 if (animTarget == winduppunchanim) {
1040 animTarget = winduppunchblockedanim;
1041 victim->animTarget = blockhighleftanim;
1042 victim->frameTarget = 1;
1043 victim->target = .5;
1044 victim->victim = this;
1045 victim->targetyaw = targetyaw + 180;
1047 if (animTarget == wolfslapanim) {
1048 animTarget = winduppunchblockedanim;
1049 victim->animTarget = blockhighleftanim;
1050 victim->frameTarget = 1;
1051 victim->target = .5;
1052 victim->victim = this;
1053 victim->targetyaw = targetyaw + 180;
1055 if ((animTarget == swordslashanim || animTarget == staffhitanim || animTarget == staffspinhitanim) && victim->weaponactive != -1) {
1056 animTarget = swordslashparriedanim;
1057 parriedrecently = .4;
1058 victim->parriedrecently = 0;
1059 victim->animTarget = swordslashparryanim;
1060 victim->frameTarget = 1;
1061 victim->target = .5;
1062 victim->victim = this;
1063 victim->targetyaw = targetyaw + 180;
1065 if (abs(Random() % 20) == 0 || weapons[victim->weaponids[victim->weaponactive]].getType() == knife) {
1066 if (victim->weaponactive != -1) {
1067 if (weapons[victim->weaponids[0]].getType() == staff || weapons[weaponids[0]].getType() == staff) {
1068 if (weapons[victim->weaponids[0]].getType() == staff)
1069 weapons[victim->weaponids[0]].damage += .2 + float(abs(Random() % 100) - 50) / 250;
1070 if (weapons[weaponids[0]].getType() == staff)
1071 weapons[weaponids[0]].damage += .2 + float(abs(Random() % 100) - 50) / 250;
1072 emit_sound_at(swordstaffsound, victim->coords);
1074 emit_sound_at(metalhitsound, victim->coords);
1078 victim->Puff(righthand);
1080 victim->frameTarget = 0;
1081 victim->animTarget = staggerbackhighanim;
1082 victim->targetyaw = targetyaw + 180;
1084 weapons[victim->weaponids[0]].owner = -1;
1085 aim = DoRotation(facing, 0, 90, 0) * 21;
1087 weapons[victim->weaponids[0]].velocity = aim * -.2;
1088 weapons[victim->weaponids[0]].tipvelocity = aim;
1089 weapons[victim->weaponids[0]].missed = 1;
1090 weapons[victim->weaponids[0]].hitsomething = 0;
1091 weapons[victim->weaponids[0]].freetime = 0;
1092 weapons[victim->weaponids[0]].firstfree = 1;
1093 weapons[victim->weaponids[0]].physics = 1;
1094 victim->num_weapons--;
1095 if (victim->num_weapons) {
1096 victim->weaponids[0] = victim->weaponids[num_weapons];
1097 if (victim->weaponstuck == victim->num_weapons)
1098 victim->weaponstuck = 0;
1100 victim->weaponactive = -1;
1101 for (int i = 0; i < numplayers; i++) {
1102 player[i].wentforweapon = 0;
1106 if (abs(Random() % 20) == 0) {
1107 if (weaponactive != -1) {
1108 if (weapons[victim->weaponids[0]].getType() == staff || weapons[weaponids[0]].getType() == staff) {
1109 if (weapons[victim->weaponids[0]].getType() == staff)
1110 weapons[victim->weaponids[0]].damage += .2 + float(abs(Random() % 100) - 50) / 250;
1111 if (weapons[weaponids[0]].getType() == staff)
1112 weapons[weaponids[0]].damage += .2 + float(abs(Random() % 100) - 50) / 250;
1114 emit_sound_at(swordstaffsound, coords);
1116 emit_sound_at(metalhitsound, coords);
1124 animTarget = staggerbackhighanim;
1125 targetyaw = targetyaw + 180;
1127 weapons[weaponids[0]].owner = -1;
1128 aim = DoRotation(facing, 0, 90, 0) * 21;
1130 weapons[weaponids[0]].velocity = aim * -.2;
1131 weapons[weaponids[0]].tipvelocity = aim;
1132 weapons[weaponids[0]].hitsomething = 0;
1133 weapons[weaponids[0]].missed = 1;
1134 weapons[weaponids[0]].freetime = 0;
1135 weapons[weaponids[0]].firstfree = 1;
1136 weapons[weaponids[0]].physics = 1;
1139 weaponids[0] = weaponids[num_weapons];
1140 if (weaponstuck == num_weapons)
1144 for (int i = 0; i < numplayers; i++) {
1145 player[i].wentforweapon = 0;
1152 if (animTarget == knifeslashstartanim || animTarget == swordslashanim || animTarget == staffhitanim || animTarget == staffspinhitanim) {
1153 if ((animTarget != staffhitanim && animTarget != staffspinhitanim) || distsq(&coords, &victim->coords) > .2) {
1154 victim->animTarget = dodgebackanim;
1155 victim->frameTarget = 0;
1159 rotatetarget = coords - victim->coords;
1160 Normalise(&rotatetarget);
1161 victim->targetyaw = -asin(0 - rotatetarget.x);
1162 victim->targetyaw *= 360 / 6.28;
1163 if (rotatetarget.z < 0)
1164 victim->targetyaw = 180 - victim->targetyaw;
1166 victim->targettilt2 = -asin(rotatetarget.y) * 360 / 6.28; //*-70;
1168 victim->lastattack3 = victim->lastattack2;
1169 victim->lastattack2 = victim->lastattack;
1170 victim->lastattack = victim->animTarget;
1172 victim->animTarget = sweepanim;
1173 victim->frameTarget = 0;
1177 rotatetarget = coords - victim->coords;
1178 Normalise(&rotatetarget);
1179 victim->targetyaw = -asin(0 - rotatetarget.x);
1180 victim->targetyaw *= 360 / 6.28;
1181 if (rotatetarget.z < 0)
1182 victim->targetyaw = 180 - victim->targetyaw;
1184 victim->targettilt2 = -asin(rotatetarget.y) * 360 / 6.28; //*-70;
1186 victim->lastattack3 = victim->lastattack2;
1187 victim->lastattack2 = victim->lastattack;
1188 victim->lastattack = victim->animTarget;
1193 victim->velocity = 0;
1195 if (aitype != playercontrolled)
1197 if (aitype != playercontrolled && Random() % 3 == 0 && escapednum < 2 && difficulty == 2)
1199 if (aitype != playercontrolled && Random() % 5 == 0 && escapednum < 2 && difficulty == 1)
1201 if (aitype != playercontrolled && Random() % 10 == 0 && escapednum < 2 && difficulty == 0)
1204 if (victim->id == 0 && animation[victim->animTarget].attack == reversal)
1211 void Person::DoDamage(float howmuch)
1213 // subtract health (temporary?)
1214 if (tutoriallevel != 1)
1215 damage += howmuch / power;
1218 damagedealt += howmuch / power;
1220 damagetaken += howmuch / power;
1223 if (id == 0 && (bonus == solidhit || bonus == twoxcombo || bonus == threexcombo || bonus == fourxcombo || bonus == megacombo))
1226 if (tutoriallevel != 1)
1227 permanentdamage += howmuch / 2 / power;
1228 if (tutoriallevel != 1)
1229 superpermanentdamage += howmuch / 4 / power;
1231 if (permanentdamage > damagetolerance / 2 && permanentdamage - howmuch < damagetolerance / 2 && Random() % 2)
1233 if ((permanentdamage > damagetolerance * .8 && Random() % 2 && !deathbleeding) || spurt)
1237 camerashake += howmuch / 100;
1238 if (id == 0 && ((howmuch > 50 && damage > damagetolerance / 2)))
1239 blackout = damage / damagetolerance;
1244 if (aitype == passivetype && damage < damagetolerance && ((tutoriallevel != 1 || cananger) && hostile))
1245 aitype = attacktypecutoff;
1246 if (tutoriallevel != 1 && aitype != playercontrolled && damage < damagetolerance && damage > damagetolerance * 2 / 3 && creature == rabbittype) {
1247 if (abs(Random() % 2) == 0) {
1248 aitype = gethelptype;
1251 aitype = attacktypecutoff;
1255 if (howmuch > damagetolerance * 50 && skeleton.free != 2) {
1258 for (int i = 0; i < skeleton.num_joints; i++) {
1260 flatvelocity2 = velocity;
1262 flatvelocity2 = skeleton.joints[i].velocity;
1264 flatfacing2 = DoRotation(DoRotation(DoRotation(skeleton.joints[i].position, 0, 0, tilt), tilt2, 0, 0), 0, yaw, 0) * scale + coords;
1266 flatfacing2 = skeleton.joints[i].position * scale + coords;
1267 flatvelocity2.x += (float)(abs(Random() % 100) - 50) / 10;
1268 flatvelocity2.y += (float)(abs(Random() % 100) - 50) / 10;
1269 flatvelocity2.z += (float)(abs(Random() % 100) - 50) / 10;
1270 Sprite::MakeSprite(bloodflamesprite, flatfacing2, flatvelocity2, 1, 1, 1, 3, 1);
1271 Sprite::MakeSprite(bloodsprite, flatfacing2, flatvelocity2, 1, 1, 1, .4, 1);
1272 Sprite::MakeSprite(cloudsprite, flatfacing2, flatvelocity2 * 0, .6, 0, 0, 1, .5);
1275 emit_sound_at(splattersound, coords);
1284 if (!dead && creature == wolftype) {
1285 award_bonus(0, Wolfbonus);
1292 if (tutoriallevel != 1 || id == 0)
1293 if (speechdelay <= 0 && !dead && aitype != playercontrolled) {
1294 int whichsound = -1;
1296 if (creature == wolftype) {
1297 int i = abs(Random() % 2);
1299 whichsound = snarlsound;
1301 whichsound = snarl2sound;
1302 envsound[numenvsounds] = coords;
1303 envsoundvol[numenvsounds] = 16;
1304 envsoundlife[numenvsounds] = .4;
1307 if (creature == rabbittype) {
1308 int i = abs(Random() % 2);
1310 whichsound = rabbitpainsound;
1311 if (i == 1 && damage > damagetolerance)
1312 whichsound = rabbitpain1sound;
1313 envsound[numenvsounds] = coords;
1314 envsoundvol[numenvsounds] = 16;
1315 envsoundlife[numenvsounds] = .4;
1317 //if(i==2)whichsound=rabbitpain2sound;
1320 if (whichsound != -1) {
1321 emit_sound_at(whichsound, coords);
1326 //if(permanentdamage>=damagetolerance&&howmuch<50)permanentdamage=damagetolerance-1;
1327 //if(damage>=damagetolerance&&howmuch<30&&!dead)damage=damagetolerance-1;
1331 * calculate/animate head facing direction?
1333 void Person::DoHead()
1335 static XYZ rotatearound;
1337 static float lookspeed = 500;
1339 if (!freeze && !winfreeze) {
1342 targetheadyaw = (float)((int)((0 - yaw - targetheadyaw + 180) * 100) % 36000) / 100;
1343 targetheadpitch = (float)((int)(targetheadpitch * 100) % 36000) / 100;
1345 while (targetheadyaw > 180)targetheadyaw -= 360;
1346 while (targetheadyaw < -180)targetheadyaw += 360;
1348 if (targetheadyaw > 160)
1349 targetheadpitch = targetheadpitch * -1;
1350 if (targetheadyaw < -160)
1351 targetheadpitch = targetheadpitch * -1;
1352 if (targetheadyaw > 160)
1353 targetheadyaw = targetheadyaw - 180;
1354 if (targetheadyaw < -160)
1355 targetheadyaw = targetheadyaw + 180;
1357 if (targetheadpitch > 120)
1358 targetheadpitch = 120;
1359 if (targetheadpitch < -120)
1360 targetheadpitch = -120;
1361 if (targetheadyaw > 120)
1362 targetheadyaw = 120;
1363 if (targetheadyaw < -120)
1364 targetheadyaw = -120;
1367 targetheadpitch = 0;
1369 if (targetheadyaw > 80)
1371 if (targetheadyaw < -80)
1372 targetheadyaw = -80;
1373 if (targetheadpitch > 50)
1374 targetheadpitch = 50;
1375 if (targetheadpitch < -50)
1376 targetheadpitch = -50;
1379 if (abs(headyaw - targetheadyaw) < multiplier * lookspeed)
1380 headyaw = targetheadyaw;
1381 else if (headyaw > targetheadyaw) {
1382 headyaw -= multiplier * lookspeed;
1383 } else if (headyaw < targetheadyaw) {
1384 headyaw += multiplier * lookspeed;
1387 if (abs(headpitch - targetheadpitch) < multiplier * lookspeed / 2)
1388 headpitch = targetheadpitch;
1389 else if (headpitch > targetheadpitch) {
1390 headpitch -= multiplier * lookspeed / 2;
1391 } else if (headpitch < targetheadpitch) {
1392 headpitch += multiplier * lookspeed / 2;
1395 rotatearound = jointPos(neck);
1396 jointPos(head) = rotatearound + DoRotation(jointPos(head) - rotatearound, headpitch, 0, 0);
1400 if (animTarget != bounceidleanim && animTarget != fightidleanim && animTarget != wolfidle && animTarget != knifefightidleanim && animTarget != drawrightanim && animTarget != drawleftanim && animTarget != walkanim) {
1401 facing = DoRotation(facing, headpitch * .4, 0, 0);
1402 facing = DoRotation(facing, 0, headyaw * .4, 0);
1405 if (animTarget == bounceidleanim || animTarget == fightidleanim || animTarget == wolfidle || animTarget == knifefightidleanim || animTarget == drawrightanim || animTarget == drawleftanim) {
1406 facing = DoRotation(facing, headpitch * .8, 0, 0);
1407 facing = DoRotation(facing, 0, headyaw * .8, 0);
1410 if (animTarget == walkanim) {
1411 facing = DoRotation(facing, headpitch * .6, 0, 0);
1412 facing = DoRotation(facing, 0, headyaw * .6, 0);
1415 skeleton.specialforward[0] = facing;
1416 //skeleton.specialforward[0]=DoRotation(facing,0,yaw,0);
1418 for (i = 0; i < skeleton.num_muscles; i++) {
1419 if (skeleton.muscles[i].visible && (skeleton.muscles[i].parent1->label == head || skeleton.muscles[i].parent2->label == head)) {
1420 skeleton.FindRotationMuscle(i, animTarget);
1427 * ragdolls character?
1429 void Person::RagDoll(bool checkcollision)
1434 if (!skeleton.free) {
1437 if (id == 0 && isFlip())
1444 facing = DoRotation(facing, 0, yaw, 0);
1446 skeleton.freetime = 0;
1448 skeleton.longdead = 0;
1451 skeleton.broken = 0;
1452 skeleton.spinny = 1;
1454 skeleton.freefall = 1;
1456 if (!isnormal(velocity.x)) velocity.x = 0;
1457 if (!isnormal(velocity.y)) velocity.y = 0;
1458 if (!isnormal(velocity.z)) velocity.z = 0;
1459 if (!isnormal(yaw)) yaw = 0;
1460 if (!isnormal(coords.x)) coords = 0;
1461 if (!isnormal(tilt)) tilt = 0;
1462 if (!isnormal(tilt2)) tilt2 = 0;
1464 for (i = 0; i < skeleton.num_joints; i++) {
1465 skeleton.joints[i].delay = 0;
1466 skeleton.joints[i].locked = 0;
1467 skeleton.joints[i].position = DoRotation(DoRotation(DoRotation(skeleton.joints[i].position, 0, 0, tilt), tilt2, 0, 0), 0, yaw, 0);
1468 if (!isnormal(skeleton.joints[i].position.x)) skeleton.joints[i].position = DoRotation(skeleton.joints[i].position, 0, yaw, 0);
1469 if (!isnormal(skeleton.joints[i].position.x)) skeleton.joints[i].position = skeleton.joints[i].position;
1470 if (!isnormal(skeleton.joints[i].position.x)) skeleton.joints[i].position = coords;
1471 skeleton.joints[i].position.y += .1;
1472 skeleton.joints[i].oldposition = skeleton.joints[i].position;
1473 skeleton.joints[i].realoldposition = skeleton.joints[i].position * scale + coords;
1476 for (i = 0; i < skeleton.num_joints; i++) {
1477 skeleton.joints[i].velocity = 0;
1478 skeleton.joints[i].velchange = 0;
1480 skeleton.DoConstraints(&coords, &scale);
1481 if (animation[animCurrent].height == lowheight || animation[animTarget].height == lowheight) {
1482 skeleton.DoConstraints(&coords, &scale);
1483 skeleton.DoConstraints(&coords, &scale);
1484 skeleton.DoConstraints(&coords, &scale);
1485 skeleton.DoConstraints(&coords, &scale);
1488 speed = animation[animTarget].speed[frameTarget] * 2;
1489 if (animation[animCurrent].speed[frameCurrent] > animation[animTarget].speed[frameTarget]) {
1490 speed = animation[animCurrent].speed[frameCurrent] * 2;
1493 speed = transspeed * 2;
1497 for (i = 0; i < skeleton.num_joints; i++) {
1498 if ((animation[animCurrent].attack != reversed || animCurrent == swordslashreversedanim) && animCurrent != rabbitkickanim && !isLanding() && !wasLanding() && animation[animCurrent].height == animation[animTarget].height)
1499 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);
1501 skeleton.joints[i].velocity = velocity / scale + facing * 5;
1502 change.x = (float)(Random() % 100) / 100;
1503 change.y = (float)(Random() % 100) / 100;
1504 change.z = (float)(Random() % 100) / 100;
1505 skeleton.joints[i].velocity += change;
1506 skeleton.joints[abs(Random() % skeleton.num_joints)].velocity -= change;
1508 change.x = (float)(Random() % 100) / 100;
1509 change.y = (float)(Random() % 100) / 100;
1510 change.z = (float)(Random() % 100) / 100;
1511 skeleton.joints[i].velchange += change;
1512 skeleton.joints[abs(Random() % skeleton.num_joints)].velchange -= change;
1515 if (checkcollision) {
1522 for (j = 0; j < skeleton.num_joints; j++) {
1523 average += skeleton.joints[j].position;
1527 coords += average * scale;
1528 for (j = 0; j < skeleton.num_joints; j++) {
1529 skeleton.joints[j].position -= average;
1532 whichpatchx = coords.x / (terrain.size / subdivision * terrain.scale);
1533 whichpatchz = coords.z / (terrain.size / subdivision * terrain.scale);
1534 if (terrain.patchobjectnum[whichpatchx][whichpatchz])
1535 for (l = 0; l < terrain.patchobjectnum[whichpatchx][whichpatchz]; l++) {
1536 i = terrain.patchobjects[whichpatchx][whichpatchz][l];
1539 if (SphereCheck(&lowpoint, 3, &colpoint, &objects.position[i], &objects.yaw[i], &objects.model[i]) != -1) {
1540 coords.x = lowpoint.x;
1541 coords.z = lowpoint.z;
1550 for (i = 0; i < skeleton.num_joints; i++) {
1551 velocity += skeleton.joints[i].velocity * scale;
1553 velocity /= skeleton.num_joints;
1556 if (Random() % 2 == 0) {
1557 if (weaponactive != -1 && animTarget != rabbitkickanim && num_weapons > 0) {
1558 weapons[weaponids[0]].owner = -1;
1559 weapons[weaponids[0]].hitsomething = 0;
1560 weapons[weaponids[0]].velocity = jointVel(righthand) * scale * -.3;
1561 weapons[weaponids[0]].velocity.x += .01;
1562 weapons[weaponids[0]].tipvelocity = jointVel(righthand) * scale;
1563 weapons[weaponids[0]].missed = 1;
1564 weapons[weaponids[0]].freetime = 0;
1565 weapons[weaponids[0]].firstfree = 1;
1566 weapons[weaponids[0]].physics = 1;
1569 weaponids[0] = weaponids[num_weapons];
1570 if (weaponstuck == num_weapons)
1574 for (i = 0; i < numplayers; i++) {
1575 player[i].wentforweapon = 0;
1580 animTarget = bounceidleanim;
1581 animCurrent = bounceidleanim;
1591 void Person::FootLand(int which, float opacity)
1593 static XYZ terrainlight;
1594 static XYZ footvel, footpoint;
1595 if (opacity >= 1 || skiddelay <= 0)
1599 footpoint = DoRotation(jointPos(leftfoot), 0, yaw, 0) * scale + coords;
1601 footpoint = DoRotation(jointPos(rightfoot), 0, yaw, 0) * scale + coords;
1602 //footpoint.y=coords.y;
1603 if (distsq(&footpoint, &viewer))
1604 Sprite::MakeSprite(cloudsprite, footpoint, footvel, 1, 1, 1, .5, .2 * opacity);
1605 } else if (environment == snowyenvironment && onterrain && terrain.getOpacity(coords.x, coords.z) < .2) {
1606 footvel = velocity / 5;
1610 footpoint = DoRotation(jointPos(leftfoot), 0, yaw, 0) * scale + coords;
1612 footpoint = DoRotation(jointPos(rightfoot), 0, yaw, 0) * scale + coords;
1613 footpoint.y = terrain.getHeight(footpoint.x, footpoint.z);
1614 terrainlight = terrain.getLighting(footpoint.x, footpoint.z);
1615 if (distsq(&footpoint, &viewer) < viewdistance * viewdistance / 4)
1616 Sprite::MakeSprite(cloudsprite, footpoint, footvel * .6, terrainlight.x, terrainlight.y, terrainlight.z, .5, .7 * opacity);
1617 if (opacity >= 1 || detail == 2)
1619 if (distsq(&footpoint, &viewer) < viewdistance * viewdistance / 4)
1620 terrain.MakeDecal(footprintdecal, footpoint, .2, 1 * opacity, yaw);
1621 } else if (environment == grassyenvironment && onterrain && terrain.getOpacity(coords.x, coords.z) < .2) {
1622 footvel = velocity / 5;
1626 footpoint = DoRotation(jointPos(leftfoot), 0, yaw, 0) * scale + coords;
1628 footpoint = DoRotation(jointPos(rightfoot), 0, yaw, 0) * scale + coords;
1629 footpoint.y = terrain.getHeight(footpoint.x, footpoint.z);
1630 terrainlight = terrain.getLighting(footpoint.x, footpoint.z);
1631 if (distsq(&footpoint, &viewer) < viewdistance * viewdistance / 4)
1632 Sprite::MakeSprite(cloudsprite, footpoint, footvel * .6, terrainlight.x * 90 / 255, terrainlight.y * 70 / 255, terrainlight.z * 8 / 255, .5, .5 * opacity);
1633 } else if (environment == desertenvironment && onterrain && terrain.getOpacity(coords.x, coords.z) < .2) {
1634 footvel = velocity / 5;
1638 footpoint = DoRotation(jointPos(leftfoot), 0, yaw, 0) * scale + coords;
1640 footpoint = DoRotation(jointPos(rightfoot), 0, yaw, 0) * scale + coords;
1641 footpoint.y = terrain.getHeight(footpoint.x, footpoint.z);
1642 terrainlight = terrain.getLighting(footpoint.x, footpoint.z);
1643 if (distsq(&footpoint, &viewer) < viewdistance * viewdistance / 4)
1644 Sprite::MakeSprite(cloudsprite, footpoint, footvel * .6, terrainlight.x * 190 / 255, terrainlight.y * 170 / 255, terrainlight.z * 108 / 255, .5, .7 * opacity);
1645 if (opacity >= 1 || detail == 2)
1647 if (distsq(&footpoint, &viewer) < viewdistance * viewdistance / 4)
1648 terrain.MakeDecal(footprintdecal, footpoint, .2, .25 * opacity, yaw);
1649 } else if (isLanding() || animTarget == jumpupanim || isLandhard()) {
1650 footvel = velocity / 5;
1654 footpoint = DoRotation(jointPos(leftfoot), 0, yaw, 0) * scale + coords;
1656 footpoint = DoRotation(jointPos(rightfoot), 0, yaw, 0) * scale + coords;
1657 //footpoint.y=coords.y;
1658 if (distsq(&footpoint, &viewer) < viewdistance * viewdistance / 4)
1659 Sprite::MakeSprite(cloudsprite, footpoint, footvel * .6, 1, 1, 1, .5, .2 * opacity);
1664 * make a puff effect at a body part (dust effect?)
1666 void Person::Puff(int whichlabel)
1668 static XYZ footvel, footpoint;
1671 footpoint = DoRotation(jointPos(whichlabel), 0, yaw, 0) * scale + coords;
1672 Sprite::MakeSprite(cloudimpactsprite, footpoint, footvel, 1, 1, 1, .9, .3);
1676 * I think I added this in an attempt to clean up code
1678 void Person::setAnimation(int animation)
1680 animTarget = animation;
1689 void Person::DoAnimations()
1691 if (!skeleton.free) {
1693 static float oldtarget;
1695 if (isIdle() && animCurrent != getIdle())
1696 normalsupdatedelay = 0;
1698 if (animTarget == tempanim || animCurrent == tempanim) {
1699 animation[tempanim] = tempanimation;
1701 if (animTarget == jumpupanim || animTarget == jumpdownanim || isFlip()) {
1707 vel[0] = velocity.x;
1708 vel[1] = velocity.y;
1709 vel[2] = velocity.z;
1712 OPENAL_3D_SetAttributes(channels[whooshsound], gLoc, vel);
1713 OPENAL_SetVolume(channels[whooshsound], 64 * findLength(&velocity) / 5);
1715 if (((velocity.y < -15) || (crouchkeydown && velocity.y < -8)) && abs(velocity.y) * 4 > fast_sqrt(velocity.x * velocity.x * velocity.z * velocity.z))
1717 if (!crouchkeydown && velocity.y >= -15)
1720 if ((animCurrent == jumpupanim || animTarget == jumpdownanim)/*&&velocity.y<40*/ && !isFlip() && (!isLanding() && !isLandhard()) && ((crouchkeydown && !crouchtogglekeydown))) {
1725 targfacing = DoRotation(targfacing, 0, targetyaw, 0);
1727 if (normaldotproduct(targfacing, velocity) >= -.3)
1728 animTarget = flipanim;
1730 animTarget = backflipanim;
1731 crouchtogglekeydown = 1;
1739 if (animation[animTarget].attack != reversed)
1741 if (!crouchkeydown || (isLanding() || isLandhard()) || (wasLanding() || wasLandhard())) {
1742 crouchtogglekeydown = 0;
1743 if (aitype == playercontrolled)
1746 if (!crouchtogglekeydown && animation[animTarget].attack == reversed && aitype == playercontrolled && (escapednum < 2 || reversaltrain))
1749 crouchtogglekeydown = 1;
1753 if (animation[animTarget].attack || animCurrent == getupfrombackanim || animCurrent == getupfromfrontanim) {
1755 normalsupdatedelay = 0;
1759 if (animTarget == rollanim && frameTarget == 3 && onfire) {
1761 emit_sound_at(fireendsound, coords);
1762 pause_sound(stream_firesound);
1766 if (animTarget == rabbittacklinganim && frameTarget == 1) {
1767 //if(victim->aitype==attacktypecutoff&&Random()%2==0&&victim->stunned<=0&&animation[victim->animTarget].attack==neutral&&victim->id!=0)Reverse();
1768 if (victim->aitype == attacktypecutoff && victim->stunned <= 0 && victim->surprised <= 0 && victim->id != 0)
1770 if (animTarget == rabbittacklinganim && frameTarget == 1 && !victim->isCrouch() && victim->animTarget != backhandspringanim) {
1771 if (normaldotproduct(victim->facing, facing) > 0)
1772 victim->animTarget = rabbittackledbackanim;
1774 victim->animTarget = rabbittackledfrontanim;
1775 victim->frameTarget = 2;
1778 victim->targetyaw = yaw;
1779 if (victim->aitype == gethelptype)
1780 victim->DoDamage(victim->damagetolerance - victim->damage);
1781 //victim->DoDamage(30);
1782 if (creature == wolftype) {
1784 emit_sound_at(clawslicesound, victim->coords);
1786 victim->DoBloodBig(1 / victim->armorhead, 210);
1788 award_bonus(id, TackleBonus,
1789 victim->aitype == gethelptype ? 50 : 0);
1793 if (!drawtogglekeydown && drawkeydown && (weaponactive == -1 || num_weapons == 1) && (animation[animTarget].label[frameTarget] || (animTarget != animCurrent && animCurrent == rollanim)) && num_weapons > 0 && creature != wolftype) {
1794 if (weapons[weaponids[0]].getType() == knife) {
1795 if (weaponactive == -1)
1797 else if (weaponactive == 0)
1800 if (weaponactive == -1) {
1801 emit_sound_at(knifesheathesound, coords);
1803 if (weaponactive != -1) {
1804 emit_sound_at(knifedrawsound, coords, 128);
1807 drawtogglekeydown = 1;
1810 if (tutoriallevel != 1 || id == 0)
1811 if ((animation[animTarget].label[frameTarget] && (animation[animTarget].label[frameTarget] < 5 || animation[animTarget].label[frameTarget] == 8))/*||(animTarget==rollanim&&frameTarget==animation[rollanim].numframes-1)*/) {
1814 if (terrain.getOpacity(coords.x, coords.z) < .2) {
1815 if (animation[animTarget].label[frameTarget] == 1)
1816 whichsound = footstepsound;
1818 whichsound = footstepsound2;
1819 if (animation[animTarget].label[frameTarget] == 1)
1821 if (animation[animTarget].label[frameTarget] == 2)
1823 if (animation[animTarget].label[frameTarget] == 3 && isRun()) {
1829 if (terrain.getOpacity(coords.x, coords.z) >= .2) {
1830 if (animation[animTarget].label[frameTarget] == 1)
1831 whichsound = footstepsound3;
1833 whichsound = footstepsound4;
1837 if (animation[animTarget].label[frameTarget] == 1)
1838 whichsound = footstepsound3;
1840 whichsound = footstepsound4;
1842 if (animation[animTarget].label[frameTarget] == 4 && (weaponactive == -1 || (animTarget != knifeslashstartanim && animTarget != knifethrowanim && animTarget != crouchstabanim && animTarget != swordgroundstabanim && animTarget != knifefollowanim))) {
1843 if (animation[animTarget].attack != neutral) {
1844 i = abs(Random() % 3);
1846 whichsound = lowwhooshsound;
1848 whichsound = midwhooshsound;
1850 whichsound = highwhooshsound;
1852 if (animation[animTarget].attack == neutral)
1853 whichsound = movewhooshsound;
1854 } else if (animation[animTarget].label[frameTarget] == 4)
1855 whichsound = knifeswishsound;
1856 if (animation[animTarget].label[frameTarget] == 8 && tutoriallevel != 1)
1857 whichsound = landsound2;
1859 emit_sound_at(whichsound, coords, 256.);
1862 if (whichsound == footstepsound || whichsound == footstepsound2 || whichsound == footstepsound3 || whichsound == footstepsound4) {
1863 envsound[numenvsounds] = coords;
1864 if (animTarget == wolfrunninganim || animTarget == rabbitrunninganim)
1865 envsoundvol[numenvsounds] = 15;
1867 envsoundvol[numenvsounds] = 6;
1868 envsoundlife[numenvsounds] = .4;
1872 if (animation[animTarget].label[frameTarget] == 3) {
1874 emit_sound_at(whichsound, coords, 128.);
1879 if (tutoriallevel != 1 || id == 0)
1880 if (speechdelay <= 0)
1881 if (animTarget != crouchstabanim && animTarget != swordgroundstabanim && animTarget != staffgroundsmashanim)
1882 if ((animation[animTarget].label[frameTarget] && (animation[animTarget].label[frameTarget] < 5 || animation[animTarget].label[frameTarget] == 8))/*||(animTarget==rollanim&&frameTarget==animation[rollanim].numframes-1)*/) {
1883 int whichsound = -1;
1884 if (animation[animTarget].label[frameTarget] == 4 && aitype != playercontrolled) {
1885 if (animation[animTarget].attack != neutral) {
1886 i = abs(Random() % 4);
1887 if (creature == rabbittype) {
1888 if (i == 0) whichsound = rabbitattacksound;
1889 if (i == 1) whichsound = rabbitattack2sound;
1890 if (i == 2) whichsound = rabbitattack3sound;
1891 if (i == 3) whichsound = rabbitattack4sound;
1893 if (creature == wolftype) {
1894 if (i == 0) whichsound = barksound;
1895 if (i == 1) whichsound = bark2sound;
1896 if (i == 2) whichsound = bark3sound;
1897 if (i == 3) whichsound = barkgrowlsound;
1901 //if(animation[animTarget].attack==neutral)whichsound=movewhooshsound;
1903 //else if(animation[animTarget].label[frameTarget]==4)whichsound=knifeswishsound;
1904 //if(animation[animTarget].label[frameTarget]==8)whichsound=landsound2;
1906 if (whichsound != -1) {
1907 emit_sound_at(whichsound, coords);
1913 if ((!wasLanding() && !wasLandhard()) && animCurrent != getIdle() && (isLanding() || isLandhard())) {
1919 currentoffset = targetoffset;
1920 frameTarget = frameCurrent;
1921 animCurrent = animTarget;
1924 if (animTarget == removeknifeanim && animation[animTarget].label[frameCurrent] == 5) {
1925 for (i = 0; i < weapons.size(); i++) {
1926 if (weapons[i].owner == -1)
1927 if (distsqflat(&coords, &weapons[i].position) < 4 && weaponactive == -1) {
1928 if (distsq(&coords, &weapons[i].position) >= 1) {
1929 if (weapons[i].getType() != staff) {
1930 emit_sound_at(knifedrawsound, coords, 128.);
1934 weapons[i].owner = id;
1935 if (num_weapons > 0) {
1936 weaponids[num_weapons] = weaponids[0];
1945 if (animTarget == crouchremoveknifeanim && animation[animTarget].label[frameCurrent] == 5) {
1946 for (i = 0; i < weapons.size(); i++) {
1947 bool willwork = true;
1948 if (weapons[i].owner != -1)
1949 if (player[weapons[i].owner].weaponstuck != -1)
1950 if (player[weapons[i].owner].weaponids[player[weapons[i].owner].weaponstuck] == i)
1951 if (player[weapons[i].owner].num_weapons > 1)
1953 if ((weapons[i].owner == -1) || (hasvictim && weapons[i].owner == victim->id && victim->skeleton.free))
1954 if (willwork && distsqflat(&coords, &weapons[i].position) < 3 && weaponactive == -1) {
1955 if (distsq(&coords, &weapons[i].position) < 1 || hasvictim) {
1956 bool fleshstuck = false;
1957 if (weapons[i].owner != -1)
1958 if (victim->weaponstuck != -1) {
1959 if (victim->weaponids[victim->weaponstuck] == i) {
1964 emit_sound_at(fleshstabremovesound, coords, 128.);
1966 if (weapons[i].getType() != staff) {
1967 emit_sound_at(knifedrawsound, coords, 128.);
1971 if (weapons[i].owner != -1) {
1973 victim = &player[weapons[i].owner];
1974 if (victim->num_weapons == 1)
1975 victim->num_weapons = 0;
1977 victim->num_weapons = 1;
1979 //victim->weaponactive=-1;
1980 victim->skeleton.longdead = 0;
1981 victim->skeleton.free = 1;
1982 victim->skeleton.broken = 0;
1984 for (int j = 0; j < victim->skeleton.num_joints; j++) {
1985 victim->skeleton.joints[j].velchange = 0;
1986 victim->skeleton.joints[j].locked = 0;
1992 Normalise(&relative);
1993 XYZ footvel, footpoint;
1995 footpoint = weapons[i].position;
1996 if (victim->weaponstuck != -1) {
1997 if (victim->weaponids[victim->weaponstuck] == i) {
1999 Sprite::MakeSprite(cloudimpactsprite, footpoint, footvel, 1, 0, 0, .8, .3);
2000 weapons[i].bloody = 2;
2001 weapons[i].blooddrip = 5;
2002 victim->weaponstuck = -1;
2005 if (victim->num_weapons > 0) {
2006 if (victim->weaponstuck != 0 && victim->weaponstuck != -1)
2007 victim->weaponstuck = 0;
2008 if (victim->weaponids[0] == i)
2009 victim->weaponids[0] = victim->weaponids[victim->num_weapons];
2012 victim->skeleton.joints[victim->skeleton.jointlabels[abdomen]].velocity += relative * 6;
2013 victim->skeleton.joints[victim->skeleton.jointlabels[neck]].velocity += relative * 6;
2014 victim->skeleton.joints[victim->skeleton.jointlabels[rightshoulder]].velocity += relative * 6;
2015 victim->skeleton.joints[victim->skeleton.jointlabels[leftshoulder]].velocity += relative * 6;
2017 weapons[i].owner = id;
2018 if (num_weapons > 0) {
2019 weaponids[num_weapons] = weaponids[0];
2028 if (animCurrent == drawleftanim && animation[animTarget].label[frameCurrent] == 5) {
2029 if (weaponactive == -1)
2031 else if (weaponactive == 0) {
2033 if (num_weapons == 2) {
2035 buffer = weaponids[0];
2036 weaponids[0] = weaponids[1];
2037 weaponids[1] = buffer;
2040 if (weaponactive == -1) {
2041 emit_sound_at(knifesheathesound, coords, 128.);
2043 if (weaponactive != -1) {
2044 emit_sound_at(knifedrawsound, coords, 128.);
2049 if ((animCurrent == walljumprightkickanim && animTarget == walljumprightkickanim) || (animCurrent == walljumpleftkickanim && animTarget == walljumpleftkickanim)) {
2050 XYZ rotatetarget = DoRotation(skeleton.forward, 0, yaw, 0);
2051 Normalise(&rotatetarget);
2052 targetyaw = -asin(0 - rotatetarget.x);
2053 targetyaw *= 360 / 6.28;
2054 if (rotatetarget.z < 0)
2055 targetyaw = 180 - targetyaw;
2057 if (animTarget == walljumprightkickanim)
2059 if (animTarget == walljumpleftkickanim)
2065 if ((animTarget == rabbitrunninganim || animTarget == wolfrunninganim) && frameTarget == 3 && (jumpkeydown || attackkeydown || id != 0))
2068 if (distsq(&victim->coords, &/*player[i].*/coords) < 5 && victim->aitype == gethelptype && (attackkeydown) && !victim->skeleton.free && victim->isRun() && victim->runninghowlong >= 1)
2073 if ((animTarget == rabbitrunninganim || animTarget == wolfrunninganim) && id == 0) {
2074 animTarget = rabbittackleanim;
2076 emit_sound_at(jumpsound, coords);
2084 targetloc = velocity;
2085 Normalise(&targetloc);
2086 targetloc += coords;
2087 for (i = 0; i < numplayers; i++) {
2089 if (distsq(&targetloc, &player[i].coords) < closestdist || closestdist == 0) {
2090 closestdist = distsq(&targetloc, &player[i].coords);
2094 if (closestid != -1)
2095 if (closestdist < 5 && !player[closestid].dead && animation[player[closestid].animTarget].height != lowheight && player[closestid].animTarget != backhandspringanim) {
2097 victim = &player[closestid];
2098 coords = victim->coords;
2099 animCurrent = rabbittacklinganim;
2100 animTarget = rabbittacklinganim;
2104 if (coords.z != victim->coords.z || coords.x != victim->coords.x) {
2105 rotatetarget = coords - victim->coords;
2106 Normalise(&rotatetarget);
2107 targetyaw = -asin(0 - rotatetarget.x);
2108 targetyaw *= 360 / 6.28;
2109 if (rotatetarget.z < 0)
2110 targetyaw = 180 - targetyaw;
2112 if (animTarget != rabbitrunninganim) {
2113 emit_sound_at(jumpsound, coords, 128.);
2119 float damagemult = 1 * power;
2120 if (creature == wolftype)
2121 damagemult = 2.5 * power;
2123 damagemult /= victim->damagetolerance / 200;
2125 //if(onfire)damagemult=3;
2126 if ((animation[animTarget].attack == normalattack || animTarget == walljumprightkickanim || animTarget == walljumpleftkickanim) && (!feint) && (victim->skeleton.free != 2 || animTarget == killanim || animTarget == dropkickanim || animTarget == crouchstabanim || animTarget == swordgroundstabanim || animTarget == staffgroundsmashanim)) {
2127 if (animTarget == spinkickanim && animation[animTarget].label[frameCurrent] == 5) {
2128 if (distsq(&coords, &victim->coords) < (scale * 5) * (scale * 5) * 3 && 3 && animation[victim->animTarget].height != lowheight) {
2132 if (Random() % 2 || creature == wolftype) {
2135 if (creature == wolftype)
2138 if (tutoriallevel != 1) {
2139 emit_sound_at(heavyimpactsound, victim->coords, 128.);
2141 if (creature == wolftype) {
2142 emit_sound_at(clawslicesound, victim->coords, 128.);
2144 victim->DoBloodBig(2 / victim->armorhead, 175);
2148 relative = victim->coords - coords;
2150 Normalise(&relative);
2151 relative = DoRotation(relative, 0, -90, 0);
2152 for (i = 0; i < victim->skeleton.num_joints; i++) {
2153 victim->skeleton.joints[i].velocity += relative * damagemult * 40;
2155 victim->skeleton.joints[victim->skeleton.jointlabels[head]].velocity += relative * damagemult * 200;
2158 victim->DoDamage(damagemult * 100 / victim->protectionhead);
2164 if (animTarget == wolfslapanim && animation[animTarget].label[frameCurrent] == 5) {
2165 if (distsq(&coords, &victim->coords) < (scale * 5) * (scale * 5) * 3 && 3 && animation[victim->animTarget].height != lowheight) {
2169 if (Random() % 2 || creature == wolftype) {
2171 if (creature == wolftype)
2174 emit_sound_at(whooshhitsound, victim->coords);
2175 if (creature == wolftype) {
2176 emit_sound_at(clawslicesound, victim->coords, 128.);
2178 victim->DoBloodBig(2, 175);
2182 relative = victim->coords - coords;
2184 Normalise(&relative);
2186 Normalise(&relative);
2187 relative = DoRotation(relative, 0, 90, 0);
2188 for (i = 0; i < victim->skeleton.num_joints; i++) {
2189 victim->skeleton.joints[i].velocity += relative * damagemult * 20;
2191 victim->skeleton.joints[victim->skeleton.jointlabels[head]].velocity += relative * damagemult * 100;
2194 victim->DoDamage(damagemult * 50 / victim->protectionhead);
2198 if (animTarget == walljumprightkickanim && animation[animTarget].label[frameCurrent] == 5) {
2199 if (distsq(&coords, &victim->coords) < (scale * 5) * (scale * 5) * 3 && animation[victim->animTarget].height != lowheight) {
2205 if (tutoriallevel != 1) {
2206 emit_sound_at(heavyimpactsound, victim->coords, 160.);
2208 if (creature == wolftype) {
2209 emit_sound_at(clawslicesound, victim->coords, 128.);
2211 victim->DoBloodBig(2 / victim->armorhead, 175);
2217 Normalise(&relative);
2218 relative = DoRotation(relative, 0, -90, 0);
2219 for (i = 0; i < victim->skeleton.num_joints; i++) {
2220 victim->skeleton.joints[i].velocity += relative * damagemult * 40;
2222 victim->skeleton.joints[victim->skeleton.jointlabels[head]].velocity += relative * damagemult * 200;
2225 victim->DoDamage(damagemult * 150 / victim->protectionhead);
2227 if (victim->damage > victim->damagetolerance)
2228 award_bonus(id, style);
2234 if (animTarget == walljumpleftkickanim && animation[animTarget].label[frameCurrent] == 5) {
2235 if (distsq(&coords, &victim->coords) < (scale * 5) * (scale * 5) * 3 && animation[victim->animTarget].height != lowheight) {
2241 if (tutoriallevel != 1) {
2242 emit_sound_at(heavyimpactsound, victim->coords, 160.);
2244 if (creature == wolftype) {
2245 emit_sound_at(clawslicesound, victim->coords, 128.);
2247 victim->DoBloodBig(2 / victim->armorhead, 175);
2253 Normalise(&relative);
2254 relative = DoRotation(relative, 0, 90, 0);
2255 for (i = 0; i < victim->skeleton.num_joints; i++) {
2256 victim->skeleton.joints[i].velocity += relative * damagemult * 40;
2258 victim->skeleton.joints[victim->skeleton.jointlabels[head]].velocity += relative * damagemult * 200;
2261 victim->DoDamage(damagemult * 150 / victim->protectionhead);
2263 if (victim->damage > victim->damagetolerance)
2264 award_bonus(id, style);
2270 if (animTarget == blockhighleftstrikeanim && animation[animTarget].label[frameCurrent] == 5) {
2271 if (distsq(&coords, &victim->coords) < (scale * 5) * (scale * 5) * 3 && animation[victim->animTarget].height != lowheight) {
2279 emit_sound_at(whooshhitsound, victim->coords);
2282 relative = victim->coords - coords;
2284 Normalise(&relative);
2285 for (i = 0; i < victim->skeleton.num_joints; i++) {
2286 victim->skeleton.joints[i].velocity += relative * damagemult * 30;
2288 victim->skeleton.joints[victim->skeleton.jointlabels[head]].velocity += relative * damagemult * 100;
2291 victim->DoDamage(damagemult * 50 / victim->protectionhead);
2295 if (animTarget == killanim && animation[animTarget].label[frameCurrent] == 8) {
2296 if (distsq(&coords, &victim->coords) < (scale * 5) * (scale * 5) * 3 && victim->dead) {
2300 emit_sound_at(whooshhitsound, victim->coords, 128.);
2302 victim->skeleton.longdead = 0;
2303 victim->skeleton.free = 1;
2304 victim->skeleton.broken = 0;
2305 victim->skeleton.spinny = 1;
2307 for (i = 0; i < victim->skeleton.num_joints; i++) {
2308 victim->skeleton.joints[i].velchange = 0;
2309 victim->skeleton.joints[i].delay = 0;
2310 victim->skeleton.joints[i].locked = 0;
2311 //victim->skeleton.joints[i].velocity=0;
2317 Normalise(&relative);
2318 for (i = 0; i < victim->skeleton.num_joints; i++) {
2319 victim->skeleton.joints[i].velocity.y = relative.y * 10;
2320 victim->skeleton.joints[i].position.y += relative.y * .3;
2321 victim->skeleton.joints[i].oldposition.y += relative.y * .3;
2322 victim->skeleton.joints[i].realoldposition.y += relative.y * .3;
2324 victim->Puff(abdomen);
2325 victim->skeleton.joints[victim->skeleton.jointlabels[abdomen]].velocity.y = relative.y * 400;
2329 if (animTarget == killanim && animation[animTarget].label[frameCurrent] == 5) {
2330 if (distsq(&coords, &victim->coords) < (scale * 5) * (scale * 5) * 9 && victim->dead) {
2334 if (tutoriallevel != 1) {
2335 emit_sound_at(heavyimpactsound, coords, 128.);
2338 relative = victim->coords - coords;
2340 Normalise(&relative);
2341 for (i = 0; i < victim->skeleton.num_joints; i++) {
2342 victim->skeleton.joints[i].velocity += relative * damagemult * 90;
2344 victim->Puff(abdomen);
2345 if (victim->dead != 2 && victim->permanentdamage > victim->damagetolerance - 250 && autoslomo) {
2349 victim->DoDamage(damagemult * 500 / victim->protectionhigh);
2350 victim->skeleton.joints[victim->skeleton.jointlabels[abdomen]].velocity += relative * damagemult * 300;
2354 if (animTarget == dropkickanim && animation[animTarget].label[frameCurrent] == 7) {
2355 if (distsq(&coords, &victim->coords) < (scale * 5) * (scale * 5) * 9 && victim->skeleton.free) {
2359 if (tutoriallevel != 1) {
2360 emit_sound_at(thudsound, coords);
2363 victim->skeleton.longdead = 0;
2364 victim->skeleton.free = 1;
2365 victim->skeleton.broken = 0;
2366 victim->skeleton.spinny = 1;
2368 for (i = 0; i < victim->skeleton.num_joints; i++) {
2369 victim->skeleton.joints[i].velchange = 0;
2370 //victim->skeleton.joints[i].delay=0;
2371 victim->skeleton.joints[i].locked = 0;
2374 relative = victim->coords - coords;
2375 Normalise(&relative);
2377 Normalise(&relative);
2378 for (i = 0; i < victim->skeleton.num_joints; i++) {
2379 victim->skeleton.joints[i].velocity += relative * damagemult * 20;
2384 victim->Puff(abdomen);
2385 victim->DoDamage(damagemult * 20 / victim->protectionhigh);
2386 victim->skeleton.joints[victim->skeleton.jointlabels[abdomen]].velocity += relative * damagemult * 200;
2395 if ((animTarget == crouchstabanim || animTarget == swordgroundstabanim) && animation[animTarget].label[frameCurrent] == 5) {
2396 //if(id==0)camerashake+=.4;
2399 if (!victim->skeleton.free)
2403 terrain.MakeDecal(blooddecalfast, (weapons[weaponids[weaponactive]].tippoint * .8 + weapons[weaponids[weaponactive]].position * .2), .08, .6, Random() % 360);
2404 emit_sound_at(knifesheathesound, coords, 128.);
2407 if (victim && hasvictim) {
2408 if (distsq(&coords, &victim->coords) < (scale * 5) * (scale * 5) * 3) {
2410 XYZ where, startpoint, endpoint, movepoint, colpoint;
2411 float rotationpoint;
2413 if (weapons[weaponids[weaponactive]].getType() == knife) {
2414 where = (weapons[weaponids[weaponactive]].tippoint * .6 + weapons[weaponids[weaponactive]].position * .4);
2415 where -= victim->coords;
2416 if (!victim->skeleton.free)
2417 where = DoRotation(where, 0, -victim->yaw, 0);
2420 startpoint.y += 100;
2424 if (weapons[weaponids[weaponactive]].getType() == sword) {
2425 where = weapons[weaponids[weaponactive]].position;
2426 where -= victim->coords;
2427 if (!victim->skeleton.free)
2428 where = DoRotation(where, 0, -victim->yaw, 0);
2430 where = weapons[weaponids[weaponactive]].tippoint;
2431 where -= victim->coords;
2432 if (!victim->skeleton.free)
2433 where = DoRotation(where, 0, -victim->yaw, 0);
2436 if (weapons[weaponids[weaponactive]].getType() == staff) {
2437 where = weapons[weaponids[weaponactive]].position;
2438 where -= victim->coords;
2439 if (!victim->skeleton.free)
2440 where = DoRotation(where, 0, -victim->yaw, 0);
2442 where = weapons[weaponids[weaponactive]].tippoint;
2443 where -= victim->coords;
2444 if (!victim->skeleton.free)
2445 where = DoRotation(where, 0, -victim->yaw, 0);
2450 whichtri = victim->skeleton.drawmodel.LineCheck(&startpoint, &endpoint, &colpoint, &movepoint, &rotationpoint);
2452 if (whichtri != -1) {
2453 if (victim->dead != 2) {
2454 victim->DoDamage(abs((victim->damagetolerance - victim->permanentdamage) * 2));
2456 award_bonus(id, FinishedBonus);
2459 weapons[weaponids[weaponactive]].bloody = 2;
2461 victim->skeleton.longdead = 0;
2462 victim->skeleton.free = 1;
2463 victim->skeleton.broken = 0;
2465 for (i = 0; i < victim->skeleton.num_joints; i++) {
2466 victim->skeleton.joints[i].velchange = 0;
2467 victim->skeleton.joints[i].locked = 0;
2468 //victim->skeleton.joints[i].velocity=0;
2470 emit_sound_at(fleshstabsound, coords, 128);
2473 if (whichtri != -1 || weapons[weaponids[weaponactive]].bloody) {
2474 weapons[weaponids[weaponactive]].blooddrip += 5;
2475 weapons[weaponids[weaponactive]].blooddripdelay = 0;
2477 if (whichtri == -1) {
2479 emit_sound_at(knifesheathesound, coords, 128.);
2485 if ((animTarget == crouchstabanim || animTarget == swordgroundstabanim) && animation[animTarget].label[frameCurrent] == 6) {
2487 emit_sound_at(knifedrawsound, coords, 128);
2490 if (victim && hasvictim) {
2491 XYZ footvel, footpoint;
2493 emit_sound_at(fleshstabremovesound, coords, 128.);
2496 footpoint = (weapons[weaponids[weaponactive]].tippoint * .8 + weapons[weaponids[weaponactive]].position * .2);
2498 if (weapons[weaponids[weaponactive]].getType() == sword) {
2499 XYZ where, startpoint, endpoint, movepoint;
2500 float rotationpoint;
2503 where = weapons[weaponids[weaponactive]].position;
2504 where -= victim->coords;
2505 if (!victim->skeleton.free)
2506 where = DoRotation(where, 0, -victim->yaw, 0);
2508 where = weapons[weaponids[weaponactive]].tippoint;
2509 where -= victim->coords;
2510 if (!victim->skeleton.free)
2511 where = DoRotation(where, 0, -victim->yaw, 0);
2516 whichtri = victim->skeleton.drawmodel.LineCheck(&startpoint, &endpoint, &footpoint, &movepoint, &rotationpoint);
2517 footpoint += victim->coords;
2519 if (whichtri == -1) {
2520 footpoint = (weapons[weaponids[weaponactive]].tippoint * .8 + weapons[weaponids[weaponactive]].position * .2);
2523 if (weapons[weaponids[weaponactive]].getType() == staff) {
2524 XYZ where, startpoint, endpoint, movepoint;
2525 float rotationpoint;
2528 where = weapons[weaponids[weaponactive]].position;
2529 where -= victim->coords;
2530 if (!victim->skeleton.free)
2531 where = DoRotation(where, 0, -victim->yaw, 0);
2533 where = weapons[weaponids[weaponactive]].tippoint;
2534 where -= victim->coords;
2535 if (!victim->skeleton.free)
2536 where = DoRotation(where, 0, -victim->yaw, 0);
2541 whichtri = victim->skeleton.drawmodel.LineCheck(&startpoint, &endpoint, &footpoint, &movepoint, &rotationpoint);
2542 footpoint += victim->coords;
2544 if (whichtri == -1) {
2545 footpoint = (weapons[weaponids[weaponactive]].tippoint * .8 + weapons[weaponids[weaponactive]].position * .2);
2548 hasvictim = victim->DoBloodBigWhere(2, 220, footpoint);
2550 if (distsq(&coords, &victim->coords) < (scale * 5) * (scale * 5) * 3) {
2551 victim->skeleton.longdead = 0;
2552 victim->skeleton.free = 1;
2553 victim->skeleton.broken = 0;
2555 for (i = 0; i < victim->skeleton.num_joints; i++) {
2556 victim->skeleton.joints[i].velchange = 0;
2557 victim->skeleton.joints[i].locked = 0;
2558 //victim->skeleton.joints[i].velocity=0;
2564 Normalise(&relative);
2565 //victim->Puff(abdomen);
2567 Sprite::MakeSprite(cloudimpactsprite, footpoint, footvel, 1, 0, 0, .8, .3);
2569 if (victim->bloodloss < victim->damagetolerance) {
2570 victim->bloodloss += 1000;
2574 victim->skeleton.joints[victim->skeleton.jointlabels[abdomen]].velocity += relative * damagemult * 20;
2578 if (!hasvictim && onterrain) {
2579 weapons[weaponids[weaponactive]].bloody = 0;
2580 weapons[weaponids[weaponactive]].blooddrip = 0;
2584 if (animTarget == upunchanim && animation[animTarget].label[frameCurrent] == 5) {
2585 if (distsq(&coords, &victim->coords) < (scale * 5) * (scale * 5) * 3) {
2593 if (tutoriallevel != 1) {
2594 emit_sound_at(heavyimpactsound, victim->coords, 128);
2599 relative = victim->coords - coords;
2601 Normalise(&relative);
2602 for (i = 0; i < victim->skeleton.num_joints; i++) {
2603 victim->skeleton.joints[i].velocity = relative * 30;
2605 victim->skeleton.joints[victim->skeleton.jointlabels[head]].velocity += relative * damagemult * 150;
2607 victim->frameTarget = 0;
2608 victim->animTarget = staggerbackhardanim;
2609 victim->targetyaw = targetyaw + 180;
2611 victim->stunned = 1;
2614 victim->Puff(abdomen);
2615 victim->DoDamage(damagemult * 60 / victim->protectionhigh);
2622 if (animTarget == winduppunchanim && animation[animTarget].label[frameCurrent] == 5) {
2623 if (distsq(&coords, &victim->coords) < (scale * 5) * (scale * 5) * 2) {
2627 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(thudsound, victim->coords);
2631 } else if (victim->damage <= victim->damagetolerance - 60 && normaldotproduct(victim->facing, victim->coords - coords) < (scale * 5) * (scale * 5) * 0 && animation[victim->animTarget].height == lowheight) {
2632 if (tutoriallevel != 1) {
2633 emit_sound_at(whooshhitsound, victim->coords);
2636 if (tutoriallevel != 1) {
2637 emit_sound_at(heavyimpactsound, victim->coords);
2641 if (victim->damage > victim->damagetolerance - 60 || normaldotproduct(victim->facing, victim->coords - coords) > 0 || animation[victim->animTarget].height == lowheight)
2644 relative = victim->coords - coords;
2646 Normalise(&relative);
2648 Normalise(&relative);
2649 for (i = 0; i < victim->skeleton.num_joints; i++) {
2650 victim->skeleton.joints[i].velocity = relative * 5;
2652 victim->skeleton.joints[victim->skeleton.jointlabels[abdomen]].velocity += relative * damagemult * 400;
2654 victim->frameTarget = 0;
2655 victim->animTarget = staggerbackhardanim;
2656 victim->targetyaw = targetyaw + 180;
2658 victim->stunned = 1;
2660 victim->Puff(abdomen);
2661 victim->DoDamage(damagemult * 60 / victim->protectionhigh);
2667 if (animTarget == blockhighleftanim && animation[animTarget].label[frameCurrent] == 5) {
2668 if (distsq(&coords, &victim->coords) < (scale * 5) * (scale * 5) * 4) {
2669 if (victim->id == 0)
2671 emit_sound_at(landsound2, victim->coords);
2677 if (animTarget == swordslashparryanim && animation[animTarget].label[frameCurrent] == 5) {
2678 if (distsq(&coords, &victim->coords) < (scale * 5) * (scale * 5) * 4) {
2679 if (victim->id == 0)
2682 if (weaponactive != -1) {
2683 if (weapons[victim->weaponids[0]].getType() == staff || weapons[weaponids[0]].getType() == staff) {
2684 if (weapons[victim->weaponids[0]].getType() == staff)
2685 weapons[victim->weaponids[0]].damage += .2 + float(abs(Random() % 100) - 50) / 250;
2686 if (weapons[weaponids[0]].getType() == staff)
2687 weapons[weaponids[0]].damage += .2 + float(abs(Random() % 100) - 50) / 250;
2689 emit_sound_at(swordstaffsound, victim->coords);
2691 emit_sound_at(metalhitsound, victim->coords);
2699 if (animTarget == knifethrowanim && animation[animTarget].label[frameCurrent] == 5) {
2700 if (weaponactive != -1) {
2703 weapons[weaponids[0]].owner = -1;
2704 aim = victim->coords + DoRotation(victim->skeleton.joints[victim->skeleton.jointlabels[abdomen]].position, 0, victim->yaw, 0) * victim->scale + victim->velocity * findDistance(&victim->coords, &coords) / 50 - (coords + DoRotation(jointPos(righthand), 0, yaw, 0) * scale);
2706 /*if(victim->animTarget==jumpupanim||victim->animTarget==jumpdownanim){
2707 aim=DoRotation(aim,(float)abs(Random()%15)-7,(float)abs(Random()%15)-7,0);
2709 weapons[weaponids[0]].velocity = aim * 50;
2710 weapons[weaponids[0]].tipvelocity = aim * 50;
2711 weapons[weaponids[0]].missed = 0;
2712 weapons[weaponids[0]].hitsomething = 0;
2713 weapons[weaponids[0]].freetime = 0;
2714 weapons[weaponids[0]].firstfree = 1;
2715 weapons[weaponids[0]].physics = 0;
2718 weaponids[0] = weaponids[num_weapons];
2724 if (animTarget == knifeslashstartanim && animation[animTarget].label[frameCurrent] == 5) {
2726 if (distsq(&coords, &victim->coords) < (scale * 5) * (scale * 5) * 4.5 &&/*animation[victim->animTarget].height!=lowheight&&*/victim->animTarget != dodgebackanim && victim->animTarget != rollanim) {
2728 if (tutoriallevel != 1)
2729 victim->DoBloodBig(1.5 / victim->armorhigh, 225);
2731 award_bonus(id, Slicebonus);
2732 if (tutoriallevel != 1) {
2733 emit_sound_at(knifeslicesound, victim->coords);
2735 //victim->skeleton.joints[victim->skeleton.jointlabels[abdomen]].velocity+=relative*damagemult*200;
2736 if (animation[victim->animTarget].attack && (victim->aitype != playercontrolled || victim->animTarget == knifeslashstartanim) && (victim->creature == rabbittype || victim->deathbleeding <= 0)) {
2737 if (victim->id != 0 || difficulty == 2) {
2738 victim->frameTarget = 0;
2739 victim->animTarget = staggerbackhardanim;
2740 victim->targetyaw = targetyaw + 180;
2744 victim->lowreversaldelay = 0;
2745 victim->highreversaldelay = 0;
2746 if (aitype != playercontrolled)
2747 weaponmissdelay = .6;
2749 if (tutoriallevel != 1)
2750 if (bloodtoggle && !weapons[weaponids[weaponactive]].bloody)
2751 weapons[weaponids[weaponactive]].bloody = 1;
2752 if (tutoriallevel != 1)
2753 weapons[weaponids[weaponactive]].blooddrip += 3;
2755 XYZ footvel, footpoint;
2757 if (skeleton.free) {
2758 footpoint = (victim->skeleton.joints[victim->skeleton.jointlabels[abdomen]].position + victim->skeleton.joints[victim->skeleton.jointlabels[neck]].position) / 2 * victim->scale + victim->coords;
2760 if (!skeleton.free) {
2761 footpoint = DoRotation((victim->skeleton.joints[victim->skeleton.jointlabels[abdomen]].position + victim->skeleton.joints[victim->skeleton.jointlabels[neck]].position) / 2, 0, victim->yaw, 0) * victim->scale + victim->coords;
2763 if (tutoriallevel != 1) {
2765 Sprite::MakeSprite(cloudimpactsprite, footpoint, footvel, 1, 0, 0, .6, .3);
2766 footvel = DoRotation(facing, 0, 90, 0) * .8;
2768 Sprite::MakeSprite(bloodsprite, footpoint, DoRotation(footvel * 7, (float)(Random() % 20), (float)(Random() % 20), 0), 1, 1, 1, .05, .9);
2769 Sprite::MakeSprite(bloodsprite, footpoint, DoRotation(footvel * 3, (float)(Random() % 20), (float)(Random() % 20), 0), 1, 1, 1, .05, .9);
2770 Sprite::MakeSprite(bloodflamesprite, footpoint, footvel * 5, 1, 1, 1, .2, 1);
2771 Sprite::MakeSprite(bloodflamesprite, footpoint, footvel * 2, 1, 1, 1, .2, 1);
2773 if (tutoriallevel == 1) {
2774 Sprite::MakeSprite(cloudimpactsprite, footpoint, footvel, 1, 1, 1, .6, .3);
2776 victim->DoDamage(damagemult * 0);
2779 if (animTarget == swordslashanim && animation[animTarget].label[frameCurrent] == 5 && victim->animTarget != rollanim) {
2780 if (distsq(&coords, &victim->coords) < (scale * 5) * (scale * 5) * 6.5 && victim->animTarget != dodgebackanim) {
2781 if (victim->weaponactive == -1 || normaldotproduct(victim->facing, victim->coords - coords) > 0 || (Random() % 2 == 0)) {
2782 award_bonus(id, Slashbonus);
2784 if (tutoriallevel != 1) {
2785 if (normaldotproduct(victim->facing, victim->coords - coords) < 0)
2786 victim->DoBloodBig(2 / victim->armorhigh, 190);
2788 victim->DoBloodBig(2 / victim->armorhigh, 185);
2789 victim->deathbleeding = 1;
2790 emit_sound_at(swordslicesound, victim->coords);
2792 //victim->skeleton.joints[victim->skeleton.jointlabels[abdomen]].velocity+=relative*damagemult*200;
2793 if (tutoriallevel != 1) {
2794 victim->frameTarget = 0;
2795 victim->animTarget = staggerbackhardanim;
2796 victim->targetyaw = targetyaw + 180;
2800 if (tutoriallevel != 1) {
2801 if (bloodtoggle && !weapons[weaponids[weaponactive]].bloody)
2802 weapons[weaponids[weaponactive]].bloody = 1;
2803 weapons[weaponids[weaponactive]].blooddrip += 3;
2805 float bloodlossamount;
2806 bloodlossamount = 200 + abs((float)(Random() % 40)) - 20;
2807 victim->bloodloss += bloodlossamount / victim->armorhigh;
2808 //victim->bloodloss+=100*(6.5-distsq(&coords,&victim->coords));
2809 victim->DoDamage(damagemult * 0);
2811 XYZ footvel, footpoint;
2813 if (skeleton.free) {
2814 footpoint = (victim->skeleton.joints[victim->skeleton.jointlabels[abdomen]].position + victim->skeleton.joints[victim->skeleton.jointlabels[neck]].position) / 2 * victim->scale + victim->coords;
2816 if (!skeleton.free) {
2817 footpoint = DoRotation((victim->skeleton.joints[victim->skeleton.jointlabels[abdomen]].position + victim->skeleton.joints[victim->skeleton.jointlabels[neck]].position) / 2, 0, victim->yaw, 0) * victim->scale + victim->coords;
2820 Sprite::MakeSprite(cloudimpactsprite, footpoint, footvel, 1, 0, 0, .9, .3);
2821 footvel = DoRotation(facing, 0, 90, 0) * .8;
2823 Sprite::MakeSprite(bloodsprite, footpoint, DoRotation(footvel * 7, (float)(Random() % 20), (float)(Random() % 20), 0), 1, 1, 1, .05, .9);
2824 Sprite::MakeSprite(bloodsprite, footpoint, DoRotation(footvel * 3, (float)(Random() % 20), (float)(Random() % 20), 0), 1, 1, 1, .05, .9);
2825 Sprite::MakeSprite(bloodflamesprite, footpoint, footvel * 5, 1, 1, 1, .3, 1);
2826 Sprite::MakeSprite(bloodflamesprite, footpoint, footvel * 2, 1, 1, 1, .3, 1);
2829 if (victim->weaponactive != -1) {
2830 if (weapons[victim->weaponids[0]].getType() == staff || weapons[weaponids[0]].getType() == staff) {
2831 if (weapons[victim->weaponids[0]].getType() == staff)
2832 weapons[victim->weaponids[0]].damage += .2 + float(abs(Random() % 100) - 50) / 250;
2833 if (weapons[weaponids[0]].getType() == staff)
2834 weapons[weaponids[0]].damage += .2 + float(abs(Random() % 100) - 50) / 250;
2836 emit_sound_at(swordstaffsound, victim->coords);
2838 emit_sound_at(metalhitsound, victim->coords);
2844 victim->Puff(righthand);
2846 victim->frameTarget = 0;
2847 victim->animTarget = staggerbackhighanim;
2848 victim->targetyaw = targetyaw + 180;
2850 weapons[victim->weaponids[0]].owner = -1;
2851 aim = DoRotation(facing, 0, 90, 0) * 21;
2853 weapons[victim->weaponids[0]].velocity = aim * -.2;
2854 weapons[victim->weaponids[0]].tipvelocity = aim;
2855 weapons[victim->weaponids[0]].missed = 1;
2856 weapons[weaponids[0]].hitsomething = 0;
2857 weapons[victim->weaponids[0]].freetime = 0;
2858 weapons[victim->weaponids[0]].firstfree = 1;
2859 weapons[victim->weaponids[0]].physics = 1;
2860 victim->num_weapons--;
2861 if (victim->num_weapons) {
2862 victim->weaponids[0] = victim->weaponids[num_weapons];
2863 if (victim->weaponstuck == victim->num_weapons)
2864 victim->weaponstuck = 0;
2866 victim->weaponactive = -1;
2867 for (i = 0; i < numplayers; i++) {
2868 player[i].wentforweapon = 0;
2875 if (animTarget == staffhitanim && animation[animTarget].label[frameCurrent] == 5 && victim->animTarget != rollanim) {
2876 if (distsq(&coords, &victim->coords) < (scale * 5) * (scale * 5) * 6.5 && victim->animTarget != dodgebackanim && victim->animTarget != sweepanim) {
2877 if (tutoriallevel != 1) {
2878 weapons[weaponids[0]].damage += .4 + float(abs(Random() % 100) - 50) / 250;
2882 if (Random() % 2 || creature == wolftype) {
2885 emit_sound_at(staffheadsound, victim->coords);
2889 relative = victim->coords - coords;
2891 Normalise(&relative);
2892 relative = DoRotation(relative, 0, 90, 0);
2894 Normalise(&relative);
2895 for (i = 0; i < victim->skeleton.num_joints; i++) {
2896 victim->skeleton.joints[i].velocity += relative * damagemult * 60;
2898 victim->skeleton.joints[victim->skeleton.jointlabels[head]].velocity += relative * damagemult * 230;
2899 victim->skeleton.joints[victim->skeleton.jointlabels[neck]].velocity += relative * damagemult * 230;
2902 if (tutoriallevel != 1) {
2903 victim->DoDamage(damagemult * 120 / victim->protectionhigh);
2905 award_bonus(id, solidhit, 30);
2910 if (animTarget == staffspinhitanim && animation[animTarget].label[frameCurrent] == 5 && victim->animTarget != rollanim) {
2911 if (distsq(&coords, &victim->coords) < (scale * 5) * (scale * 5) * 6.5 && victim->animTarget != dodgebackanim && victim->animTarget != sweepanim) {
2912 if (tutoriallevel != 1) {
2913 weapons[weaponids[0]].damage += .6 + float(abs(Random() % 100) - 50) / 250;
2917 if (Random() % 2 || creature == wolftype) {
2920 emit_sound_at(staffheadsound, victim->coords);
2924 relative = victim->coords - coords;
2926 Normalise(&relative);
2927 relative = DoRotation(relative, 0, -90, 0);
2928 for (i = 0; i < victim->skeleton.num_joints; i++) {
2929 victim->skeleton.joints[i].velocity += relative * damagemult * 40;
2931 victim->skeleton.joints[victim->skeleton.jointlabels[head]].velocity += relative * damagemult * 220;
2932 victim->skeleton.joints[victim->skeleton.jointlabels[neck]].velocity += relative * damagemult * 220;
2935 if (tutoriallevel != 1) {
2936 victim->DoDamage(damagemult * 350 / victim->protectionhead);
2938 award_bonus(id, solidhit, 60);
2943 if (animTarget == staffgroundsmashanim && animation[animTarget].label[frameCurrent] == 5) {
2944 if (distsq(&coords, &victim->coords) < (scale * 5) * (scale * 5) * 6.5) {
2946 if (tutoriallevel != 1) {
2948 weapons[weaponids[0]].damage += .4 + float(abs(Random() % 100) - 50) / 500;
2951 if (Random() % 2 || creature == wolftype) {
2954 emit_sound_at(staffbodysound, victim->coords);
2956 victim->skeleton.longdead = 0;
2957 victim->skeleton.free = 1;
2958 victim->skeleton.broken = 0;
2960 for (i = 0; i < victim->skeleton.num_joints; i++) {
2961 victim->skeleton.joints[i].velchange = 0;
2962 victim->skeleton.joints[i].locked = 0;
2963 //victim->skeleton.joints[i].velocity=0;
2969 /*relative=victim->coords-coords;
2971 Normalise(&relative);
2972 relative=DoRotation(relative,0,90,0);*/
2974 Normalise(&relative);
2975 if (!victim->dead) {
2976 for (i = 0; i < victim->skeleton.num_joints; i++) {
2977 victim->skeleton.joints[i].velocity = relative * damagemult * 40;
2980 victim->skeleton.joints[victim->skeleton.jointlabels[abdomen]].velocity += relative * damagemult * 40;
2983 for (i = 0; i < victim->skeleton.num_joints; i++) {
2984 victim->skeleton.joints[i].velocity = relative * damagemult * abs(Random() % 20);
2987 //victim->skeleton.joints[victim->skeleton.jointlabels[abdomen]].velocity+=relative*damagemult*20;
2989 victim->Puff(abdomen);
2990 if (tutoriallevel != 1) {
2991 victim->DoDamage(damagemult * 100 / victim->protectionhigh);
2993 if (!victim->dead) {
2994 award_bonus(id, solidhit, 40);
3000 if (animTarget == lowkickanim && animation[animTarget].label[frameCurrent] == 5) {
3001 if (distsq(&coords, &victim->coords) < (scale * 5) * (scale * 5) * 3 && animation[victim->animTarget].height != highheight) {
3006 relative = victim->coords - coords;
3008 Normalise(&relative);
3012 if (animation[victim->animTarget].height == lowheight) {
3018 for (i = 0; i < victim->skeleton.num_joints; i++) {
3019 victim->skeleton.joints[i].velocity += relative * damagemult * 40;
3021 victim->skeleton.joints[victim->skeleton.jointlabels[head]].velocity += relative * damagemult * 200;
3022 if (tutoriallevel != 1) {
3023 emit_sound_at(heavyimpactsound, victim->coords, 128.);
3026 victim->DoDamage(damagemult * 100 / victim->protectionhead);
3027 if (victim->howactive == typesleeping)
3028 victim->DoDamage(damagemult * 150 / victim->protectionhead);
3029 if (creature == wolftype) {
3030 emit_sound_at(clawslicesound, victim->coords, 128.);
3032 victim->DoBloodBig(2 / victim->armorhead, 175);
3035 if (victim->damage >= victim->damagetolerance)
3037 for (i = 0; i < victim->skeleton.num_joints; i++) {
3038 victim->skeleton.joints[i].velocity += relative * damagemult * 10;
3040 victim->skeleton.joints[victim->skeleton.jointlabels[abdomen]].velocity += relative * damagemult * 200;
3041 victim->frameTarget = 0;
3042 victim->animTarget = staggerbackhighanim;
3043 victim->targetyaw = targetyaw + 180;
3045 if (tutoriallevel != 1) {
3046 emit_sound_at(landsound2, victim->coords, 128.);
3048 victim->Puff(abdomen);
3049 victim->DoDamage(damagemult * 30 / victim->protectionhigh);
3050 if (creature == wolftype) {
3051 emit_sound_at(clawslicesound, victim->coords, 128.);
3053 victim->DoBloodBig(2 / victim->armorhigh, 170);
3060 if (animTarget == sweepanim && animation[animTarget].label[frameCurrent] == 5) {
3061 if (victim->animTarget != jumpupanim && distsq(&coords, &victim->coords) < (scale * 5) * (scale * 5) * 3 && victim != this) {
3065 if (tutoriallevel != 1) {
3066 emit_sound_at(landsound2, victim->coords, 128.);
3069 relative = victim->coords - coords;
3071 Normalise(&relative);
3073 if (animation[victim->animTarget].height == middleheight || animation[victim->animCurrent].height == middleheight || victim->damage >= victim->damagetolerance - 40) {
3076 for (i = 0; i < victim->skeleton.num_joints; i++) {
3077 victim->skeleton.joints[i].velocity += relative * damagemult * 15;
3079 relative = DoRotation(relative, 0, -90, 0);
3081 for (i = 0; i < victim->skeleton.num_joints; i++) {
3082 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)
3083 victim->skeleton.joints[i].velocity = relative * 80;
3085 victim->Puff(rightankle);
3086 victim->Puff(leftankle);
3087 victim->DoDamage(damagemult * 40 / victim->protectionlow);
3089 if (victim->damage >= victim->damagetolerance)
3091 for (i = 0; i < victim->skeleton.num_joints; i++) {
3092 victim->skeleton.joints[i].velocity += relative * damagemult * 10;
3094 relative = DoRotation(relative, 0, -90, 0);
3095 for (i = 0; i < victim->skeleton.num_joints; i++) {
3096 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)
3097 victim->skeleton.joints[i].velocity += relative * damagemult * 80;
3099 victim->skeleton.joints[victim->skeleton.jointlabels[abdomen]].velocity += relative * damagemult * 200;
3100 victim->frameTarget = 0;
3101 victim->animTarget = staggerbackhighanim;
3102 victim->targetyaw = targetyaw + 180;
3104 if (tutoriallevel != 1) {
3105 emit_sound_at(landsound2, victim->coords, 128.);
3107 victim->Puff(abdomen);
3108 victim->DoDamage(damagemult * 30 / victim->protectionlow);
3116 if (animation[animTarget].attack == reversal && (!victim->feint || (victim->lastattack == victim->lastattack2 && victim->lastattack2 == victim->lastattack3 && Random() % 2) || animTarget == knifefollowanim)) {
3117 if (animTarget == spinkickreversalanim && animation[animTarget].label[frameCurrent] == 7) {
3125 if (tutoriallevel != 1) {
3126 emit_sound_at(heavyimpactsound, victim->coords, 128.);
3128 if (creature == wolftype) {
3129 emit_sound_at(clawslicesound, victim->coords, 128);
3131 victim->DoBloodBig(2 / victim->armorhigh, 170);
3135 relative = victim->coords - oldcoords;
3137 Normalise(&relative);
3138 //relative=DoRotation(relative,0,-90,0);
3139 for (i = 0; i < victim->skeleton.num_joints; i++) {
3140 victim->skeleton.joints[i].velocity += relative * damagemult * 40;
3142 victim->skeleton.joints[victim->skeleton.jointlabels[abdomen]].velocity += relative * damagemult * 200;
3144 victim->Puff(abdomen);
3145 victim->DoDamage(damagemult * 150 / victim->protectionhigh);
3147 award_bonus(id, Reversal);
3150 if ((animTarget == swordslashreversalanim || animTarget == knifeslashreversalanim || animTarget == staffhitreversalanim || animTarget == staffspinhitreversalanim) && animation[animTarget].label[frameCurrent] == 5) {
3151 if (victim->weaponactive != -1 && victim->num_weapons > 0) {
3152 if (weapons[victim->weaponids[victim->weaponactive]].owner == victim->id) {
3153 weapons[victim->weaponids[victim->weaponactive]].owner = id;
3155 if (num_weapons > 0) {
3156 weaponids[num_weapons] = weaponids[victim->weaponactive];
3159 weaponids[0] = victim->weaponids[victim->weaponactive];
3160 victim->num_weapons--;
3161 if (victim->num_weapons > 0) {
3162 victim->weaponids[victim->weaponactive] = victim->weaponids[victim->num_weapons];
3163 //if(victim->weaponstuck==victim->num_weapons)victim->weaponstuck=0;
3165 victim->weaponactive = -1;
3170 if (animTarget == staffhitreversalanim && animation[animTarget].label[frameCurrent] == 5) {
3178 emit_sound_at(whooshhitsound, victim->coords, 128.);
3181 relative = victim->coords - oldcoords;
3183 Normalise(&relative);
3184 //relative=DoRotation(relative,0,-90,0);
3185 for (i = 0; i < victim->skeleton.num_joints; i++) {
3186 victim->skeleton.joints[i].velocity += relative * damagemult * 30;
3188 victim->skeleton.joints[victim->skeleton.jointlabels[abdomen]].velocity += relative * damagemult * 200;
3191 victim->DoDamage(damagemult * 70 / victim->protectionhigh);
3194 if (animTarget == staffspinhitreversalanim && animation[animTarget].label[frameCurrent] == 7) {
3203 award_bonus(id, staffreversebonus);
3205 if (tutoriallevel != 1) {
3206 emit_sound_at(heavyimpactsound, victim->coords, 128.);
3209 award_bonus(id, staffreversebonus); // Huh, again?
3212 relative = victim->coords - oldcoords;
3214 Normalise(&relative);
3215 //relative=DoRotation(relative,0,-90,0);
3216 for (i = 0; i < victim->skeleton.num_joints; i++) {
3217 victim->skeleton.joints[i].velocity += relative * damagemult * 30;
3219 victim->skeleton.joints[victim->skeleton.jointlabels[abdomen]].velocity += relative * damagemult * 200;
3222 victim->DoDamage(damagemult * 70 / victim->protectionhigh);
3225 if (animTarget == upunchreversalanim && animation[animTarget].label[frameCurrent] == 7) {
3231 Normalise(&relative);
3234 for (i = 0; i < victim->skeleton.num_joints; i++) {
3235 victim->skeleton.joints[i].velocity += relative * damagemult * 70;
3237 victim->skeleton.joints[victim->skeleton.jointlabels[lefthand]].velocity *= .1;
3238 victim->skeleton.joints[victim->skeleton.jointlabels[leftwrist]].velocity *= .2;
3239 victim->skeleton.joints[victim->skeleton.jointlabels[leftelbow]].velocity *= .5;
3240 victim->skeleton.joints[victim->skeleton.jointlabels[leftshoulder]].velocity *= .7;
3241 victim->skeleton.joints[victim->skeleton.jointlabels[righthand]].velocity *= .1;
3242 victim->skeleton.joints[victim->skeleton.jointlabels[rightwrist]].velocity *= .2;
3243 victim->skeleton.joints[victim->skeleton.jointlabels[rightelbow]].velocity *= .5;
3244 victim->skeleton.joints[victim->skeleton.jointlabels[rightshoulder]].velocity *= .7;
3246 victim->Puff(abdomen);
3247 victim->DoDamage(damagemult * 90 / victim->protectionhigh);
3249 award_bonus(id, Reversal);
3253 if (weaponactive != -1 || creature == wolftype)
3255 if (creature == rabbittype && weaponactive != -1)
3256 if (weapons[weaponids[0]].getType() == staff)
3259 if (weaponactive != -1) {
3260 victim->DoBloodBig(2 / victim->armorhigh, 225);
3261 emit_sound_at(knifeslicesound, victim->coords);
3262 if (bloodtoggle && !weapons[weaponids[weaponactive]].bloody)
3263 weapons[weaponids[weaponactive]].bloody = 1;
3264 weapons[weaponids[weaponactive]].blooddrip += 3;
3266 if (weaponactive == -1 && creature == wolftype) {
3268 emit_sound_at(clawslicesound, victim->coords, 128.);
3270 victim->DoBloodBig(2 / victim->armorhigh, 175);
3277 if (animTarget == swordslashreversalanim && animation[animTarget].label[frameCurrent] == 7) {
3283 Normalise(&relative);
3286 for (i = 0; i < victim->skeleton.num_joints; i++) {
3287 victim->skeleton.joints[i].velocity += relative * damagemult * 70;
3289 victim->skeleton.joints[victim->skeleton.jointlabels[lefthand]].velocity *= .1 - 1;
3290 victim->skeleton.joints[victim->skeleton.jointlabels[leftwrist]].velocity *= .2 - 1;
3291 victim->skeleton.joints[victim->skeleton.jointlabels[leftelbow]].velocity *= .5 - 1;
3292 victim->skeleton.joints[victim->skeleton.jointlabels[leftshoulder]].velocity *= .7 - 1;
3293 victim->skeleton.joints[victim->skeleton.jointlabels[righthand]].velocity *= .1 - 1;
3294 victim->skeleton.joints[victim->skeleton.jointlabels[rightwrist]].velocity *= .2 - 1;
3295 victim->skeleton.joints[victim->skeleton.jointlabels[rightelbow]].velocity *= .5 - 1;
3296 victim->skeleton.joints[victim->skeleton.jointlabels[rightshoulder]].velocity *= .7 - 1;
3298 award_bonus(id, swordreversebonus);
3301 if (hasvictim && animTarget == knifeslashreversalanim && animation[animTarget].label[frameCurrent] == 7) {
3309 if (tutoriallevel != 1) {
3310 emit_sound_at(heavyimpactsound, victim->coords, 128.);
3314 relative = victim->coords - oldcoords;
3316 Normalise(&relative);
3317 relative = DoRotation(relative, 0, -90, 0);
3318 for (i = 0; i < victim->skeleton.num_joints; i++) {
3319 victim->skeleton.joints[i].velocity += relative * damagemult * 40;
3321 victim->skeleton.joints[victim->skeleton.jointlabels[abdomen]].velocity += relative * damagemult * 200;
3323 victim->Puff(abdomen);
3324 victim->DoDamage(damagemult * 30 / victim->protectionhigh);
3326 award_bonus(id, Reversal);
3329 if (hasvictim && animTarget == sneakattackanim && animation[animTarget].label[frameCurrent] == 7) {
3332 victim->skeleton.spinny = 0;
3334 relative = facing * -1;
3336 Normalise(&relative);
3337 if (victim->id == 0)
3339 for (i = 0; i < victim->skeleton.num_joints; i++) {
3340 victim->skeleton.joints[i].velocity += relative * damagemult * 40;
3342 //victim->DoDamage(1000);
3343 victim->damage = victim->damagetolerance;
3344 victim->permanentdamage = victim->damagetolerance - 1;
3347 if (weaponactive != -1 || creature == wolftype)
3349 if (creature == rabbittype && weaponactive != -1)
3350 if (weapons[weaponids[0]].getType() == staff)
3353 if (weaponactive != -1) {
3354 victim->DoBloodBig(200, 225);
3355 emit_sound_at(knifeslicesound, victim->coords);
3357 weapons[weaponids[weaponactive]].bloody = 2;
3358 weapons[weaponids[weaponactive]].blooddrip += 5;
3361 if (creature == wolftype && weaponactive == -1) {
3362 emit_sound_at(clawslicesound, victim->coords, 128.);
3364 victim->DoBloodBig(2, 175);
3367 award_bonus(id, spinecrusher);
3370 if (hasvictim && (animTarget == knifefollowanim || animTarget == knifesneakattackanim) && animation[animTarget].label[frameCurrent] == 5) {
3371 if (weaponactive != -1 && victim->bloodloss < victim->damagetolerance) {
3373 if (animTarget == knifefollowanim)
3374 victim->DoBloodBig(200, 210);
3375 if (animTarget == knifesneakattackanim) {
3376 /*victim->DoBloodBig(200,195);
3381 bloodvel=DoRotation(bloodvel,((float)(Random()%100))/4,yaw+((float)(Random()%100))/4,0)*scale;
3382 Sprite::MakeSprite(bloodsprite, DoRotation(jointPos(neck),0,yaw,0)*scale+coords,bloodvel, 1,1,1, .05, 1);
3384 XYZ footvel, footpoint;
3386 footpoint = weapons[weaponids[0]].tippoint;
3388 Sprite::MakeSprite(cloudimpactsprite, footpoint, footvel, 1, 0, 0, .9, .3);
3389 footvel = (weapons[weaponids[0]].tippoint - weapons[weaponids[0]].position);
3390 Sprite::MakeSprite(bloodsprite, footpoint, DoRotation(footvel * 7, (float)(Random() % 20), (float)(Random() % 20), 0), 1, 1, 1, .05, .9);
3391 Sprite::MakeSprite(bloodsprite, footpoint, DoRotation(footvel * 3, (float)(Random() % 20), (float)(Random() % 20), 0), 1, 1, 1, .05, .9);
3392 Sprite::MakeSprite(bloodflamesprite, footpoint, footvel * 5, 1, 1, 1, .3, 1);
3393 Sprite::MakeSprite(bloodflamesprite, footpoint, footvel * 2, 1, 1, 1, .3, 1);
3394 victim->DoBloodBig(200, 195);
3395 award_bonus(id, tracheotomy);
3397 if (animTarget == knifefollowanim) {
3398 award_bonus(id, Stabbonus);
3399 XYZ footvel, footpoint;
3401 footpoint = weapons[weaponids[0]].tippoint;
3403 Sprite::MakeSprite(cloudimpactsprite, footpoint, footvel, 1, 0, 0, .9, .3);
3404 footvel = (weapons[weaponids[0]].tippoint - weapons[weaponids[0]].position) * -1;
3405 Sprite::MakeSprite(bloodsprite, footpoint, DoRotation(footvel * 7, (float)(Random() % 20), (float)(Random() % 20), 0), 1, 1, 1, .05, .9);
3406 Sprite::MakeSprite(bloodsprite, footpoint, DoRotation(footvel * 3, (float)(Random() % 20), (float)(Random() % 20), 0), 1, 1, 1, .05, .9);
3407 Sprite::MakeSprite(bloodflamesprite, footpoint, footvel * 5, 1, 1, 1, .2, 1);
3408 Sprite::MakeSprite(bloodflamesprite, footpoint, footvel * 2, 1, 1, 1, .2, 1);
3411 victim->bloodloss += 10000;
3412 victim->velocity = 0;
3413 emit_sound_at(fleshstabsound, victim->coords);
3415 weapons[weaponids[weaponactive]].bloody = 2;
3416 weapons[weaponids[weaponactive]].blooddrip += 5;
3420 if (hasvictim && (animTarget == knifefollowanim || animTarget == knifesneakattackanim) && animation[animTarget].label[frameCurrent] == 6) {
3422 victim->velocity = 0;
3423 for (i = 0; i < victim->skeleton.num_joints; i++) {
3424 victim->skeleton.joints[i].velocity = 0;
3426 if (animTarget == knifefollowanim) {
3428 for (i = 0; i < victim->skeleton.num_joints; i++) {
3429 victim->skeleton.joints[i].velocity = 0;
3432 if (weaponactive != -1 && animation[victim->animTarget].attack != reversal) {
3433 emit_sound_at(fleshstabremovesound, victim->coords);
3435 weapons[weaponids[weaponactive]].bloody = 2;
3436 weapons[weaponids[weaponactive]].blooddrip += 5;
3438 XYZ footvel, footpoint;
3440 footpoint = weapons[weaponids[0]].tippoint;
3442 Sprite::MakeSprite(cloudimpactsprite, footpoint, footvel, 1, 0, 0, .9, .3);
3443 footvel = (weapons[weaponids[0]].tippoint - weapons[weaponids[0]].position) * -1;
3444 Sprite::MakeSprite(bloodsprite, footpoint, DoRotation(footvel * 7, (float)(Random() % 20), (float)(Random() % 20), 0), 1, 1, 1, .05, .9);
3445 Sprite::MakeSprite(bloodsprite, footpoint, DoRotation(footvel * 3, (float)(Random() % 20), (float)(Random() % 20), 0), 1, 1, 1, .05, .9);
3446 Sprite::MakeSprite(bloodflamesprite, footpoint, footvel * 5, 1, 1, 1, .3, 1);
3447 Sprite::MakeSprite(bloodflamesprite, footpoint, footvel * 2, 1, 1, 1, .3, 1);
3451 if (hasvictim && (animTarget == swordsneakattackanim) && animation[animTarget].label[frameCurrent] == 5) {
3452 if (weaponactive != -1 && victim->bloodloss < victim->damagetolerance) {
3453 award_bonus(id, backstab);
3457 XYZ footvel, footpoint;
3459 footpoint = (weapons[weaponids[0]].tippoint + weapons[weaponids[0]].position) / 2;
3461 Sprite::MakeSprite(cloudimpactsprite, footpoint, footvel, 1, 0, 0, .9, .3);
3462 footvel = (weapons[weaponids[0]].tippoint - weapons[weaponids[0]].position);
3463 Sprite::MakeSprite(bloodsprite, footpoint, DoRotation(footvel * 7, (float)(Random() % 20), (float)(Random() % 20), 0), 1, 1, 1, .05, .9);
3464 Sprite::MakeSprite(bloodsprite, footpoint, DoRotation(footvel * 3, (float)(Random() % 20), (float)(Random() % 20), 0), 1, 1, 1, .05, .9);
3465 Sprite::MakeSprite(bloodflamesprite, footpoint, DoRotation(footvel * 5, (float)(Random() % 20), (float)(Random() % 20), 0), 1, 1, 1, .3, 1);
3466 Sprite::MakeSprite(bloodflamesprite, footpoint, DoRotation(footvel * 3, (float)(Random() % 20), (float)(Random() % 20), 0), 1, 1, 1, .3, 1);
3467 victim->DoBloodBig(200, 180);
3468 victim->DoBloodBig(200, 215);
3469 victim->bloodloss += 10000;
3470 victim->velocity = 0;
3471 emit_sound_at(fleshstabsound, victim->coords);
3473 weapons[weaponids[weaponactive]].bloody = 2;
3474 weapons[weaponids[weaponactive]].blooddrip += 5;
3478 if (hasvictim && animTarget == swordsneakattackanim && animation[animTarget].label[frameCurrent] == 6) {
3480 victim->velocity = 0;
3481 for (i = 0; i < victim->skeleton.num_joints; i++) {
3482 victim->skeleton.joints[i].velocity = 0;
3484 if (weaponactive != -1) {
3485 emit_sound_at(fleshstabremovesound, victim->coords);
3487 weapons[weaponids[weaponactive]].bloody = 2;
3488 weapons[weaponids[weaponactive]].blooddrip += 5;
3490 XYZ footvel, footpoint;
3492 footpoint = weapons[weaponids[0]].tippoint;
3494 Sprite::MakeSprite(cloudimpactsprite, footpoint, footvel, 1, 0, 0, .9, .3);
3495 footvel = (weapons[weaponids[0]].tippoint - weapons[weaponids[0]].position) * -1;
3496 Sprite::MakeSprite(bloodsprite, footpoint, DoRotation(footvel * 7, (float)(Random() % 20), (float)(Random() % 20), 0), 1, 1, 1, .05, .9);
3497 Sprite::MakeSprite(bloodsprite, footpoint, DoRotation(footvel * 3, (float)(Random() % 20), (float)(Random() % 20), 0), 1, 1, 1, .05, .9);
3498 Sprite::MakeSprite(bloodflamesprite, footpoint, footvel * 5, 1, 1, 1, .3, 1);
3499 Sprite::MakeSprite(bloodflamesprite, footpoint, footvel * 2, 1, 1, 1, .3, 1);
3503 if (animTarget == sweepreversalanim && animation[animTarget].label[frameCurrent] == 7) {
3511 if (weaponactive == -1) {
3512 if (tutoriallevel != 1) {
3513 emit_sound_at(heavyimpactsound, victim->coords, 128.);
3518 if (weaponactive != -1 || creature == wolftype)
3520 if (creature == rabbittype && weaponactive != -1)
3521 if (weapons[weaponids[0]].getType() == staff)
3524 if (weaponactive != -1) {
3525 victim->DoBloodBig(2 / victim->armorhead, 225);
3526 emit_sound_at(knifeslicesound, victim->coords);
3527 if (bloodtoggle && !weapons[weaponids[weaponactive]].bloody)
3528 weapons[weaponids[weaponactive]].bloody = 1;
3529 weapons[weaponids[weaponactive]].blooddrip += 3;
3531 if (weaponactive == -1 && creature == wolftype) {
3532 emit_sound_at(clawslicesound, victim->coords, 128.);
3534 victim->DoBloodBig(2 / victim->armorhead, 175);
3538 award_bonus(id, Reversal);
3543 //relative=victim->coords-oldcoords;
3544 relative = facing * -1;
3546 Normalise(&relative);
3547 relative = DoRotation(relative, 0, 90, 0);
3549 Normalise(&relative);
3550 for (i = 0; i < victim->skeleton.num_joints; i++) {
3551 victim->skeleton.joints[i].velocity += relative * damagemult * 20;
3553 victim->skeleton.joints[victim->skeleton.jointlabels[head]].velocity += relative * damagemult * 200;
3554 if (victim->damage < victim->damagetolerance - 100)
3555 victim->velocity = relative * 200;
3556 victim->DoDamage(damagemult * 100 / victim->protectionhead);
3557 victim->velocity = 0;
3560 if (animTarget == sweepreversalanim && ((animation[animTarget].label[frameCurrent] == 9 && victim->damage < victim->damagetolerance) || (animation[animTarget].label[frameCurrent] == 7 && victim->damage > victim->damagetolerance))) {
3564 //relative=victim->coords-oldcoords;
3565 relative = facing * -1;
3567 Normalise(&relative);
3568 relative = DoRotation(relative, 0, 90, 0);
3570 Normalise(&relative);
3571 for (i = 0; i < victim->skeleton.num_joints; i++) {
3572 victim->skeleton.joints[i].velocity += relative * damagemult * 20;
3574 victim->skeleton.joints[victim->skeleton.jointlabels[head]].velocity += relative * damagemult * 200;
3577 if (hasvictim && (animTarget == spinkickreversalanim || animTarget == sweepreversalanim || animTarget == rabbitkickreversalanim || animTarget == upunchreversalanim || animTarget == jumpreversalanim || animTarget == swordslashreversalanim || animTarget == knifeslashreversalanim || animTarget == rabbittacklereversal || animTarget == wolftacklereversal || animTarget == staffhitreversalanim || animTarget == staffspinhitreversalanim))
3578 if (victim->damage > victim->damagetolerance && bonus != reverseko) {
3579 award_bonus(id, reverseko);
3585 if (frameTarget > animation[animCurrent].numframes - 1) {
3588 animTarget = getIdle();
3592 if (animCurrent == rabbittackleanim || animCurrent == rabbittacklinganim) {
3593 animTarget = rollanim;
3595 emit_sound_at(movewhooshsound, coords, 128.);
3597 if (animCurrent == staggerbackhighanim) {
3598 animTarget = getIdle();
3600 if (animCurrent == staggerbackhardanim) {
3601 animTarget = getIdle();
3603 if (animCurrent == removeknifeanim) {
3604 animTarget = getIdle();
3606 if (animCurrent == crouchremoveknifeanim) {
3607 animTarget = getCrouch();
3609 if (animCurrent == backhandspringanim) {
3610 animTarget = getIdle();
3612 if (animCurrent == dodgebackanim) {
3613 animTarget = getIdle();
3615 if (animCurrent == drawleftanim) {
3616 animTarget = getIdle();
3618 if (animCurrent == drawrightanim || animCurrent == crouchdrawrightanim) {
3619 animTarget = getIdle();
3620 if (animCurrent == crouchdrawrightanim) {
3621 animTarget = getCrouch();
3623 if (weaponactive == -1)
3625 else if (weaponactive == 0) {
3627 if (num_weapons == 2) {
3629 buffer = weaponids[0];
3630 weaponids[0] = weaponids[1];
3631 weaponids[1] = buffer;
3635 if (weaponactive == -1) {
3636 emit_sound_at(knifesheathesound, coords, 128.);
3638 if (weaponactive != -1) {
3639 emit_sound_at(knifedrawsound, coords, 128.);
3642 if (animCurrent == rollanim) {
3643 animTarget = getCrouch();
3648 if (animTarget == walljumprightkickanim) {
3651 if (animTarget == walljumpleftkickanim) {
3654 animTarget = jumpdownanim;
3656 if (animCurrent == climbanim) {
3657 animTarget = getCrouch();
3659 coords += facing * .1;
3660 if (!isnormal(coords.x))
3671 if (animTarget == rabbitkickreversalanim) {
3672 animTarget = getCrouch();
3675 if (animTarget == jumpreversalanim) {
3676 animTarget = getCrouch();
3679 if (animTarget == walljumprightanim || animTarget == walljumpbackanim || animTarget == walljumpfrontanim) {
3680 if (attackkeydown && animTarget != walljumpfrontanim) {
3682 float closestdist = -1;
3685 for (i = 0; i < numplayers; i++) {
3686 if (id != i && player[i].coords.y < coords.y && !player[i].skeleton.free) {
3687 distance = distsq(&player[i].coords, &coords);
3688 if (closestdist == -1 || distance < closestdist) {
3689 closestdist = distance;
3694 if (closestdist > 0 && closest >= 0 && closestdist < 16) {
3695 victim = &player[closest];
3696 animTarget = walljumprightkickanim;
3698 XYZ rotatetarget = victim->coords - coords;
3699 Normalise(&rotatetarget);
3700 yaw = -asin(0 - rotatetarget.x);
3702 if (rotatetarget.z < 0)
3704 targettilt2 = -asin(rotatetarget.y) * 360 / 6.28;
3705 velocity = (victim->coords - coords) * 4;
3710 if (animTarget == walljumpbackanim) {
3711 animTarget = backflipanim;
3713 velocity = facing * -8;
3716 resume_stream(whooshsound);
3718 if (animTarget == walljumprightanim) {
3719 animTarget = rightflipanim;
3723 velocity = DoRotation(facing, 0, 30, 0) * -8;
3726 if (animTarget == walljumpfrontanim) {
3727 animTarget = frontflipanim;
3731 velocity = facing * 8;
3735 resume_stream(whooshsound);
3737 if (animTarget == walljumpleftanim) {
3738 if (attackkeydown) {
3740 float closestdist = -1;
3743 for (i = 0; i < numplayers; i++) {
3744 if (id != i && player[i].coords.y < coords.y && !player[i].skeleton.free) {
3745 distance = distsq(&player[i].coords, &coords);
3746 if (closestdist == -1 || distance < closestdist) {
3747 closestdist = distance;
3752 if (closestdist > 0 && closest >= 0 && closestdist < 16) {
3753 victim = &player[closest];
3754 animTarget = walljumpleftkickanim;
3756 XYZ rotatetarget = victim->coords - coords;
3757 Normalise(&rotatetarget);
3758 yaw = -asin(0 - rotatetarget.x);
3760 if (rotatetarget.z < 0)
3762 targettilt2 = -asin(rotatetarget.y) * 360 / 6.28;
3763 velocity = (victim->coords - coords) * 4;
3768 if (animTarget != walljumpleftkickanim) {
3769 animTarget = leftflipanim;
3773 velocity = DoRotation(facing, 0, -30, 0) * -8;
3777 resume_stream(whooshsound);
3779 if (animTarget == sneakattackanim) {
3780 animCurrent = getCrouch();
3781 animTarget = getCrouch();
3788 transspeed = 1000000;
3789 targetheadyaw += 180;
3790 coords -= facing * .7;
3792 coords.y = terrain.getHeight(coords.x, coords.z);
3796 if (animTarget == knifesneakattackanim || animTarget == swordsneakattackanim) {
3797 animTarget = getIdle();
3800 coords.y = terrain.getHeight(coords.x, coords.z);
3804 if (animCurrent == knifefollowanim) {
3805 animTarget = getIdle();
3808 if (animation[animTarget].attack == reversal && animCurrent != sneakattackanim && animCurrent != knifesneakattackanim && animCurrent != swordsneakattackanim && animCurrent != knifefollowanim) {
3809 float ycoords = oldcoords.y;
3810 animTarget = getStop();
3815 transspeed = 1000000;
3816 targetheadyaw += 180;
3817 if (!isnormal(coords.x))
3819 if (animCurrent == spinkickreversalanim || animCurrent == swordslashreversalanim)
3820 oldcoords = coords + facing * .5;
3821 else if (animCurrent == sweepreversalanim)
3822 oldcoords = coords + facing * 1.1;
3823 else if (animCurrent == upunchreversalanim) {
3824 oldcoords = coords + facing * 1.5;
3827 targetheadyaw += 180;
3830 } else if (animCurrent == knifeslashreversalanim) {
3831 oldcoords = coords + facing * .5;
3834 targetheadyaw += 90;
3837 } else if (animCurrent == staffspinhitreversalanim) {
3840 targetheadyaw += 180;
3845 oldcoords.y = terrain.getHeight(oldcoords.x, oldcoords.z);
3847 oldcoords.y = ycoords;
3848 currentoffset = coords - oldcoords;
3854 if (animCurrent == knifesneakattackedanim || animCurrent == swordsneakattackedanim) {
3859 if (animation[animTarget].attack == reversed) {
3861 if (animTarget == sweepreversedanim)
3863 animTarget = backhandspringanim;
3865 emit_sound_at(landsound, coords, 128);
3867 if (animCurrent == upunchreversedanim || animCurrent == swordslashreversedanim) {
3868 animTarget = rollanim;
3871 coords += (DoRotation(jointPos(leftfoot), 0, yaw, 0) + DoRotation(jointPos(rightfoot), 0, yaw, 0)) / 2 * scale;
3872 coords.y = oldcoords.y;
3874 if (animCurrent == knifeslashreversedanim) {
3875 animTarget = rollanim;
3880 coords += (DoRotation(jointPos(leftfoot), 0, yaw, 0) + DoRotation(jointPos(rightfoot), 0, yaw, 0)) / 2 * scale;
3881 coords.y = oldcoords.y;
3885 animTarget = jumpdownanim;
3888 animTarget = getIdle();
3890 animTarget = getIdle();
3891 if (animCurrent == spinkickanim || animCurrent == getupfrombackanim || animCurrent == getupfromfrontanim || animCurrent == lowkickanim) {
3892 animTarget = getIdle();
3894 coords += (DoRotation(jointPos(leftfoot), 0, yaw, 0) + DoRotation(jointPos(rightfoot), 0, yaw, 0)) / 2 * scale;
3895 coords.y = oldcoords.y;
3896 //coords+=DoRotation(animation[animCurrent].offset,0,yaw,0)*scale;
3897 targetoffset.y = coords.y;
3899 targetoffset.y = terrain.getHeight(coords.x, coords.z);
3900 currentoffset = DoRotation(animation[animCurrent].offset * -1, 0, yaw, 0) * scale;
3901 currentoffset.y -= (coords.y - targetoffset.y);
3902 coords.y = targetoffset.y;
3904 normalsupdatedelay = 0;
3906 if (animCurrent == upunchanim) {
3907 animTarget = getStop();
3908 normalsupdatedelay = 0;
3911 if (animCurrent == rabbitkickanim && animTarget != backflipanim) {
3915 if (num_weapons > 0)
3916 if (weapons[0].getType() == staff)
3922 rabbitkickragdoll = 1;
3924 if (animCurrent == rabbitkickreversedanim) {
3930 skeleton.spinny = 0;
3931 SolidHitBonus(!id); // FIXME: tricky id
3935 animTarget = rollanim;
3938 pause_sound(whooshsound);
3942 if (animCurrent == rabbittackledbackanim || animCurrent == rabbittackledfrontanim) {
3946 skeleton.spinny = 0;
3948 if (animCurrent == jumpreversedanim) {
3954 skeleton.spinny = 0;
3955 SolidHitBonus(!id); // FIXME: tricky id
3959 animTarget = rollanim;
3960 coords += facing * 2;
3962 pause_sound(whooshsound);
3967 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) {
3968 animTarget = getupfromfrontanim;
3970 } else if (animation[animCurrent].attack == normalattack) {
3971 animTarget = getIdle();
3974 if (animCurrent == blockhighleftanim && aitype != playercontrolled) {
3975 animTarget = blockhighleftstrikeanim;
3977 if (animCurrent == knifeslashstartanim || animCurrent == knifethrowanim || animCurrent == swordslashanim || animCurrent == staffhitanim || animCurrent == staffgroundsmashanim || animCurrent == staffspinhitanim) {
3978 animTarget = getIdle();
3981 if (animCurrent == spinkickanim && victim->skeleton.free) {
3982 if (creature == rabbittype)
3983 animTarget = fightidleanim;
3988 if (isIdle() && !wasIdle())
3989 normalsupdatedelay = 0;
3991 if (animCurrent == jumpupanim && velocity.y < 0 && !isFlip()) {
3992 animTarget = jumpdownanim;
3995 if (!skeleton.free) {
3997 if (!transspeed && animation[animTarget].attack != 2 && animation[animTarget].attack != 3) {
3998 if (!isRun() || !wasRun()) {
3999 if (animation[animTarget].speed[frameTarget] > animation[animCurrent].speed[frameCurrent])
4000 target += multiplier * animation[animTarget].speed[frameTarget] * speed * 2;
4001 if (animation[animTarget].speed[frameTarget] <= animation[animCurrent].speed[frameCurrent])
4002 target += multiplier * animation[animCurrent].speed[frameCurrent] * speed * 2;
4004 if (isRun() && wasRun()) {
4006 tempspeed = velspeed;
4007 if (tempspeed < 10 * speedmult)
4008 tempspeed = 10 * speedmult;
4009 target += multiplier * animation[animTarget].speed[frameCurrent] * speed * 1.7 * tempspeed / (speed * 45 * scale);
4011 } else if (transspeed)
4012 target += multiplier * transspeed * speed * 2;
4014 if (!isRun() || !wasRun()) {
4015 if (animation[animTarget].speed[frameTarget] > animation[animCurrent].speed[frameCurrent])
4016 target += multiplier * animation[animTarget].speed[frameTarget] * 2;
4017 if (animation[animTarget].speed[frameTarget] <= animation[animCurrent].speed[frameCurrent])
4018 target += multiplier * animation[animCurrent].speed[frameCurrent] * 2;
4022 if (animCurrent != animTarget)
4023 target = (target + oldtarget) / 2;
4026 frameCurrent = frameTarget;
4030 rot = targetrot * target;
4031 yaw += rot - oldrot;
4037 if (animCurrent != oldanimCurrent || animTarget != oldanimTarget || ((frameCurrent != oldframeCurrent || frameTarget != oldframeTarget) && !calcrot)) {
4039 for (i = 0; i < skeleton.num_joints; i++) {
4040 skeleton.joints[i].position = animation[animCurrent].position[i][frameCurrent];
4043 skeleton.FindForwards();
4045 for (i = 0; i < skeleton.num_muscles; i++) {
4046 if (skeleton.muscles[i].visible) {
4047 skeleton.FindRotationMuscle(i, animTarget);
4050 for (i = 0; i < skeleton.num_muscles; i++) {
4051 if (skeleton.muscles[i].visible) {
4052 if (isnormal((float)((int)(skeleton.muscles[i].rotate1 * 100) % 36000) / 100))
4053 skeleton.muscles[i].oldrotate1 = (float)((int)(skeleton.muscles[i].rotate1 * 100) % 36000) / 100;
4054 if (isnormal((float)((int)(skeleton.muscles[i].rotate2 * 100) % 36000) / 100))
4055 skeleton.muscles[i].oldrotate2 = (float)((int)(skeleton.muscles[i].rotate2 * 100) % 36000) / 100;
4056 if (isnormal((float)((int)(skeleton.muscles[i].rotate3 * 100) % 36000) / 100))
4057 skeleton.muscles[i].oldrotate3 = (float)((int)(skeleton.muscles[i].rotate3 * 100) % 36000) / 100;
4062 for (i = 0; i < skeleton.num_joints; i++) {
4063 skeleton.joints[i].position = animation[animTarget].position[i][frameTarget];
4066 skeleton.FindForwards();
4068 for (i = 0; i < skeleton.num_muscles; i++) {
4069 if (skeleton.muscles[i].visible) {
4070 skeleton.FindRotationMuscle(i, animTarget);
4073 for (i = 0; i < skeleton.num_muscles; i++) {
4074 if (skeleton.muscles[i].visible) {
4075 if (isnormal((float)((int)(skeleton.muscles[i].rotate1 * 100) % 36000) / 100))
4076 skeleton.muscles[i].newrotate1 = (float)((int)(skeleton.muscles[i].rotate1 * 100) % 36000) / 100;
4077 if (isnormal((float)((int)(skeleton.muscles[i].rotate2 * 100) % 36000) / 100))
4078 skeleton.muscles[i].newrotate2 = (float)((int)(skeleton.muscles[i].rotate2 * 100) % 36000) / 100;
4079 if (isnormal((float)((int)(skeleton.muscles[i].rotate3 * 100) % 36000) / 100))
4080 skeleton.muscles[i].newrotate3 = (float)((int)(skeleton.muscles[i].rotate3 * 100) % 36000) / 100;
4081 if (skeleton.muscles[i].newrotate3 > skeleton.muscles[i].oldrotate3 + 180) skeleton.muscles[i].newrotate3 -= 360;
4082 if (skeleton.muscles[i].newrotate3 < skeleton.muscles[i].oldrotate3 - 180) skeleton.muscles[i].newrotate3 += 360;
4083 if (skeleton.muscles[i].newrotate2 > skeleton.muscles[i].oldrotate2 + 180) skeleton.muscles[i].newrotate2 -= 360;
4084 if (skeleton.muscles[i].newrotate2 < skeleton.muscles[i].oldrotate2 - 180) skeleton.muscles[i].newrotate2 += 360;
4085 if (skeleton.muscles[i].newrotate1 > skeleton.muscles[i].oldrotate1 + 180) skeleton.muscles[i].newrotate1 -= 360;
4086 if (skeleton.muscles[i].newrotate1 < skeleton.muscles[i].oldrotate1 - 180) skeleton.muscles[i].newrotate1 += 360;
4090 if (frameCurrent >= animation[animCurrent].numframes)
4091 frameCurrent = animation[animCurrent].numframes - 1;
4093 oldanimCurrent = animCurrent;
4094 oldanimTarget = animTarget;
4095 oldframeTarget = frameTarget;
4096 oldframeCurrent = frameCurrent;
4098 for (i = 0; i < skeleton.num_joints; i++) {
4099 skeleton.joints[i].velocity = (animation[animCurrent].position[i][frameCurrent] * (1 - target) + animation[animTarget].position[i][frameTarget] * (target) - skeleton.joints[i].position) / multiplier;
4100 skeleton.joints[i].position = animation[animCurrent].position[i][frameCurrent] * (1 - target) + animation[animTarget].position[i][frameTarget] * (target);
4102 offset = currentoffset * (1 - target) + targetoffset * target;
4103 for (i = 0; i < skeleton.num_muscles; i++) {
4104 if (skeleton.muscles[i].visible) {
4105 skeleton.muscles[i].rotate1 = skeleton.muscles[i].oldrotate1 * (1 - target) + skeleton.muscles[i].newrotate1 * (target);
4106 skeleton.muscles[i].rotate2 = skeleton.muscles[i].oldrotate2 * (1 - target) + skeleton.muscles[i].newrotate2 * (target);
4107 skeleton.muscles[i].rotate3 = skeleton.muscles[i].oldrotate3 * (1 - target) + skeleton.muscles[i].newrotate3 * (target);
4112 if (isLanding() && landhard) {
4115 animTarget = getLandhard();
4122 //skeleton.DoConstraints();
4129 void Person::DoStuff()
4131 static XYZ terrainnormal;
4132 static XYZ flatfacing;
4133 static XYZ flatvelocity;
4134 static float flatvelspeed;
4138 static int bloodsize;
4139 static int startx, starty, endx, endy;
4140 static GLubyte color;
4141 static XYZ bloodvel;
4143 onfiredelay -= multiplier;
4144 if (onfiredelay < 0 && onfire) {
4145 if (Random() % 2 == 0) {
4151 crouchkeydowntime += multiplier;
4153 crouchkeydowntime = 0;
4154 jumpkeydowntime += multiplier;
4155 if (!jumpkeydown && skeleton.free)
4156 jumpkeydowntime = 0;
4158 if (hostile || damage > 0 || bloodloss > 0)
4161 if (isIdle() || isRun())
4164 if (num_weapons == 1 && weaponactive != -1)
4168 blooddimamount -= multiplier * .3;
4169 speechdelay -= multiplier;
4170 texupdatedelay -= multiplier;
4171 interestdelay -= multiplier;
4172 flamedelay -= multiplier;
4173 parriedrecently -= multiplier;
4180 speed = 1.1 * speedmult;
4182 speed = 1.0 * speedmult;
4184 rabbitkickragdoll = 0;
4188 if (id != 0 && (creature == rabbittype || difficulty != 2))
4190 if (id != 0 && creature == wolftype && difficulty == 2) {
4192 if (aitype != passivetype) {
4194 if (aitype == attacktypecutoff && (player[0].isIdle() || player[0].isCrouch() || player[0].skeleton.free || player[0].animTarget == getupfrombackanim || player[0].animTarget == getupfromfrontanim || player[0].animTarget == sneakanim) && distsq(&coords, &player[0].coords) < 16) {
4200 if (animTarget == wolfrunninganim && !superruntoggle) {
4201 animTarget = getRun();
4205 if (weaponactive == -1 && num_weapons > 0) {
4206 if (weapons[weaponids[0]].getType() == staff) {
4212 burnt += multiplier;
4213 /*if(aitype!=playercontrolled)*///deathbleeding=5;
4214 /*if(aitype!=playercontrolled)*/
4218 OPENAL_SetVolume(channels[stream_firesound], 256 + 256 * findLength(&velocity) / 3);
4220 if (animTarget == jumpupanim || animTarget == jumpdownanim || isFlip()) {
4226 vel[0] = velocity.x;
4227 vel[1] = velocity.y;
4228 vel[2] = velocity.z;
4231 OPENAL_3D_SetAttributes(channels[whooshsound], gLoc, vel);
4232 OPENAL_SetVolume(channels[whooshsound], 64 * findLength(&velocity) / 5);
4236 while (flamedelay < 0 && onfire) {
4238 howmany = abs(Random() % (skeleton.num_joints));
4240 flatvelocity = (coords - oldcoords) / multiplier / 2; //velocity/2;
4242 flatvelocity = skeleton.joints[howmany].velocity * scale / 2;
4244 flatfacing = DoRotation(DoRotation(DoRotation(skeleton.joints[howmany].position, 0, 0, tilt), tilt2, 0, 0), 0, yaw, 0) * scale + coords;
4246 flatfacing = skeleton.joints[howmany].position * scale + coords;
4247 Sprite::MakeSprite(flamesprite, flatfacing, flatvelocity, 1, 1, 1, .6 + (float)abs(Random() % 100) / 200 - .25, 1);
4250 while (flamedelay < 0 && !onfire && tutoriallevel == 1 && id != 0) {
4252 howmany = abs(Random() % (skeleton.num_joints));
4254 flatvelocity = (coords - oldcoords) / multiplier / 2; //velocity/2;
4256 flatvelocity = skeleton.joints[howmany].velocity * scale / 2;
4258 flatfacing = DoRotation(DoRotation(DoRotation(skeleton.joints[howmany].position, 0, 0, tilt), tilt2, 0, 0), 0, yaw, 0) * scale + coords;
4260 flatfacing = skeleton.joints[howmany].position * scale + coords;
4261 Sprite::MakeSprite(breathsprite, flatfacing, flatvelocity, 1, 1, 1, .6 + (float)abs(Random() % 100) / 200 - .25, .3);
4265 bleeding -= multiplier * .3;
4266 if (bloodtoggle == 2) {
4267 skeleton.drawmodel.textureptr.bind();
4268 if (bleeding <= 0 && (detail != 2 || osx))
4273 if (neckspurtamount > 0) {
4274 neckspurtamount -= multiplier;
4275 neckspurtdelay -= multiplier * 3;
4276 neckspurtparticledelay -= multiplier * 3;
4277 if (neckspurtparticledelay < 0 && neckspurtdelay > 2) {
4280 if (!skeleton.free) {
4281 bloodvel.z = 5 * neckspurtamount;
4282 bloodvel = DoRotation(bloodvel, ((float)(Random() % 100)) / 40, yaw + ((float)(Random() % 100)) / 40, 0) * scale;
4284 if (skeleton.free) {
4285 bloodvel -= DoRotation(skeleton.forward * 10 * scale, ((float)(Random() % 100)) / 40, ((float)(Random() % 100)) / 40, 0);
4288 bloodvel += DoRotation(jointVel(head), ((float)(Random() % 100)) / 40, yaw + ((float)(Random() % 100)) / 40, 0) * scale;
4290 bloodvel += DoRotation(velocity, ((float)(Random() % 100)) / 40, ((float)(Random() % 100)) / 40, 0) * scale;
4292 Sprite::MakeSprite(bloodsprite, (jointPos(neck) + (jointPos(neck) - jointPos(head)) / 5)*scale + coords, bloodvel, 1, 1, 1, .05, .9);
4294 Sprite::MakeSprite(bloodsprite, DoRotation(jointPos(neck) + (jointPos(neck) - jointPos(head)) / 5, 0, yaw, 0)*scale + coords, bloodvel, 1, 1, 1, .05, .9);
4295 neckspurtparticledelay = .05;
4297 if (neckspurtdelay < 0) {
4302 if (deathbleeding > 0 && dead != 2) {
4303 if (deathbleeding < 5)
4304 bleeddelay -= deathbleeding * multiplier / 4;
4306 bleeddelay -= 5 * multiplier / 4;
4307 if (bleeddelay < 0 && bloodtoggle) {
4313 bloodvel += DoRotation(jointVel(abdomen), ((float)(Random() % 100)) / 4, yaw + ((float)(Random() % 100)) / 4, 0) * scale;
4315 bloodvel += DoRotation(velocity, ((float)(Random() % 100)) / 4, ((float)(Random() % 100)) / 4, 0) * scale;
4317 Sprite::MakeSprite(bloodsprite, jointPos(abdomen) * scale + coords, bloodvel, 1, 1, 1, .05, 1);
4319 Sprite::MakeSprite(bloodsprite, DoRotation((jointPos(abdomen) + jointPos(abdomen)) / 2, 0, yaw, 0)*scale + coords, bloodvel, 1, 1, 1, .05, 1);
4322 bloodloss += deathbleeding * multiplier * 80;
4323 deathbleeding -= multiplier * 1.6;
4324 //if(id==0)deathbleeding-=multiplier*.2;
4325 if (deathbleeding < 0)
4327 if (bloodloss > damagetolerance && animation[animTarget].attack == neutral) {
4328 if (weaponactive != -1) {
4329 weapons[weaponids[0]].owner = -1;
4330 weapons[weaponids[0]].velocity = velocity * scale * -.3;
4331 weapons[weaponids[0]].velocity.x += .01;
4332 weapons[weaponids[0]].tipvelocity = velocity * scale;
4333 weapons[weaponids[0]].missed = 1;
4334 weapons[weaponids[0]].hitsomething = 0;
4335 weapons[weaponids[0]].freetime = 0;
4336 weapons[weaponids[0]].firstfree = 1;
4337 weapons[weaponids[0]].physics = 1;
4340 weaponids[0] = weaponids[num_weapons];
4341 if (weaponstuck == num_weapons)
4345 for (i = 0; i < numplayers; i++) {
4346 player[i].wentforweapon = 0;
4358 if (!dead && creature == wolftype) {
4359 award_bonus(0, Wolfbonus);
4362 if (animTarget == knifefollowedanim && !skeleton.free) {
4363 for (i = 0; i < skeleton.num_joints; i++) {
4364 skeleton.joints[i].velocity = 0;
4365 skeleton.joints[i].velocity.y = -2;
4368 if (id != 0 && unconscioustime > .1) {
4376 if (texupdatedelay < 0 && bleeding > 0 && bloodtoggle == 2 && distsq(&viewer, &coords) < 9) {
4377 texupdatedelay = .12;
4379 bloodsize = 5 - realtexdetail;
4383 startx = bleedy; //abs(Random()%(skeleton.skinsize-bloodsize-1));
4384 starty = bleedx; //abs(Random()%(skeleton.skinsize-bloodsize-1));
4385 endx = startx + bloodsize;
4386 endy = starty + bloodsize;
4396 if (endx > skeleton.skinsize - 1) {
4397 endx = skeleton.skinsize - 1;
4400 if (endy > skeleton.skinsize - 1) {
4401 endy = skeleton.skinsize - 1;
4409 for (i = startx; i < endx; i++) {
4410 for (j = starty; j < endy; j++) {
4411 if (Random() % 2 == 0) {
4412 color = Random() % 85 + 170;
4413 if (skeleton.skinText[i * skeleton.skinsize * 3 + j * 3 + 0] > color / 2)
4414 skeleton.skinText[i * skeleton.skinsize * 3 + j * 3 + 0] = color / 2;
4415 skeleton.skinText[i * skeleton.skinsize * 3 + j * 3 + 1] = 0;
4416 skeleton.skinText[i * skeleton.skinsize * 3 + j * 3 + 2] = 0;
4420 if (!osx && detail > 1) {
4421 skeleton.drawmodel.textureptr.bind();
4425 if (!skeleton.free) {
4426 bleedy -= 4 / realtexdetail;
4428 bleedx += (abs(Random() % 3) - 1) * 2 / realtexdetail;
4430 bleedx += (abs(Random() % 3) - 1) * 4 / realtexdetail;
4432 if (skeleton.free) {
4433 bleedx += 4 * direction / realtexdetail;
4435 bleedy += (abs(Random() % 3) - 1) * 2 / realtexdetail;
4437 bleedy += (abs(Random() % 3) - 1) * 4 / realtexdetail;
4441 if (abs(righthandmorphness - targetrighthandmorphness) < multiplier * 4) {
4442 righthandmorphness = targetrighthandmorphness;
4443 righthandmorphstart = righthandmorphend;
4444 } else if (righthandmorphness > targetrighthandmorphness) {
4445 righthandmorphness -= multiplier * 4;
4446 } else if (righthandmorphness < targetrighthandmorphness) {
4447 righthandmorphness += multiplier * 4;
4450 if (abs(lefthandmorphness - targetlefthandmorphness) < multiplier * 4) {
4451 lefthandmorphness = targetlefthandmorphness;
4452 lefthandmorphstart = lefthandmorphend;
4453 } else if (lefthandmorphness > targetlefthandmorphness) {
4454 lefthandmorphness -= multiplier * 4;
4455 } else if (lefthandmorphness < targetlefthandmorphness) {
4456 lefthandmorphness += multiplier * 4;
4459 if (creature == rabbittype || targettailmorphness == 5 || targettailmorphness == 0) {
4460 if (abs(tailmorphness - targettailmorphness) < multiplier * 10) {
4461 tailmorphness = targettailmorphness;
4462 tailmorphstart = tailmorphend;
4463 } else if (tailmorphness > targettailmorphness) {
4464 tailmorphness -= multiplier * 10;
4465 } else if (tailmorphness < targettailmorphness) {
4466 tailmorphness += multiplier * 10;
4470 if (creature == wolftype) {
4471 if (abs(tailmorphness - targettailmorphness) < multiplier * 4) {
4472 tailmorphness = targettailmorphness;
4473 tailmorphstart = tailmorphend;
4474 } else if (tailmorphness > targettailmorphness) {
4475 tailmorphness -= multiplier * 2;
4476 } else if (tailmorphness < targettailmorphness) {
4477 tailmorphness += multiplier * 2;
4481 if (headmorphend == 3 || headmorphstart == 3) {
4482 if (abs(headmorphness - targetheadmorphness) < multiplier * 7) {
4483 headmorphness = targetheadmorphness;
4484 headmorphstart = headmorphend;
4485 } else if (headmorphness > targetheadmorphness) {
4486 headmorphness -= multiplier * 7;
4487 } else if (headmorphness < targetheadmorphness) {
4488 headmorphness += multiplier * 7;
4490 } else if (headmorphend == 5 || headmorphstart == 5) {
4491 if (abs(headmorphness - targetheadmorphness) < multiplier * 10) {
4492 headmorphness = targetheadmorphness;
4493 headmorphstart = headmorphend;
4494 } else if (headmorphness > targetheadmorphness) {
4495 headmorphness -= multiplier * 10;
4496 } else if (headmorphness < targetheadmorphness) {
4497 headmorphness += multiplier * 10;
4500 if (abs(headmorphness - targetheadmorphness) < multiplier * 4) {
4501 headmorphness = targetheadmorphness;
4502 headmorphstart = headmorphend;
4503 } else if (headmorphness > targetheadmorphness) {
4504 headmorphness -= multiplier * 4;
4505 } else if (headmorphness < targetheadmorphness) {
4506 headmorphness += multiplier * 4;
4510 if (abs(chestmorphness - targetchestmorphness) < multiplier) {
4511 chestmorphness = targetchestmorphness;
4512 chestmorphstart = chestmorphend;
4513 } else if (chestmorphness > targetchestmorphness) {
4514 chestmorphness -= multiplier;
4515 } else if (chestmorphness < targetchestmorphness) {
4516 chestmorphness += multiplier;
4519 if (dead != 2 && howactive <= typesleeping) {
4520 if (chestmorphstart == 0 && chestmorphend == 0) {
4522 targetchestmorphness = 1;
4525 if (chestmorphstart != 0 && chestmorphend != 0) {
4527 targetchestmorphness = 1;
4529 if (environment == snowyenvironment) {
4533 footvel = DoRotation(skeleton.specialforward[0], 0, yaw, 0) * -1;
4535 footvel = skeleton.specialforward[0] * -1;
4537 footpoint = DoRotation((jointPos(head) + jointPos(neck)) / 2, 0, yaw, 0) * scale + coords;
4539 footpoint = ((jointPos(head) + jointPos(neck)) / 2) * scale + coords;
4540 if (animTarget == sleepanim)
4541 footvel = DoRotation(footvel, 0, 90, 0);
4542 Sprite::MakeSprite(breathsprite, footpoint + footvel * .2, footvel * .4, 1, 1, 1, .4, .3);
4546 if (!dead && howactive < typesleeping) {
4547 blinkdelay -= multiplier * 2;
4548 if (headmorphstart == 0 && headmorphend == 0 && blinkdelay <= 0) {
4550 targetheadmorphness = 1;
4552 blinkdelay = (float)(abs(Random() % 40)) / 5;
4554 if (headmorphstart == 3 && headmorphend == 3) {
4556 targetheadmorphness = 1;
4561 twitchdelay -= multiplier * 1.5;
4562 if (animTarget != hurtidleanim) {
4563 if (headmorphstart == 0 && headmorphend == 0 && twitchdelay <= 0) {
4565 targetheadmorphness = 1;
4567 twitchdelay = (float)(abs(Random() % 40)) / 5;
4569 if (headmorphstart == 5 && headmorphend == 5) {
4571 targetheadmorphness = 1;
4575 if ((isIdle() || isCrouch()) && animTarget != hurtidleanim) {
4576 twitchdelay3 -= multiplier * 1;
4577 if (Random() % 2 == 0) {
4578 if (righthandmorphstart == 0 && righthandmorphend == 0 && twitchdelay3 <= 0) {
4579 righthandmorphness = 0;
4580 targetrighthandmorphness = 1;
4581 righthandmorphend = 1;
4582 if (Random() % 2 == 0)twitchdelay3 = (float)(abs(Random() % 40)) / 5;
4584 if (righthandmorphstart == 1 && righthandmorphend == 1) {
4585 righthandmorphness = 0;
4586 targetrighthandmorphness = 1;
4587 righthandmorphend = 0;
4590 if (Random() % 2 == 0) {
4591 if (lefthandmorphstart == 0 && lefthandmorphend == 0 && twitchdelay3 <= 0) {
4592 lefthandmorphness = 0;
4593 targetlefthandmorphness = 1;
4594 lefthandmorphend = 1;
4595 twitchdelay3 = (float)(abs(Random() % 40)) / 5;
4597 if (lefthandmorphstart == 1 && lefthandmorphend == 1) {
4598 lefthandmorphness = 0;
4599 targetlefthandmorphness = 1;
4600 lefthandmorphend = 0;
4606 if (creature == rabbittype) {
4607 if (howactive < typesleeping)
4608 twitchdelay2 -= multiplier * 1.5;
4610 twitchdelay2 -= multiplier * 0.5;
4611 if (howactive <= typesleeping) {
4612 if (tailmorphstart == 0 && tailmorphend == 0 && twitchdelay2 <= 0) {
4614 targettailmorphness = 1;
4616 twitchdelay2 = (float)(abs(Random() % 40)) / 5;
4618 if (tailmorphstart == 1 && tailmorphend == 1) {
4620 targettailmorphness = 1;
4623 if (tailmorphstart == 2 && tailmorphend == 2) {
4625 targettailmorphness = 1;
4632 if (creature == wolftype) {
4633 twitchdelay2 -= multiplier * 1.5;
4634 if (tailmorphend != 0)
4635 if ((isRun() || animTarget == jumpupanim || animTarget == jumpdownanim || animTarget == backflipanim) && !skeleton.free) {
4637 targettailmorphness = 1;
4641 if (tailmorphend != 5)
4642 if (animTarget == flipanim || animTarget == frontflipanim || animTarget == rollanim || skeleton.free) {
4644 targettailmorphness = 1;
4648 if (twitchdelay2 <= 0) {
4649 if (((tailmorphstart == 0 && tailmorphend == 0) || (tailmorphstart == 5 && tailmorphend == 5))) {
4651 targettailmorphness = 1;
4654 if (tailmorphstart == 1 && tailmorphend == 1) {
4656 targettailmorphness = 1;
4659 if (tailmorphstart == 2 && tailmorphend == 2) {
4661 targettailmorphness = 1;
4664 if (tailmorphstart == 3 && tailmorphend == 3) {
4666 targettailmorphness = 1;
4669 if (tailmorphstart == 4 && tailmorphend == 4) {
4671 targettailmorphness = 1;
4678 unconscioustime = 0;
4680 if (dead == 1 || howactive == typesleeping) {
4681 unconscioustime += multiplier;
4682 //If unconscious, close eyes and mouth
4683 if (righthandmorphend != 0)
4684 righthandmorphness = 0;
4685 righthandmorphend = 0;
4686 targetrighthandmorphness = 1;
4688 if (lefthandmorphend != 0)
4689 lefthandmorphness = 0;
4690 lefthandmorphend = 0;
4691 targetlefthandmorphness = 1;
4693 if (headmorphend != 3 && headmorphend != 5)
4696 targetheadmorphness = 1;
4700 if (howactive > typesleeping) {
4703 if (bloodtoggle && !bled) {
4704 terrain.MakeDecal(blooddecalslow, headpoint, .8, .5, 0);
4706 if (bloodtoggle && !bled)
4707 for (l = 0; l < terrain.patchobjectnum[whichpatchx][whichpatchz]; l++) {
4708 j = terrain.patchobjects[whichpatchx][whichpatchz][l];
4709 XYZ point = DoRotation(headpoint - objects.position[j], 0, -objects.yaw[j], 0);
4713 objects.model[j].MakeDecal(blooddecalslow, &point, &size, &opacity, &yaw);
4718 if (dead == 2 || howactive > typesleeping) {
4719 //If dead, open mouth and hands
4720 if (righthandmorphend != 0)
4721 righthandmorphness = 0;
4722 righthandmorphend = 0;
4723 targetrighthandmorphness = 1;
4725 if (lefthandmorphend != 0)
4726 lefthandmorphness = 0;
4727 lefthandmorphend = 0;
4728 targetlefthandmorphness = 1;
4730 if (headmorphend != 2)
4733 targetheadmorphness = 1;
4736 if (stunned > 0 && !dead && headmorphend != 2) {
4737 if (headmorphend != 4)
4740 targetheadmorphness = 1;
4743 if (damage > damagetolerance && !dead) {
4746 unconscioustime = 0;
4748 if (creature == wolftype) {
4749 award_bonus(0, Wolfbonus);
4754 if (weaponactive != -1) {
4755 weapons[weaponids[0]].owner = -1;
4756 weapons[weaponids[0]].velocity = velocity * scale * -.3;
4757 weapons[weaponids[0]].velocity.x += .01;
4758 weapons[weaponids[0]].tipvelocity = velocity * scale;
4759 weapons[weaponids[0]].missed = 1;
4760 weapons[weaponids[0]].hitsomething = 0;
4761 weapons[weaponids[0]].freetime = 0;
4762 weapons[weaponids[0]].firstfree = 1;
4763 weapons[weaponids[0]].physics = 1;
4766 weaponids[0] = weaponids[num_weapons];
4767 if (weaponstuck == num_weapons)
4771 for (i = 0; i < numplayers; i++) {
4772 player[i].wentforweapon = 0;
4778 if ((id == 0 || distsq(&coords, &viewer) < 50) && autoslomo) {
4786 //if(dead)damage-=multiplier/4;
4788 damage -= multiplier * 13;
4789 //if(!dead&&deathbleeding<=0&&id==0)bloodloss-=multiplier*4;
4791 permanentdamage -= multiplier * 4;
4792 if (isIdle() || isCrouch()) {
4794 permanentdamage -= multiplier * 4;
4795 //if(!dead&&deathbleeding<=0&&id==0)bloodloss-=multiplier*4;
4799 if (permanentdamage < 0)
4800 permanentdamage = 0;
4801 if (superpermanentdamage < 0)
4802 superpermanentdamage = 0;
4803 if (permanentdamage < superpermanentdamage) {
4804 permanentdamage = superpermanentdamage;
4806 if (damage < permanentdamage) {
4807 damage = permanentdamage;
4809 if (dead == 1 && damage < damagetolerance) {
4813 for (i = 0; i < skeleton.num_joints; i++) {
4814 skeleton.joints[i].velocity = 0;
4817 if (permanentdamage > damagetolerance && dead != 2) {
4820 if (weaponactive != -1) {
4821 weapons[weaponids[0]].owner = -1;
4822 weapons[weaponids[0]].velocity = velocity * scale * -.3;
4823 weapons[weaponids[0]].velocity.x += .01;
4824 weapons[weaponids[0]].tipvelocity = velocity * scale;
4825 weapons[weaponids[0]].missed = 1;
4826 weapons[weaponids[0]].hitsomething = 0;
4827 weapons[weaponids[0]].freetime = 0;
4828 weapons[weaponids[0]].firstfree = 1;
4829 weapons[weaponids[0]].physics = 1;
4832 weaponids[0] = weaponids[num_weapons];
4833 if (weaponstuck == num_weapons)
4837 for (i = 0; i < numplayers; i++) {
4838 player[i].wentforweapon = 0;
4844 if (!dead && creature == wolftype) {
4845 award_bonus(0, Wolfbonus);
4848 if (unconscioustime < .1 && (bonus != spinecrusher || bonustime > 1) && (bonus != FinishedBonus || bonustime > 1) && bloodloss < damagetolerance)
4849 award_bonus(id, touchofdeath);
4850 if (id != 0 && unconscioustime > .1) {
4858 emit_sound_at(breaksound, coords);
4861 if (skeleton.free == 1) {
4863 pause_sound(whooshsound);
4866 //If knocked over, open hands and close mouth
4867 if (righthandmorphend != 0)
4868 righthandmorphness = 0;
4869 righthandmorphend = 0;
4870 targetrighthandmorphness = 1;
4872 if (lefthandmorphend != 0)
4873 lefthandmorphness = 0;
4874 lefthandmorphend = 0;
4875 targetlefthandmorphness = 1;
4877 if (headmorphend != 3 && headmorphend != 5 && headmorphstart != 3 && headmorphstart != 5) {
4878 if (headmorphend != 0)
4881 targetheadmorphness = 1;
4885 skeleton.DoGravity(&scale);
4887 damageamount = skeleton.DoConstraints(&coords, &scale) * 5;
4888 if (damage > damagetolerance - damageamount && !dead && (bonus != spinecrusher || bonustime > 1) && (bonus != style || bonustime > 1) && (bonus != cannon || bonustime > 1))
4889 award_bonus(id, deepimpact);
4890 DoDamage(damageamount / ((protectionhigh + protectionhead + protectionlow) / 3));
4894 for (j = 0; j < skeleton.num_joints; j++) {
4895 average += skeleton.joints[j].position;
4899 coords += average * scale;
4900 for (j = 0; j < skeleton.num_joints; j++) {
4901 skeleton.joints[j].position -= average;
4903 average /= multiplier;
4905 //velocity=jointVel(groin)*scale;
4907 for (i = 0; i < skeleton.num_joints; i++) {
4908 velocity += skeleton.joints[i].velocity * scale;
4910 velocity /= skeleton.num_joints;
4912 if (!isnormal(velocity.x) && velocity.x) {
4916 if (findLength(&average) < 10 && dead && skeleton.free) {
4917 skeleton.longdead += (2000 - findLength(&average)) * multiplier + multiplier;
4918 if (skeleton.longdead > 2000) {
4919 if (skeleton.longdead > 6000) {
4921 pause_sound(whooshsound);
4926 if (dead == 2 && bloodloss < damagetolerance) {
4928 headpoint = (jointPos(head) + jointPos(neck)) / 2 * scale + coords;
4930 if (bloodtoggle && !bled) {
4931 terrain.MakeDecal(blooddecal, headpoint, .2 * 1.2, .5, 0);
4933 if (bloodtoggle && !bled)
4934 for (l = 0; l < terrain.patchobjectnum[whichpatchx][whichpatchz]; l++) {
4935 j = terrain.patchobjects[whichpatchx][whichpatchz][l];
4936 XYZ point = DoRotation(headpoint - objects.position[j], 0, -objects.yaw[j], 0);
4937 float size = .2 * 1.2;
4940 objects.model[j].MakeDecal(blooddecal, &point, &size, &opacity, &yaw);
4944 if (dead == 2 && bloodloss >= damagetolerance) {
4946 headpoint = (jointPos(abdomen) + jointPos(neck)) / 2 * scale + coords;
4949 if (bloodtoggle && !bled) {
4950 terrain.MakeDecal(blooddecalslow, headpoint, .8, .5, 0);
4952 if (bloodtoggle && !bled)
4953 for (l = 0; l < terrain.patchobjectnum[whichpatchx][whichpatchz]; l++) {
4954 j = terrain.patchobjects[whichpatchx][whichpatchz][l];
4955 XYZ point = DoRotation(headpoint - objects.position[j], 0, -objects.yaw[j], 0);
4959 objects.model[j].MakeDecal(blooddecalslow, &point, &size, &opacity, &yaw);
4966 if (!dead && crouchkeydown && skeleton.freetime > .5 && id == 0 && skeleton.free) {
4967 bool canrecover = 1;
4968 XYZ startpoint, endpoint, colpoint, colviewer, coltarget;
4969 startpoint = coords;
4972 if (terrain.lineTerrain(startpoint, endpoint, &colpoint) != -1)
4974 if (velocity.y < -30)
4976 for (i = 0; i < objects.numobjects; i++) {
4977 if (objects.type[i] != treeleavestype && objects.type[i] != bushtype && objects.type[i] != firetype) {
4978 colviewer = startpoint;
4979 coltarget = endpoint;
4980 if (objects.model[i].LineCheck(&colviewer, &coltarget, &colpoint, &objects.position[i], &objects.yaw[i]) != -1)
4989 terrainnormal = jointPos(groin) - jointPos(abdomen);
4990 if (joint(groin).locked && joint(abdomen).locked) {
4991 terrainnormal = jointPos(groin) - jointPos(abdomen);
4992 middle = (jointPos(groin) + jointPos(abdomen)) / 2;
4994 if (joint(abdomen).locked && joint(neck).locked) {
4995 terrainnormal = jointPos(abdomen) - jointPos(neck);
4996 middle = (jointPos(neck) + jointPos(abdomen)) / 2;
4998 if (joint(groin).locked && joint(neck).locked) {
4999 terrainnormal = jointPos(groin) - jointPos(neck);
5000 middle = (jointPos(groin) + jointPos(neck)) / 2;
5002 Normalise(&terrainnormal);
5004 targetyaw = -asin(0 - terrainnormal.x);
5005 targetyaw *= 360 / 6.28;
5006 if (terrainnormal.z < 0)
5007 targetyaw = 180 - targetyaw;
5012 animTarget = flipanim;
5013 crouchtogglekeydown = 1;
5018 animCurrent = tempanim;
5021 //tilt2=targettilt2;
5023 //if(middle.y>0)targetoffset.y=middle.y+1;
5025 for (i = 0; i < skeleton.num_joints; i++) {
5026 tempanimation.position[i][0] = skeleton.joints[i].position;
5027 tempanimation.position[i][0] = DoRotation(tempanimation.position[i][0], 0, -yaw, 0);
5032 if (findLength(&average) < 10 && !dead && skeleton.free) {
5033 skeleton.longdead += (2000 - findLength(&average)) * multiplier + multiplier;
5034 if (skeleton.longdead > (damage + 500) * 1.5) {
5036 pause_sound(whooshsound);
5042 terrainnormal = jointPos(groin) - jointPos(abdomen);
5043 if (joint(groin).locked && joint(abdomen).locked) {
5044 terrainnormal = jointPos(groin) - jointPos(abdomen);
5045 middle = (jointPos(groin) + jointPos(abdomen)) / 2;
5047 if (joint(abdomen).locked && joint(neck).locked) {
5048 terrainnormal = jointPos(abdomen) - jointPos(neck);
5049 middle = (jointPos(neck) + jointPos(abdomen)) / 2;
5051 if (joint(groin).locked && joint(neck).locked) {
5052 terrainnormal = jointPos(groin) - jointPos(neck);
5053 middle = (jointPos(groin) + jointPos(neck)) / 2;
5055 Normalise(&terrainnormal);
5057 targetyaw = -asin(0 - terrainnormal.x);
5058 targetyaw *= 360 / 6.28;
5059 if (terrainnormal.z < 0)
5060 targetyaw = 180 - targetyaw;
5063 targettilt2 = asin(terrainnormal.y) * 180 / 3.14 * -1;
5066 if (skeleton.forward.y < 0) {
5067 animTarget = getupfrombackanim;
5071 if (skeleton.forward.y > -.3) {
5072 animTarget = getupfromfrontanim;
5080 if ((Random() % 8 == 0 && id != 0 && creature == rabbittype) || (Random() % 2 == 0 && id != 0 && creature == wolftype) || (id == 0 && crouchkeydown && (forwardkeydown || backkeydown || leftkeydown || rightkeydown))) {
5081 animTarget = rollanim;
5082 targetyaw = lookyaw;
5099 if ( !leftkeydown && !rightkeydown)
5106 if (abs(targettilt2) > 50)
5108 animCurrent = tempanim;
5111 tilt2 = targettilt2;
5113 if (middle.y > 0 && animTarget != rollanim)
5114 targetoffset.y = middle.y + 1;
5116 for (i = 0; i < skeleton.num_joints; i++) {
5117 tempanimation.position[i][0] = skeleton.joints[i].position;
5118 tempanimation.position[i][0] = DoRotation(tempanimation.position[i][0], 0, -yaw, 0);
5125 if (num_weapons > 0)
5126 if (weapons[0].getType() == staff)
5128 if (!skeleton.freefall && freefall && ((jumpkeydown && jumpkeydowntime < .2) || (hasstaff && rabbitkickragdoll)) && !dead) {
5129 if (velocity.y > -30) {
5131 tempvelocity = velocity;
5132 Normalise(&tempvelocity);
5133 targetyaw = -asin(0 - tempvelocity.x);
5134 targetyaw *= 360 / 6.28;
5136 targetyaw = 180 - targetyaw;
5140 if (dotproduct(&skeleton.forward, &tempvelocity) < 0) {
5141 animTarget = rollanim;
5144 animTarget = backhandspringanim;
5150 emit_sound_at(movewhooshsound, coords, 128.);
5152 animCurrent = animTarget;
5153 frameCurrent = frameTarget - 1;
5165 if (skeleton.freefall == 0)
5170 if (aitype != passivetype || skeleton.free == 1)
5171 if (findLengthfast(&velocity) > .1)
5172 for (i = 0; i < objects.numobjects; i++) {
5173 if (objects.type[i] == firetype)
5174 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) {
5176 if (!objects.onfire[i]) {
5177 emit_sound_at(firestartsound, objects.position[i]);
5179 objects.onfire[i] = 1;
5182 if (objects.onfire[i]) {
5187 if (objects.type[i] == bushtype)
5188 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) {
5190 if (!objects.onfire[i]) {
5191 emit_sound_at(firestartsound, objects.position[i]);
5193 objects.onfire[i] = 1;
5197 if (objects.onfire[i]) {
5201 if (objects.messedwith[i] <= 0) {
5205 emit_sound_at(bushrustle, coords, 40 * findLength(&velocity));
5208 envsound[numenvsounds] = coords;
5209 envsoundvol[numenvsounds] = 4 * findLength(&velocity);
5210 envsoundlife[numenvsounds] = .4;
5215 if (environment == grassyenvironment)
5216 howmany = findLength(&velocity) * 4;
5217 if (environment == snowyenvironment)
5218 howmany = findLength(&velocity) * 2;
5220 if (environment != desertenvironment)
5221 for (j = 0; j < howmany; j++) {
5222 tempvel.x = float(abs(Random() % 100) - 50) / 20;
5223 tempvel.y = float(abs(Random() % 100) - 50) / 20;
5224 tempvel.z = float(abs(Random() % 100) - 50) / 20;
5227 pos.x += float(abs(Random() % 100) - 50) / 200;
5228 pos.y += float(abs(Random() % 100) - 50) / 200;
5229 pos.z += float(abs(Random() % 100) - 50) / 200;
5230 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);
5231 Sprite::setLastSpriteSpecial(1);
5233 howmany = findLength(&velocity) * 4;
5235 if (environment == snowyenvironment)
5236 for (j = 0; j < howmany; j++) {
5237 tempvel.x = float(abs(Random() % 100) - 50) / 20;
5238 tempvel.y = float(abs(Random() % 100) - 50) / 20;
5239 tempvel.z = float(abs(Random() % 100) - 50) / 20;
5242 pos.x += float(abs(Random() % 100) - 50) / 200;
5243 pos.y += float(abs(Random() % 100) - 50) / 200;
5244 pos.z += float(abs(Random() % 100) - 50) / 200;
5245 Sprite::MakeSprite(splintersprite, pos, tempvel * .3 + velocity * float(abs(Random() % 100)) / 100 / 2, 1, 1, 1, .1, 1);
5246 Sprite::setLastSpriteSpecial(2);
5249 objects.rotx[i] += velocity.x * multiplier * 6;
5250 objects.roty[i] += velocity.z * multiplier * 6;
5251 objects.messedwith[i] = .5;
5254 if (objects.type[i] == treeleavestype && environment != desertenvironment) {
5255 if (objects.pitch[i] == 0)
5258 tempcoord = coords - objects.position[i];
5259 tempcoord = DoRotation(tempcoord, 0, -objects.yaw[i], 0);
5260 tempcoord = DoRotation(tempcoord, -objects.pitch[i], 0, 0);
5261 tempcoord += objects.position[i];
5263 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]) {
5264 if (objects.messedwith[i] <= 0) {
5268 emit_sound_at(bushrustle, coords, 40 * findLength(&velocity));
5271 envsound[numenvsounds] = coords;
5272 envsoundvol[numenvsounds] = 4 * findLength(&velocity);
5273 envsoundlife[numenvsounds] = .4;
5278 if (environment == grassyenvironment)
5279 howmany = findLength(&velocity) * 4;
5280 if (environment == snowyenvironment)
5281 howmany = findLength(&velocity) * 2;
5283 if (environment != desertenvironment)
5284 for (j = 0; j < howmany; j++) {
5285 tempvel.x = float(abs(Random() % 100) - 50) / 20;
5286 tempvel.y = float(abs(Random() % 100) - 50) / 20;
5287 tempvel.z = float(abs(Random() % 100) - 50) / 20;
5289 pos += velocity * .1;
5291 pos.x += float(abs(Random() % 100) - 50) / 150;
5292 pos.y += float(abs(Random() % 100) - 50) / 150;
5293 pos.z += float(abs(Random() % 100) - 50) / 150;
5294 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);
5295 Sprite::setLastSpriteSpecial(1);
5297 howmany = findLength(&velocity) * 4;
5299 if (environment == snowyenvironment)
5300 for (j = 0; j < howmany; j++) {
5301 tempvel.x = float(abs(Random() % 100) - 50) / 20;
5302 tempvel.y = float(abs(Random() % 100) - 50) / 20;
5303 tempvel.z = float(abs(Random() % 100) - 50) / 20;
5305 pos += velocity * .1;
5307 pos.x += float(abs(Random() % 100) - 50) / 150;
5308 pos.y += float(abs(Random() % 100) - 50) / 150;
5309 pos.z += float(abs(Random() % 100) - 50) / 150;
5310 Sprite::MakeSprite(splintersprite, pos, tempvel * .3 + velocity * float(abs(Random() % 100)) / 100 / 2, 1, 1, 1, .1, 1);
5311 Sprite::setLastSpriteSpecial(2);
5314 objects.messedwith[i] = .5;
5319 if (!skeleton.free) {
5322 if ((stunned > 0 || surprised > 0) && numplayers > 2 && aitype != passivetype)
5325 if (aitype != passivetype && victim->skeleton.free && !victim->dead)
5327 if (tutoriallevel == 1 && id != 0)
5329 if (play && aitype != playercontrolled) {
5330 int whichsound = -1;
5331 i = abs(Random() % 4);
5332 if (speechdelay <= 0) {
5333 if (creature == rabbittype) {
5335 whichsound = rabbitchitter;
5337 whichsound = rabbitchitter2;
5339 if (creature == wolftype) {
5341 whichsound = growlsound;
5343 whichsound = growl2sound;
5348 if (whichsound != -1) {
5349 emit_sound_at(whichsound, coords);
5353 if (animTarget == staggerbackhighanim)
5355 if (animTarget == staggerbackhardanim)
5357 staggerdelay -= multiplier;
5358 if (animTarget != crouchstabanim && animTarget != swordgroundstabanim && animTarget != staffgroundsmashanim)
5360 if (velocity.y < -30 && animTarget == jumpdownanim)
5362 if (animCurrent != getIdle() && wasIdle() && animTarget != getIdle() && isIdle()) {
5363 animTarget = getIdle();
5367 weaponmissdelay -= multiplier;
5368 highreversaldelay -= multiplier;
5369 lowreversaldelay -= multiplier;
5370 lastcollide -= multiplier;
5371 skiddelay -= multiplier;
5372 if (!isnormal(velocity.x) && velocity.x) {
5375 if (!isnormal(targettilt) && targettilt) {
5378 if (!isnormal(targettilt2) && targettilt2) {
5381 if (!isnormal(targetyaw) && targetyaw) {
5385 if (animTarget == bounceidleanim || animTarget == wolfidle || animTarget == walkanim || animTarget == drawrightanim || animTarget == crouchdrawrightanim || animTarget == drawleftanim || animTarget == fightidleanim || animTarget == fightsidestep || animTarget == hanganim || isCrouch() || animTarget == backhandspringanim) {
5386 //open hands and close mouth
5387 if (righthandmorphend != 0 && righthandmorphness == targetrighthandmorphness) {
5388 righthandmorphness = 0;
5389 righthandmorphend = 0;
5390 targetrighthandmorphness = 1;
5393 if (lefthandmorphend != 0 && lefthandmorphness == targetlefthandmorphness) {
5394 lefthandmorphness = 0;
5395 lefthandmorphend = 0;
5396 targetlefthandmorphness = 1;
5399 if (headmorphend != 3 && headmorphend != 5 && headmorphstart != 3 && headmorphstart != 5 && headmorphend != 0 && headmorphness == targetheadmorphness) {
5402 targetheadmorphness = 1;
5406 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) {
5407 //open hands and mouth
5408 if (righthandmorphend != 0 && righthandmorphness == targetrighthandmorphness) {
5409 righthandmorphness = 0;
5410 righthandmorphend = 0;
5411 targetrighthandmorphness = 1;
5414 if (lefthandmorphend != 0 && lefthandmorphness == targetlefthandmorphness) {
5415 lefthandmorphness = 0;
5416 lefthandmorphend = 0;
5417 targetlefthandmorphness = 1;
5420 if (headmorphend != 1 && headmorphness == targetheadmorphness) {
5423 targetheadmorphness = 1;
5427 if (animTarget == jumpupanim || animTarget == crouchstabanim || animTarget == swordgroundstabanim || animTarget == swordfightidlebothanim || animTarget == blockhighleftanim || animTarget == blockhighleftanim) {
5428 //close hands and mouth
5429 if (righthandmorphend != 1 && righthandmorphness == targetrighthandmorphness) {
5430 righthandmorphness = 0;
5431 righthandmorphend = 1;
5432 targetrighthandmorphness = 1;
5435 if (lefthandmorphend != 1 && lefthandmorphness == targetlefthandmorphness) {
5436 lefthandmorphness = 0;
5437 lefthandmorphend = 1;
5438 targetlefthandmorphness = 1;
5441 if (headmorphend != 0 && headmorphness == targetheadmorphness) {
5444 targetheadmorphness = 1;
5448 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) {
5449 //close hands and yell
5450 if (righthandmorphend != 1 && righthandmorphness == targetrighthandmorphness) {
5451 righthandmorphness = 0;
5452 righthandmorphend = 1;
5453 targetrighthandmorphness = 1;
5456 if (lefthandmorphend != 1 && lefthandmorphness == targetlefthandmorphness) {
5457 lefthandmorphness = 0;
5458 lefthandmorphend = 1;
5459 targetlefthandmorphness = 1;
5462 if (headmorphend != 2 && headmorphness == targetheadmorphness) {
5465 targetheadmorphness = 1;
5472 if (victim != this && !victim->dead && victim->aitype != passivetype && victim->aitype != searchtype && aitype != passivetype && aitype != searchtype && victim->id < numplayers && 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){
5880 XYZ point, newpoint, change, change2;
5881 float heightleft, heightright;
5883 // TODO: implement localToWorld and worldToLocal
5884 // but keep in mind it won't be the same math if player is ragdolled or something
5885 // - localToWorldStanding / worldToLocalStanding (or crouching or...?)
5886 // then comb through code for places where to use it
5888 // point = localToWorld(jointPos(leftfoot))
5889 point = DoRotation(p->jointPos(leftfoot), 0, p->yaw, 0) * p->scale + p->coords;
5890 // adjust height of foot
5891 heightleft = terrain.getHeight(point.x, point.z) + .04;
5892 point.y = heightleft;
5893 change = p->jointPos(leftankle) - p->jointPos(leftfoot);
5894 change2 = p->jointPos(leftknee) - p->jointPos(leftfoot);
5895 // jointPos(leftfoot) = interpolate(worldToLocal(point), jointPos(leftfoot), interp)
5896 p->jointPos(leftfoot) = DoRotation((point - p->coords) / p->scale, 0, -p->yaw, 0) * interp + p->jointPos(leftfoot) * (1 - interp);
5897 // move ankle along with foot
5898 p->jointPos(leftankle) = p->jointPos(leftfoot) + change;
5899 // average knee pos between old and new pos
5900 p->jointPos(leftknee) = (p->jointPos(leftfoot) + change2) / 2 + (p->jointPos(leftknee)) / 2;
5902 // do same as above for right leg
5903 point = DoRotation(p->jointPos(rightfoot), 0, p->yaw, 0) * p->scale + p->coords;
5904 heightright = terrain.getHeight(point.x, point.z) + .04;
5905 point.y = heightright;
5906 change = p->jointPos(rightankle) - p->jointPos(rightfoot);
5907 change2 = p->jointPos(rightknee) - p->jointPos(rightfoot);
5908 p->jointPos(rightfoot) = DoRotation((point - p->coords) / p->scale, 0, -p->yaw, 0) * interp + p->jointPos(rightfoot) * (1 - interp);
5909 p->jointPos(rightankle) = p->jointPos(rightfoot) + change;
5910 p->jointPos(rightknee) = (p->jointPos(rightfoot) + change2) / 2 + (p->jointPos(rightknee)) / 2;
5912 // fix up skeleton now that we've moved body parts?
5913 p->skeleton.DoConstraints(&p->coords, &p->scale);
5920 int Person::DrawSkeleton()
5922 int oldplayerdetail;
5923 if ((frustum.SphereInFrustum(coords.x, coords.y + scale * 3, coords.z, scale * 8) && distsq(&viewer, &coords) < viewdistance * viewdistance) || skeleton.free == 3) {
5924 if (onterrain && (isIdle() || isCrouch() || wasIdle() || wasCrouch()) && !skeleton.free) {
5934 glAlphaFunc(GL_GREATER, 0.0001);
5936 float terrainheight;
5940 if (!isnormal(tilt))
5942 if (!isnormal(tilt2))
5944 oldplayerdetail = playerdetail;
5946 if (distsq(&viewer, &coords) < viewdistance * viewdistance / 32 && detail == 2) {
5949 if (distsq(&viewer, &coords) < viewdistance * viewdistance / 128 && detail == 1) {
5952 if (distsq(&viewer, &coords) < viewdistance * viewdistance / 256 && (detail != 1 && detail != 2)) {
5957 if (playerdetail != oldplayerdetail) {
5959 normalsupdatedelay = 0;
5961 static float updatedelaychange;
5962 static float morphness;
5963 static float framemult;
5965 skeleton.FindForwards();
5966 if (howactive == typesittingwall) {
5967 skeleton.specialforward[1] = 0;
5968 skeleton.specialforward[1].z = 1;
5974 static int weaponattachmuscle;
5975 static int weaponrotatemuscle;
5976 static XYZ weaponpoint;
5977 static int start, endthing;
5978 if ((dead != 2 || skeleton.free != 2) && updatedelay <= 0) {
5979 if (!isSleeping() && !isSitting()) {
5980 // TODO: give these meaningful names
5981 const bool cond1 = (isIdle() || isCrouch() || isLanding() || isLandhard()
5982 || animTarget == drawrightanim || animTarget == drawleftanim || animTarget == crouchdrawrightanim);
5983 const bool cond2 = (wasIdle() || wasCrouch() || wasLanding() || wasLandhard()
5984 || animCurrent == drawrightanim || animCurrent == drawleftanim || animCurrent == crouchdrawrightanim);
5986 if (onterrain && (cond1 && cond2) && !skeleton.free) {
5988 if (creature == wolftype)
5992 if (onterrain && (cond1 && !cond2) && !skeleton.free) {
5993 IKHelper(this, target);
5994 if (creature == wolftype)
5995 IKHelper(this, target);
5998 if (onterrain && (!cond1 && cond2) && !skeleton.free) {
5999 IKHelper(this, 1 - target);
6000 if (creature == wolftype)
6001 IKHelper(this, 1 - target);
6005 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()))
6008 targetheadyaw = -targetyaw;
6009 targetheadpitch = 0;
6010 if (animation[animTarget].attack == 3)
6011 targetheadyaw += 180;
6013 for (i = 0; i < skeleton.drawmodel.vertexNum; i++) {
6014 skeleton.drawmodel.vertex[i] = 0;
6015 skeleton.drawmodel.vertex[i].y = 999;
6017 for (i = 0; i < skeleton.drawmodellow.vertexNum; i++) {
6018 skeleton.drawmodellow.vertex[i] = 0;
6019 skeleton.drawmodellow.vertex[i].y = 999;
6021 for (i = 0; i < skeleton.drawmodelclothes.vertexNum; i++) {
6022 skeleton.drawmodelclothes.vertex[i] = 0;
6023 skeleton.drawmodelclothes.vertex[i].y = 999;
6025 for (i = 0; i < skeleton.num_muscles; i++) {
6026 // convenience renames
6027 const int p1 = skeleton.muscles[i].parent1->label;
6028 const int p2 = skeleton.muscles[i].parent2->label;
6030 if ((skeleton.muscles[i].numvertices > 0 && playerdetail) || (skeleton.muscles[i].numverticeslow > 0 && !playerdetail)) {
6035 if (p1 == righthand || p2 == righthand) {
6036 morphness = righthandmorphness;
6037 start = righthandmorphstart;
6038 endthing = righthandmorphend;
6040 if (p1 == lefthand || p2 == lefthand) {
6041 morphness = lefthandmorphness;
6042 start = lefthandmorphstart;
6043 endthing = lefthandmorphend;
6045 if (p1 == head || p2 == head) {
6046 morphness = headmorphness;
6047 start = headmorphstart;
6048 endthing = headmorphend;
6050 if ((p1 == neck && p2 == abdomen) || (p2 == neck && p1 == abdomen)) {
6051 morphness = chestmorphness;
6052 start = chestmorphstart;
6053 endthing = chestmorphend;
6055 if ((p1 == groin && p2 == abdomen) || (p2 == groin && p1 == abdomen)) {
6056 morphness = tailmorphness;
6057 start = tailmorphstart;
6058 endthing = tailmorphend;
6061 skeleton.FindRotationMuscle(i, animTarget);
6062 mid = (skeleton.muscles[i].parent1->position + skeleton.muscles[i].parent2->position) / 2;
6063 glMatrixMode(GL_MODELVIEW);
6067 glRotatef(tilt2, 1, 0, 0);
6069 glRotatef(tilt, 0, 0, 1);
6072 glTranslatef(mid.x, mid.y, mid.z);
6074 skeleton.muscles[i].lastrotate1 = skeleton.muscles[i].rotate1;
6075 glRotatef(-skeleton.muscles[i].lastrotate1 + 90, 0, 1, 0);
6077 skeleton.muscles[i].lastrotate2 = skeleton.muscles[i].rotate2;
6078 glRotatef(-skeleton.muscles[i].lastrotate2 + 90, 0, 0, 1);
6080 skeleton.muscles[i].lastrotate3 = skeleton.muscles[i].rotate3;
6081 glRotatef(-skeleton.muscles[i].lastrotate3, 0, 1, 0);
6083 if (playerdetail || skeleton.free == 3) {
6084 for (j = 0; j < skeleton.muscles[i].numvertices; j++) {
6085 XYZ &v0 = skeleton.model[start].vertex[skeleton.muscles[i].vertices[j]];
6086 XYZ &v1 = skeleton.model[endthing].vertex[skeleton.muscles[i].vertices[j]];
6087 glMatrixMode(GL_MODELVIEW);
6089 if (p1 == abdomen || p2 == abdomen)
6090 glTranslatef((v0.x * (1-morphness) + v1.x * morphness) * proportionbody.x,
6091 (v0.y * (1-morphness) + v1.y * morphness) * proportionbody.y,
6092 (v0.z * (1-morphness) + v1.z * morphness) * proportionbody.z);
6093 if (p1 == lefthand || p1 == righthand || p1 == leftwrist || p1 == rightwrist || p1 == leftelbow || p1 == rightelbow || p2 == leftelbow || p2 == rightelbow)
6094 glTranslatef((v0.x * (1-morphness) + v1.x * morphness) * proportionarms.x,
6095 (v0.y * (1-morphness) + v1.y * morphness) * proportionarms.y,
6096 (v0.z * (1-morphness) + v1.z * morphness) * proportionarms.z);
6097 if (p1 == leftfoot || p1 == rightfoot || p1 == leftankle || p1 == rightankle || p1 == leftknee || p1 == rightknee || p2 == leftknee || p2 == rightknee)
6098 glTranslatef((v0.x * (1-morphness) + v1.x * morphness) * proportionlegs.x,
6099 (v0.y * (1-morphness) + v1.y * morphness) * proportionlegs.y,
6100 (v0.z * (1-morphness) + v1.z * morphness) * proportionlegs.z);
6101 if (p1 == head || p2 == head)
6102 glTranslatef((v0.x * (1-morphness) + v1.x * morphness) * proportionhead.x,
6103 (v0.y * (1-morphness) + v1.y * morphness) * proportionhead.y,
6104 (v0.z * (1-morphness) + v1.z * morphness) * proportionhead.z);
6105 glGetFloatv(GL_MODELVIEW_MATRIX, M);
6106 //if(!isnormal(M[12])||!isnormal(M[13])||!isnormal(M[14]))test=0;
6107 //if(!isnormal(scale))test=1;
6108 skeleton.drawmodel.vertex[skeleton.muscles[i].vertices[j]].x = M[12] * scale;
6109 skeleton.drawmodel.vertex[skeleton.muscles[i].vertices[j]].y = M[13] * scale;
6110 skeleton.drawmodel.vertex[skeleton.muscles[i].vertices[j]].z = M[14] * scale;
6115 if (!playerdetail || skeleton.free == 3) {
6116 for (j = 0; j < skeleton.muscles[i].numverticeslow; j++) {
6117 XYZ &v0 = skeleton.modellow.vertex[skeleton.muscles[i].verticeslow[j]];
6118 glMatrixMode(GL_MODELVIEW);
6120 if (p1 == abdomen || p2 == abdomen)
6121 glTranslatef(v0.x * proportionbody.x,
6122 v0.y * proportionbody.y,
6123 v0.z * proportionbody.z);
6124 if (p1 == lefthand || p1 == righthand || p1 == leftwrist || p1 == rightwrist || p1 == leftelbow || p1 == rightelbow || p2 == leftelbow || p2 == rightelbow)
6125 glTranslatef(v0.x * proportionarms.x,
6126 v0.y * proportionarms.y,
6127 v0.z * proportionarms.z);
6128 if (p1 == leftfoot || p1 == rightfoot || p1 == leftankle || p1 == rightankle || p1 == leftknee || p1 == rightknee || p2 == leftknee || p2 == rightknee)
6129 glTranslatef(v0.x * proportionlegs.x,
6130 v0.y * proportionlegs.y,
6131 v0.z * proportionlegs.z);
6132 if (p1 == head || p2 == head)
6133 glTranslatef(v0.x * proportionhead.x,
6134 v0.y * proportionhead.y,
6135 v0.z * proportionhead.z);
6137 glGetFloatv(GL_MODELVIEW_MATRIX, M);
6138 skeleton.drawmodellow.vertex[skeleton.muscles[i].verticeslow[j]].x = M[12] * scale;
6139 skeleton.drawmodellow.vertex[skeleton.muscles[i].verticeslow[j]].y = M[13] * scale;
6140 skeleton.drawmodellow.vertex[skeleton.muscles[i].verticeslow[j]].z = M[14] * scale;
6146 if (skeleton.clothes && skeleton.muscles[i].numverticesclothes > 0) {
6147 mid = (skeleton.muscles[i].parent1->position + skeleton.muscles[i].parent2->position) / 2;
6149 glMatrixMode(GL_MODELVIEW);
6153 glRotatef(tilt2, 1, 0, 0);
6155 glRotatef(tilt, 0, 0, 1);
6156 glTranslatef(mid.x, mid.y, mid.z);
6157 skeleton.muscles[i].lastrotate1 = skeleton.muscles[i].rotate1;
6158 glRotatef(-skeleton.muscles[i].lastrotate1 + 90, 0, 1, 0);
6160 skeleton.muscles[i].lastrotate2 = skeleton.muscles[i].rotate2;
6161 glRotatef(-skeleton.muscles[i].lastrotate2 + 90, 0, 0, 1);
6163 skeleton.muscles[i].lastrotate3 = skeleton.muscles[i].rotate3;
6164 glRotatef(-skeleton.muscles[i].lastrotate3, 0, 1, 0);
6166 for (j = 0; j < skeleton.muscles[i].numverticesclothes; j++) {
6167 XYZ &v0 = skeleton.modelclothes.vertex[skeleton.muscles[i].verticesclothes[j]];
6168 glMatrixMode(GL_MODELVIEW);
6170 if (p1 == abdomen || p2 == abdomen)
6171 glTranslatef(v0.x * proportionbody.x,
6172 v0.y * proportionbody.y,
6173 v0.z * proportionbody.z);
6174 if (p1 == lefthand || p1 == righthand || p1 == leftwrist || p1 == rightwrist || p1 == leftelbow || p1 == rightelbow || p2 == leftelbow || p2 == rightelbow)
6175 glTranslatef(v0.x * proportionarms.x,
6176 v0.y * proportionarms.y,
6177 v0.z * proportionarms.z);
6178 if (p1 == leftfoot || p1 == rightfoot || p1 == leftankle || p1 == rightankle || p1 == leftknee || p1 == rightknee || p2 == leftknee || p2 == rightknee)
6179 glTranslatef(v0.x * proportionlegs.x,
6180 v0.y * proportionlegs.y,
6181 v0.z * proportionlegs.z);
6182 if (p1 == head || p2 == head)
6183 glTranslatef(v0.x * proportionhead.x,
6184 v0.y * proportionhead.y,
6185 v0.z * proportionhead.z);
6186 glGetFloatv(GL_MODELVIEW_MATRIX, M);
6187 skeleton.drawmodelclothes.vertex[skeleton.muscles[i].verticesclothes[j]].x = M[12] * scale;
6188 skeleton.drawmodelclothes.vertex[skeleton.muscles[i].verticesclothes[j]].y = M[13] * scale;
6189 skeleton.drawmodelclothes.vertex[skeleton.muscles[i].verticesclothes[j]].z = M[14] * scale;
6194 updatedelay = 1 + (float)(Random() % 100) / 1000;
6196 if (skeleton.free != 2 && (skeleton.free == 1 || skeleton.free == 3 || id == 0 || (normalsupdatedelay <= 0) || animTarget == getupfromfrontanim || animTarget == getupfrombackanim || animCurrent == getupfromfrontanim || animCurrent == getupfrombackanim)) {
6197 normalsupdatedelay = 1;
6198 if (playerdetail || skeleton.free == 3)
6199 skeleton.drawmodel.CalculateNormals(0);
6200 if (!playerdetail || skeleton.free == 3)
6201 skeleton.drawmodellow.CalculateNormals(0);
6202 if (skeleton.clothes)
6203 skeleton.drawmodelclothes.CalculateNormals(0);
6205 if (playerdetail || skeleton.free == 3)
6206 skeleton.drawmodel.UpdateVertexArrayNoTexNoNorm();
6207 if (!playerdetail || skeleton.free == 3)
6208 skeleton.drawmodellow.UpdateVertexArrayNoTexNoNorm();
6209 if (skeleton.clothes) {
6210 skeleton.drawmodelclothes.UpdateVertexArrayNoTexNoNorm();
6215 updatedelaychange = -framemult * 4 * (45 - findDistance(&viewer, &coords) * 1);
6216 if (updatedelaychange > -realmultiplier * 30)
6217 updatedelaychange = -realmultiplier * 30;
6218 if (updatedelaychange > -framemult * 4)
6219 updatedelaychange = -framemult * 4;
6220 if (skeleton.free == 1)
6221 updatedelaychange *= 6;
6223 updatedelaychange *= 8;
6224 updatedelay += updatedelaychange;
6226 glMatrixMode(GL_MODELVIEW);
6229 glTranslatef(coords.x, coords.y - .02, coords.z);
6231 glTranslatef(coords.x, coords.y - .02, coords.z);
6233 glTranslatef(offset.x * scale, offset.y * scale, offset.z * scale);
6235 glRotatef(yaw, 0, 1, 0);
6238 glColor4f(.4, 1, .4, 1);
6239 glDisable(GL_LIGHTING);
6240 glDisable(GL_TEXTURE_2D);
6243 for (i = 0; i < skeleton.drawmodel.vertexNum; i++) {
6244 XYZ &v0 = skeleton.drawmodel.vertex[i];
6245 glVertex3f(v0.x, v0.y, v0.z);
6251 for (i = 0; i < skeleton.drawmodel.TriangleNum; i++) {
6252 XYZ &v0 = skeleton.drawmodel.vertex[skeleton.drawmodel.Triangles[i].vertex[0]];
6253 XYZ &v1 = skeleton.drawmodel.vertex[skeleton.drawmodel.Triangles[i].vertex[1]];
6254 XYZ &v2 = skeleton.drawmodel.vertex[skeleton.drawmodel.Triangles[i].vertex[2]];
6255 glVertex3f(v0.x, v0.y, v0.z);
6256 glVertex3f(v1.x, v1.y, v1.z);
6257 glVertex3f(v1.x, v1.y, v1.z);
6258 glVertex3f(v2.x, v2.y, v2.z);
6259 glVertex3f(v2.x, v2.y, v2.z);
6260 glVertex3f(v0.x, v0.y, v0.z);
6266 terrainlight = terrain.getLighting(coords.x, coords.z);
6267 distance = distsq(&viewer, &coords);
6268 distance = (viewdistance * viewdistance - (distance - (viewdistance * viewdistance * fadestart)) * (1 / (1 - fadestart))) / viewdistance / viewdistance;
6272 terrainheight = (coords.y - terrain.getHeight(coords.x, coords.z)) / 3 + 1;
6273 if (terrainheight < 1)
6275 if (terrainheight > 1.7)
6276 terrainheight = 1.7;
6279 glColor4f((1 - (1 - terrainlight.x) / terrainheight) - burnt, (1 - (1 - terrainlight.y) / terrainheight) - burnt, (1 - (1 - terrainlight.z) / terrainheight) - burnt, distance);
6280 glDisable(GL_BLEND);
6281 glAlphaFunc(GL_GREATER, 0.0001);
6282 glEnable(GL_TEXTURE_2D);
6284 glDisable(GL_TEXTURE_2D);
6285 glColor4f(.7, .35, 0, .5);
6287 glEnable(GL_LIGHTING);
6290 if (tutoriallevel && id != 0) {
6291 //glDisable(GL_TEXTURE_2D);
6292 glColor4f(.7, .7, .7, 0.6);
6294 glEnable(GL_LIGHTING);
6296 if (canattack && cananger)
6297 if (animation[animTarget].attack == normalattack || animation[animTarget].attack == reversed) {
6298 glDisable(GL_TEXTURE_2D);
6299 glColor4f(1, 0, 0, 0.8);
6301 glMatrixMode(GL_TEXTURE);
6303 glTranslatef(0, -smoketex, 0);
6304 glTranslatef(-smoketex, 0, 0);
6308 if ((tutoriallevel && id != 0))
6309 skeleton.drawmodel.drawdifftex(Sprite::cloudimpacttexture);
6311 skeleton.drawmodel.draw();
6314 if (!playerdetail) {
6315 if ((tutoriallevel && id != 0))
6316 skeleton.drawmodellow.drawdifftex(Sprite::cloudimpacttexture);
6318 skeleton.drawmodellow.drawdifftex(skeleton.drawmodel.textureptr);
6321 if (!(animation[animTarget].attack == normalattack || animation[animTarget].attack == reversed))
6322 if (tutoriallevel && id != 0) {
6324 glMatrixMode(GL_MODELVIEW);
6325 glEnable(GL_TEXTURE_2D);
6326 glColor4f(.7, .7, .7, 0.6);
6328 glEnable(GL_LIGHTING);
6330 if (canattack && cananger)
6331 if (animation[animTarget].attack == normalattack || animation[animTarget].attack == reversed) {
6332 glDisable(GL_TEXTURE_2D);
6333 glColor4f(1, 0, 0, 0.8);
6335 glMatrixMode(GL_TEXTURE);
6337 glTranslatef(0, -smoketex * .6, 0);
6338 glTranslatef(smoketex * .6, 0, 0);
6341 if ((tutoriallevel && id != 0))
6342 skeleton.drawmodel.drawdifftex(Sprite::cloudimpacttexture);
6344 skeleton.drawmodel.draw();
6347 if (!playerdetail) {
6348 if ((tutoriallevel && id != 0))
6349 skeleton.drawmodellow.drawdifftex(Sprite::cloudimpacttexture);
6351 skeleton.drawmodellow.drawdifftex(skeleton.drawmodel.textureptr);
6356 if (tutoriallevel && id != 0) {
6358 glMatrixMode(GL_MODELVIEW);
6359 glEnable(GL_TEXTURE_2D);
6361 if (skeleton.clothes) {
6365 skeleton.drawmodelclothes.draw();
6367 skeleton.drawmodelclothes.drawimmediate();
6373 if (num_weapons > 0) {
6374 for (k = 0; k < num_weapons; k++) {
6376 if (weaponactive == k) {
6377 if (weapons[i].getType() != staff) {
6378 for (j = 0; j < skeleton.num_muscles; j++) {
6379 if ((skeleton.muscles[j].parent1->label == righthand || skeleton.muscles[j].parent2->label == righthand) && skeleton.muscles[j].numvertices > 0) {
6380 weaponattachmuscle = j;
6383 for (j = 0; j < skeleton.num_muscles; j++) {
6384 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) {
6385 weaponrotatemuscle = j;
6388 weaponpoint = (skeleton.muscles[weaponattachmuscle].parent1->position + skeleton.muscles[weaponattachmuscle].parent2->position) / 2;
6389 if (creature == wolftype)
6390 weaponpoint = (jointPos(rightwrist) * .7 + jointPos(righthand) * .3);
6392 if (weapons[i].getType() == staff) {
6393 for (j = 0; j < skeleton.num_muscles; j++) {
6394 if ((skeleton.muscles[j].parent1->label == righthand || skeleton.muscles[j].parent2->label == righthand) && skeleton.muscles[j].numvertices > 0) {
6395 weaponattachmuscle = j;
6398 for (j = 0; j < skeleton.num_muscles; j++) {
6399 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) {
6400 weaponrotatemuscle = j;
6403 //weaponpoint=jointPos(rightwrist);
6404 weaponpoint = (skeleton.muscles[weaponattachmuscle].parent1->position + skeleton.muscles[weaponattachmuscle].parent2->position) / 2;
6405 //weaponpoint+=skeleton.specialforward[1]*.1+(jointPos(rightwrist)-jointPos(rightelbow));
6406 XYZ tempnormthing, vec1, vec2;
6407 vec1 = (jointPos(rightwrist) - jointPos(rightelbow));
6408 vec2 = (jointPos(rightwrist) - jointPos(rightshoulder));
6409 CrossProduct(&vec1, &vec2, &tempnormthing);
6410 Normalise(&tempnormthing);
6411 if (animTarget != staffhitanim && animCurrent != staffhitanim && animTarget != staffgroundsmashanim && animCurrent != staffgroundsmashanim && animTarget != staffspinhitanim && animCurrent != staffspinhitanim)
6412 weaponpoint += tempnormthing * .1 - skeleton.specialforward[1] * .3 + (jointPos(rightwrist) - jointPos(rightelbow));
6415 if (weaponactive != k && weaponstuck != k) {
6416 if (weapons[i].getType() == knife)
6417 weaponpoint = jointPos(abdomen) + (jointPos(righthip) - jointPos(lefthip)) * .1 + (jointPos(rightshoulder) - jointPos(leftshoulder)) * .35;
6418 if (weapons[i].getType() == sword)
6419 weaponpoint = jointPos(abdomen) + (jointPos(lefthip) - jointPos(righthip)) * .09 + (jointPos(leftshoulder) - jointPos(rightshoulder)) * .33;
6420 if (weapons[i].getType() == staff)
6421 weaponpoint = jointPos(abdomen) + (jointPos(lefthip) - jointPos(righthip)) * .09 + (jointPos(leftshoulder) - jointPos(rightshoulder)) * .33;
6422 for (j = 0; j < skeleton.num_muscles; j++) {
6423 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) {
6424 weaponrotatemuscle = j;
6428 if (weaponstuck == k) {
6429 if (weaponstuckwhere == 0)
6430 weaponpoint = jointPos(abdomen) * .5 + jointPos(neck) * .5 - skeleton.forward * .8;
6432 weaponpoint = jointPos(abdomen) * .5 + jointPos(neck) * .5 + skeleton.forward * .8;
6433 for (j = 0; j < skeleton.num_muscles; j++) {
6434 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) {
6435 weaponrotatemuscle = j;
6439 if (skeleton.free) {
6440 weapons[i].position = weaponpoint * scale + coords;
6441 weapons[i].bigrotation = 0;
6442 weapons[i].bigtilt = 0;
6443 weapons[i].bigtilt2 = 0;
6445 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;
6446 weapons[i].bigrotation = yaw;
6447 weapons[i].bigtilt = tilt;
6448 weapons[i].bigtilt2 = tilt2;
6450 weapons[i].rotation1 = skeleton.muscles[weaponrotatemuscle].lastrotate1;
6451 weapons[i].rotation2 = skeleton.muscles[weaponrotatemuscle].lastrotate2;
6452 weapons[i].rotation3 = skeleton.muscles[weaponrotatemuscle].lastrotate3;
6453 if (weaponactive == k) {
6454 if (weapons[i].getType() == knife) {
6455 weapons[i].smallrotation = 180;
6456 weapons[i].smallrotation2 = 0;
6457 if (isCrouch() || wasCrouch()) {
6458 weapons[i].smallrotation2 = 20;
6460 if (animTarget == hurtidleanim) {
6461 weapons[i].smallrotation2 = 50;
6463 if ((animCurrent == crouchstabanim && animTarget == crouchstabanim) || (animCurrent == backhandspringanim && animTarget == backhandspringanim)) {
6464 XYZ temppoint1, temppoint2, tempforward;
6467 temppoint1 = jointPos(righthand);
6468 temppoint2 = animation[animCurrent].weapontarget[frameCurrent] * (1 - target) + animation[animTarget].weapontarget[frameTarget] * (target);
6469 distance = findDistance(&temppoint1, &temppoint2);
6470 weapons[i].rotation2 = asin((temppoint1.y - temppoint2.y) / distance);
6471 weapons[i].rotation2 *= 360 / 6.28;
6474 weapons[i].rotation1 = acos((temppoint1.z - temppoint2.z) / findDistance(&temppoint1, &temppoint2));
6475 weapons[i].rotation1 *= 360 / 6.28;
6476 weapons[i].rotation3 = 0;
6477 weapons[i].smallrotation = -90;
6478 weapons[i].smallrotation2 = 0;
6479 if (temppoint1.x > temppoint2.x)
6480 weapons[i].rotation1 = 360 - weapons[i].rotation1;
6482 if ((animCurrent == knifeslashreversalanim && animTarget == knifeslashreversalanim) || (animCurrent == knifeslashreversedanim && animTarget == knifeslashreversedanim)) {
6483 XYZ temppoint1, temppoint2, tempforward;
6486 temppoint1 = jointPos(righthand);
6487 temppoint2 = animation[animCurrent].weapontarget[frameCurrent] * (1 - target) + animation[animTarget].weapontarget[frameTarget] * (target);
6488 distance = findDistance(&temppoint1, &temppoint2);
6489 weapons[i].rotation2 = asin((temppoint1.y - temppoint2.y) / distance);
6490 weapons[i].rotation2 *= 360 / 6.28;
6493 weapons[i].rotation1 = acos((temppoint1.z - temppoint2.z) / findDistance(&temppoint1, &temppoint2));
6494 weapons[i].rotation1 *= 360 / 6.28;
6495 weapons[i].rotation3 = 0;
6496 weapons[i].smallrotation = 90;
6497 weapons[i].smallrotation2 = 0;
6498 if (temppoint1.x > temppoint2.x)
6499 weapons[i].rotation1 = 360 - weapons[i].rotation1;
6501 if (animTarget == knifethrowanim) {
6502 weapons[i].smallrotation = 90;
6503 //weapons[i].smallrotation2=-90;
6504 weapons[i].smallrotation2 = 0;
6505 weapons[i].rotation1 = 0;
6506 weapons[i].rotation2 = 0;
6507 weapons[i].rotation3 = 0;
6509 if (animTarget == knifesneakattackanim && frameTarget < 5) {
6510 weapons[i].smallrotation = -90;
6511 weapons[i].rotation1 = 0;
6512 weapons[i].rotation2 = 0;
6513 weapons[i].rotation3 = 0;
6516 if (weapons[i].getType() == sword) {
6517 weapons[i].smallrotation = 0;
6518 weapons[i].smallrotation2 = 0;
6519 if (animTarget == knifethrowanim) {
6520 weapons[i].smallrotation = -90;
6521 weapons[i].smallrotation2 = 0;
6522 weapons[i].rotation1 = 0;
6523 weapons[i].rotation2 = 0;
6524 weapons[i].rotation3 = 0;
6526 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)) {
6527 XYZ temppoint1, temppoint2, tempforward;
6530 temppoint1 = animation[animCurrent].position[skeleton.jointlabels[righthand]][frameCurrent] * (1 - target) + animation[animTarget].position[skeleton.jointlabels[righthand]][frameTarget] * (target); //jointPos(righthand);
6531 temppoint2 = animation[animCurrent].weapontarget[frameCurrent] * (1 - target) + animation[animTarget].weapontarget[frameTarget] * (target);
6532 distance = findDistance(&temppoint1, &temppoint2);
6533 weapons[i].rotation2 = asin((temppoint1.y - temppoint2.y) / distance);
6534 weapons[i].rotation2 *= 360 / 6.28;
6537 weapons[i].rotation1 = acos((temppoint1.z - temppoint2.z) / findDistance(&temppoint1, &temppoint2));
6538 weapons[i].rotation1 *= 360 / 6.28;
6539 weapons[i].rotation3 = 0;
6540 weapons[i].smallrotation = 90;
6541 weapons[i].smallrotation2 = 0;
6542 if (temppoint1.x > temppoint2.x)
6543 weapons[i].rotation1 = 360 - weapons[i].rotation1;
6546 if (weapons[i].getType() == staff) {
6547 weapons[i].smallrotation = 100;
6548 weapons[i].smallrotation2 = 0;
6549 if ((animTarget == staffhitanim && animCurrent == staffhitanim) || (animTarget == staffhitreversedanim && animCurrent == staffhitreversedanim) || (animTarget == staffspinhitreversedanim && animCurrent == staffspinhitreversedanim) || (animTarget == staffgroundsmashanim && animCurrent == staffgroundsmashanim) || (animTarget == staffspinhitanim && animCurrent == staffspinhitanim)) {
6550 XYZ temppoint1, temppoint2, tempforward;
6553 temppoint1 = animation[animCurrent].position[skeleton.jointlabels[righthand]][frameCurrent] * (1 - target) + animation[animTarget].position[skeleton.jointlabels[righthand]][frameTarget] * (target); //jointPos(righthand);
6554 temppoint2 = animation[animCurrent].weapontarget[frameCurrent] * (1 - target) + animation[animTarget].weapontarget[frameTarget] * (target);
6555 distance = findDistance(&temppoint1, &temppoint2);
6556 weapons[i].rotation2 = asin((temppoint1.y - temppoint2.y) / distance);
6557 weapons[i].rotation2 *= 360 / 6.28;
6560 weapons[i].rotation1 = acos((temppoint1.z - temppoint2.z) / findDistance(&temppoint1, &temppoint2));
6561 weapons[i].rotation1 *= 360 / 6.28;
6562 weapons[i].rotation3 = 0;
6563 weapons[i].smallrotation = 90;
6564 weapons[i].smallrotation2 = 0;
6565 if (temppoint1.x > temppoint2.x)
6566 weapons[i].rotation1 = 360 - weapons[i].rotation1;
6570 if (weaponactive != k && weaponstuck != k) {
6571 if (weapons[i].getType() == knife) {
6572 weapons[i].smallrotation = -70;
6573 weapons[i].smallrotation2 = 10;
6575 if (weapons[i].getType() == sword) {
6576 weapons[i].smallrotation = -100;
6577 weapons[i].smallrotation2 = -8;
6579 if (weapons[i].getType() == staff) {
6580 weapons[i].smallrotation = -100;
6581 weapons[i].smallrotation2 = -8;
6584 if (weaponstuck == k) {
6585 if (weaponstuckwhere == 0)
6586 weapons[i].smallrotation = 180;
6588 weapons[i].smallrotation = 0;
6589 weapons[i].smallrotation2 = 10;
6598 if (animation[animTarget].attack || isRun() || animTarget == staggerbackhardanim || isFlip() || animTarget == climbanim || animTarget == sneakanim || animTarget == rollanim || animTarget == walkanim || animTarget == backhandspringanim || isFlip() || isWallJump())
6600 if (animCurrent != animTarget)
6602 //if(id==0)calcrot=1;
6603 if (skeleton.free == 2)
6612 int Person::SphereCheck(XYZ *p1, float radius, XYZ *p, XYZ *move, float *rotate, Model *model)
6615 static float distance;
6616 static float olddistance;
6617 static int intersecting;
6618 static int firstintersecting;
6621 static XYZ start, end;
6622 static float slopethreshold = -.4;
6624 firstintersecting = -1;
6628 if (distsq(p1, &model->boundingspherecenter) > radius * radius + model->boundingsphereradius * model->boundingsphereradius)
6631 *p1 = DoRotation(*p1, 0, -*rotate, 0);
6632 for (i = 0; i < 4; i++) {
6633 for (j = 0; j < model->TriangleNum; j++) {
6634 if (model->facenormals[j].y <= slopethreshold) {
6636 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)));
6637 if (distance < radius) {
6638 point = *p1 - model->facenormals[j] * distance;
6639 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]]))
6642 intersecting = sphere_line_intersection(&model->vertex[model->Triangles[j].vertex[0]],
6643 &model->vertex[model->Triangles[j].vertex[1]],
6646 intersecting = sphere_line_intersection(&model->vertex[model->Triangles[j].vertex[1]],
6647 &model->vertex[model->Triangles[j].vertex[2]],
6650 intersecting = sphere_line_intersection(&model->vertex[model->Triangles[j].vertex[0]],
6651 &model->vertex[model->Triangles[j].vertex[2]],
6654 if (dotproduct(&model->facenormals[j], &end) > 0 && intersecting) {
6658 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)) {
6659 p1->y = point.y + radius;
6660 if ((animTarget == jumpdownanim || isFlip())) {
6661 if (isFlip() && (frameTarget < 5 || animation[animTarget].label[frameTarget] == 7 || animation[animTarget].label[frameTarget] == 4))
6664 if (animTarget == jumpupanim) {
6666 animTarget = getIdle();
6673 pause_sound(whooshsound);
6674 OPENAL_SetVolume(channels[whooshsound], 0);
6677 if ((animTarget == jumpdownanim || isFlip()) && !wasLanding() && !wasLandhard()) {
6680 animTarget = getLanding();
6681 emit_sound_at(landsound, coords, 128.);
6684 envsound[numenvsounds] = coords;
6685 envsoundvol[numenvsounds] = 16;
6686 envsoundlife[numenvsounds] = .4;
6694 if ((distance < olddistance || firstintersecting == -1) && intersecting) {
6695 olddistance = distance;
6696 firstintersecting = j;
6701 for (j = 0; j < model->TriangleNum; j++) {
6702 if (model->facenormals[j].y > slopethreshold) {
6705 start.y -= radius / 4;
6706 XYZ &v0 = model->vertex[model->Triangles[j].vertex[0]];
6707 XYZ &v1 = model->vertex[model->Triangles[j].vertex[1]];
6708 XYZ &v2 = model->vertex[model->Triangles[j].vertex[2]];
6709 distance = abs((model->facenormals[j].x * start.x)
6710 + (model->facenormals[j].y * start.y)
6711 + (model->facenormals[j].z * start.z)
6712 - ((model->facenormals[j].x * v0.x)
6713 + (model->facenormals[j].y * v0.y)
6714 + (model->facenormals[j].z * v0.z)));
6715 if (distance < radius * .5) {
6716 point = start - model->facenormals[j] * distance;
6717 if (PointInTriangle( &point, model->facenormals[j], &v0, &v1, &v2))
6720 intersecting = sphere_line_intersection(v0.x,v0.y,v0.z, v1.x,v1.y,v1.z, p1->x, p1->y, p1->z, radius / 2);
6722 intersecting = sphere_line_intersection(v1.x,v1.y,v1.z, v2.x,v2.y,v2.z, p1->x, p1->y, p1->z, radius / 2);
6724 intersecting = sphere_line_intersection(v0.x,v0.y,v0.z, v2.x,v2.y,v2.z, p1->x, p1->y, p1->z, radius / 2);
6726 if (dotproduct(&model->facenormals[j], &end) > 0 && intersecting) {
6727 if ((animTarget == jumpdownanim || animTarget == jumpupanim || isFlip())) {
6729 velocity -= DoRotation(model->facenormals[j], 0, *rotate, 0) * findLength(&velocity) * abs(normaldotproduct(velocity, DoRotation(model->facenormals[j], 0, *rotate, 0))); //(distance-radius*.5)/multiplier;
6730 if (findLengthfast(&start) < findLengthfast(&velocity))
6733 *p1 += model->facenormals[j] * (distance - radius * .5);
6736 if ((distance < olddistance || firstintersecting == -1) && intersecting) {
6737 olddistance = distance;
6738 firstintersecting = j;
6745 *p = DoRotation(*p, 0, *rotate, 0);
6748 *p1 = DoRotation(*p1, 0, *rotate, 0);
6750 return firstintersecting;