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)
92 return skeleton.joints[skeleton.jointlabels[bodypart]];
94 XYZ& Person::jointPos(int bodypart)
96 return joint(bodypart).position;
98 XYZ& Person::jointVel(int bodypart)
100 return joint(bodypart).velocity;
106 * GameTick/doPlayerCollisions
108 void Person::CheckKick()
111 && (animTarget == rabbitkickanim
115 && animCurrent == rabbitkickanim)
116 && distsq(&coords, &victim->coords) < 1.2
117 && !victim->skeleton.free))
120 if (animation[victim->animTarget].height != lowheight) {
121 float damagemult = (creature == wolftype ? 2.5 : 1.) * power * power;
122 XYZ relative = velocity;
124 Normalise(&relative);
128 if (tutoriallevel != 1)
129 emit_sound_at(heavyimpactsound, victim->coords);
131 for (int i = 0; i < victim->skeleton.num_joints; i++) {
132 victim->skeleton.joints[i].velocity += relative * 120 * damagemult;
135 victim->DoDamage(100 * damagemult / victim->protectionhigh);
141 animTarget = backflipanim;
143 velocity = facing * -10;
147 resume_stream(whooshsound);
149 award_bonus(id, cannon);
150 } else if (victim->isCrouch()) {
151 animTarget = rabbitkickreversedanim;
152 animCurrent = rabbitkickreversedanim;
153 victim->animCurrent = rabbitkickreversalanim;
154 victim->animTarget = rabbitkickreversalanim;
160 victim->oldcoords = victim->coords;
161 coords = victim->coords;
162 victim->targetyaw = targetyaw;
163 victim->victim = this;
170 * GameTick/doPlayerCollisions - spread fire between players
171 * GameTick/doDebugKeys - press f to ignite
172 * Person::DoStuff - spread fire from lit campfires and bushes
174 void Person::CatchFire()
176 XYZ flatfacing, flatvelocity;
178 for (int i = 0; i < 10; i++) {
179 howmany = abs(Random() % (skeleton.num_joints));
181 flatvelocity = velocity;
183 flatvelocity = skeleton.joints[howmany].velocity;
185 flatfacing = DoRotation(DoRotation(DoRotation(skeleton.joints[howmany].position, 0, 0, tilt), tilt2, 0, 0), 0, yaw, 0) * scale + coords;
187 flatfacing = skeleton.joints[howmany].position * scale + coords;
188 Sprite::MakeSprite(flamesprite, flatfacing, flatvelocity, 1, 1, 1, 2, 1);
193 emit_sound_at(firestartsound, coords);
195 emit_stream_at(stream_firesound, coords);
203 * idle animation for this creature (depending on status)
205 int Person::getIdle()
207 if (indialogue != -1 && howactive == typeactive && creature == rabbittype)
209 if (hasvictim && victim != this/*||(id==0&&attackkeydown)*/)
210 if (/*(id==0&&attackkeydown)||*/(!victim->dead && victim->aitype != passivetype && victim->aitype != searchtype && aitype != passivetype && aitype != searchtype && victim->id < numplayers)) {
211 if ((aitype == playercontrolled && stunned <= 0 && weaponactive == -1) || pause) {
212 if (creature == rabbittype)
213 return fightidleanim;
214 if (creature == wolftype)
217 if (aitype == playercontrolled && stunned <= 0 && weaponactive != -1) {
218 if (weapons[weaponids[weaponactive]].getType() == knife)
219 return knifefightidleanim;
220 if (weapons[weaponids[weaponactive]].getType() == sword && victim->weaponactive != -1)
221 return swordfightidlebothanim;
222 if (weapons[weaponids[weaponactive]].getType() == sword)
223 return swordfightidleanim;
224 if (weapons[weaponids[weaponactive]].getType() == staff)
225 return swordfightidleanim;
227 if (aitype != playercontrolled && stunned <= 0 && creature != wolftype && !pause)
228 return fightsidestep;
230 if ((damage > permanentdamage || damage > damagetolerance * .8 || deathbleeding > 0) && creature != wolftype)
232 if (howactive == typesitting) return sitanim;
233 if (howactive == typesittingwall) return sitwallanim;
234 if (howactive == typesleeping) return sleepanim;
235 if (howactive == typedead1) return dead1anim;
236 if (howactive == typedead2) return dead2anim;
237 if (howactive == typedead3) return dead3anim;
238 if (howactive == typedead4) return dead4anim;
239 if (creature == rabbittype) return bounceidleanim;
240 if (creature == wolftype) return wolfidle;
245 * crouch animation for this creature
247 int Person::getCrouch()
249 if (creature == rabbittype)
251 if (creature == wolftype)
252 return wolfcrouchanim;
257 * running animation for this creature (can be upright or all fours)
261 if (creature == rabbittype && (!superruntoggle || weaponactive != -1))
263 if (creature == wolftype && (!superruntoggle))
266 if (creature == rabbittype && (superruntoggle && weaponactive == -1))
267 return rabbitrunninganim;
268 if (creature == wolftype && (superruntoggle))
269 return wolfrunninganim;
275 int Person::getStop()
277 if (creature == rabbittype)
279 if (creature == wolftype)
286 int Person::getLanding()
288 if (creature == rabbittype)
290 if (creature == wolftype)
297 int Person::getLandhard()
299 if (creature == rabbittype)
301 if (creature == wolftype)
302 return wolflandhardanim;
309 * Person::DoAnimations
312 SolidHitBonus(int playerid)
314 if (bonustime < 1.5 && bonus >= solidhit && bonus <= megacombo)
315 award_bonus(playerid, bonus == megacombo ? bonus : bonus + 1);
317 award_bonus(playerid, solidhit);
321 * spawns blood effects
323 void Person::DoBlood(float howmuch, int which)
325 // FIXME: should abstract out inputs
326 static int bleedxint, bleedyint;
328 //if(howmuch&&id==0)blooddimamount=1;
329 if (bloodtoggle && tutoriallevel != 1) {
330 if (bleeding <= 0 && spurt) {
332 for (int i = 0; i < 3; i++) {
333 // emit blood particles
335 if (!skeleton.free) {
337 bloodvel = DoRotation(bloodvel, ((float)(Random() % 100)) / 4, yaw + ((float)(Random() % 100)) / 4, 0) * scale;
340 bloodvel -= DoRotation(skeleton.forward * 10 * scale, ((float)(Random() % 100)) / 4, ((float)(Random() % 100)) / 4, 0);
343 bloodvel += DoRotation(jointVel(head), ((float)(Random() % 100)) / 4, yaw + ((float)(Random() % 100)) / 4, 0) * scale;
345 bloodvel += DoRotation(velocity, ((float)(Random() % 100)) / 4, ((float)(Random() % 100)) / 4, 0) * scale;
347 Sprite::MakeSprite(bloodsprite, jointPos(head) * scale + coords, bloodvel, 1, 1, 1, .05, 1);
348 Sprite::MakeSprite(bloodflamesprite, jointPos(head) * scale + coords, bloodvel, 1, 1, 1, .3, 1);
350 if (!skeleton.free) {
351 Sprite::MakeSprite(bloodsprite, DoRotation((jointPos(head) + jointPos(neck)) / 2, 0, yaw, 0)*scale + coords, bloodvel, 1, 1, 1, .05, 1);
352 Sprite::MakeSprite(bloodflamesprite, DoRotation((jointPos(head) + jointPos(neck)) / 2, 0, yaw, 0)*scale + coords, bloodvel, 1, 1, 1, .3, 1);
355 if (Random() % 2 == 0) // 50% chance
356 for (int i = 0; i < 3; i++) {
357 if (Random() % 2 != 0) {
358 // emit teeth particles
361 bloodvel -= DoRotation(skeleton.forward * 10 * scale, ((float)(Random() % 100)) / 4, ((float)(Random() % 100)) / 4, 0);
362 bloodvel += DoRotation(jointVel(head), ((float)(Random() % 100)) / 4, yaw + ((float)(Random() % 100)) / 4, 0) * scale;
365 bloodvel = DoRotation(bloodvel, ((float)(Random() % 100)) / 4, yaw + ((float)(Random() % 100)) / 4, 0) * scale;
366 bloodvel += DoRotation(velocity, ((float)(Random() % 100)) / 4, ((float)(Random() % 100)) / 4, 0) * scale;
370 Sprite::MakeSprite(splintersprite, jointPos(head) * scale + coords, bloodvel, 1, 1, 1, .05, 1);
372 Sprite::MakeSprite(splintersprite, DoRotation((jointPos(head) + jointPos(neck)) / 2, 0, yaw, 0)*scale + coords, bloodvel, 1, 1, 1, .05, 1);
374 Sprite::setLastSpriteSpecial(3); // sets it to teeth
379 // FIXME: manipulating attributes
380 bleeding = howmuch + (float)abs(Random() % 100) / 200 - .25;
383 if (creature == rabbittype)
384 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) {
385 bleedxint = abs(Random() % 512);
386 bleedyint = abs(Random() % 512);
388 if (creature == wolftype)
389 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) {
390 bleedxint = abs(Random() % 512);
391 bleedyint = abs(Random() % 512);
395 bleedy /= realtexdetail;
396 bleedx /= realtexdetail;
397 direction = abs(Random() % 2) * 2 - 1;
406 * spawns big blood effects and ???
407 * modifies character's skin texture
409 void Person::DoBloodBig(float howmuch, int which)
411 static int bleedxint, bleedyint, i, j;
413 if (howmuch && id == 0)
416 if (tutoriallevel != 1 || id == 0)
417 if (aitype != playercontrolled && howmuch > 0) {
421 // FIXME: seems to be spawning sounds by manipulating attributes... MESSY!
422 if (creature == wolftype) {
423 int i = abs(Random() % 2);
425 whichsound = snarlsound;
427 whichsound = snarl2sound;
428 envsound[numenvsounds] = coords;
429 envsoundvol[numenvsounds] = 16;
430 envsoundlife[numenvsounds] = .4;
433 if (creature == rabbittype) {
434 int i = abs(Random() % 2);
436 whichsound = rabbitpainsound;
437 if (i == 1 && howmuch >= 2)
438 whichsound = rabbitpain1sound;
439 envsound[numenvsounds] = coords;
440 envsoundvol[numenvsounds] = 16;
441 envsoundlife[numenvsounds] = .4;
443 //if(i==2)whichsound=rabbitpain2sound;
446 if (whichsound != -1)
447 emit_sound_at(whichsound, coords);
450 if (id == 0 && howmuch > 0) {
451 // FIXME: manipulating attributes
459 if (bloodtoggle && decals && tutoriallevel != 1) {
460 if (bleeding <= 0 && spurt) {
462 for (int i = 0; i < 3; i++) {
463 // emit blood particles
464 // FIXME: copypaste from above
466 if (!skeleton.free) {
468 bloodvel = DoRotation(bloodvel, ((float)(Random() % 100)) / 4, yaw + ((float)(Random() % 100)) / 4, 0) * scale;
471 bloodvel -= DoRotation(skeleton.forward * 10 * scale, ((float)(Random() % 100)) / 4, ((float)(Random() % 100)) / 4, 0);
474 bloodvel += DoRotation(jointVel(head), ((float)(Random() % 100)) / 4, yaw + ((float)(Random() % 100)) / 4, 0) * scale;
476 bloodvel += DoRotation(velocity, ((float)(Random() % 100)) / 4, ((float)(Random() % 100)) / 4, 0) * scale;
478 Sprite::MakeSprite(bloodsprite, jointPos(head) * scale + coords, bloodvel, 1, 1, 1, .05, 1);
479 Sprite::MakeSprite(bloodflamesprite, jointPos(head) * scale + coords, bloodvel, 1, 1, 1, .3, 1);
481 if (!skeleton.free) {
482 Sprite::MakeSprite(bloodsprite, DoRotation((jointPos(head) + jointPos(neck)) / 2, 0, yaw, 0)*scale + coords, bloodvel, 1, 1, 1, .05, 1);
483 Sprite::MakeSprite(bloodflamesprite, DoRotation((jointPos(head) + jointPos(neck)) / 2, 0, yaw, 0)*scale + coords, bloodvel, 1, 1, 1, .3, 1);
488 // weird texture manipulation code follows.
489 // looks like this is painting blood onto the character's skin texture
490 // FIXME: surely there's a better way
492 int offsetx = 0, offsety = 0;
494 offsety = Random() % 40;
495 offsetx = abs(Random() % 60);
497 if (which == 190 || which == 185) {
498 offsety = Random() % 40;
499 offsetx = abs(Random() % 100) - 20;
502 offsety = Random() % 10;
503 offsetx = Random() % 10;
506 offsety = Random() % 20;
507 offsetx = Random() % 20;
509 if (which == 220 || which == 215) {
519 if (creature == rabbittype)
520 for (i = 0; i < 512; i++) {
521 for (j = 0; j < 512; j++) {
522 if (bloodText[i * 512 * 3 + j * 3 + 0] <= which + 4 && bloodText[i * 512 * 3 + j * 3 + 0] >= which - 4) {
523 if (i < startx) startx = i;
524 if (j < starty) starty = j;
525 if (i > endx) endx = i;
526 if (j > endy) endy = j;
530 if (creature == wolftype)
531 for (i = 0; i < 512; i++) {
532 for (j = 0; j < 512; j++) {
533 if (wolfbloodText[i * 512 * 3 + j * 3 + 0] <= which + 4 && wolfbloodText[i * 512 * 3 + j * 3 + 0] >= which - 4) {
534 if (i < startx) startx = i;
535 if (j < starty) starty = j;
536 if (i > endx) endx = i;
537 if (j > endy) endy = j;
547 if (startx < 0) startx = 0;
548 if (starty < 0) starty = 0;
549 if (endx > 512 - 1) endx = 512 - 1;
550 if (endy > 512 - 1) endy = 512 - 1;
551 if (endx < startx) endx = startx;
552 if (endy < starty) endy = starty;
554 startx /= realtexdetail;
555 starty /= realtexdetail;
556 endx /= realtexdetail;
557 endy /= realtexdetail;
559 int texdetailint = realtexdetail;
561 if (creature == rabbittype)
562 for (i = startx; i < endx; i++) {
563 for (j = starty; j < endy; j++) {
564 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) {
565 color = Random() % 85 + 170;
566 where = i * skeleton.skinsize * 3 + j * 3;
567 if (skeleton.skinText[where + 0] > color / 2)
568 skeleton.skinText[where + 0] = color / 2;
569 skeleton.skinText[where + 1] = 0;
570 skeleton.skinText[where + 2] = 0;
574 if (creature == wolftype)
575 for (i = startx; i < endx; i++) {
576 for (j = starty; j < endy; j++) {
577 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) {
578 color = Random() % 85 + 170;
579 where = i * skeleton.skinsize * 3 + j * 3;
580 if (skeleton.skinText[where + 0] > color / 2)
581 skeleton.skinText[where + 0] = color / 2;
582 skeleton.skinText[where + 1] = 0;
583 skeleton.skinText[where + 2] = 0;
587 skeleton.drawmodel.textureptr.bind();
592 if (creature == rabbittype)
593 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) {
594 bleedxint = abs(Random() % 512);
595 bleedyint = abs(Random() % 512);
597 if (creature == wolftype)
598 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) {
599 bleedxint = abs(Random() % 512);
600 bleedyint = abs(Random() % 512);
602 bleedy = bleedxint + offsetx;
603 bleedx = bleedyint + offsety;
604 bleedy /= realtexdetail;
605 bleedx /= realtexdetail;
610 if (bleedx > skeleton.skinsize - 1)
611 bleedx = skeleton.skinsize - 1;
612 if (bleedy > skeleton.skinsize - 1)
613 bleedy = skeleton.skinsize - 1;
614 direction = abs(Random() % 2) * 2 - 1;
617 bleeding = howmuch + (float)abs(Random() % 100) / 200 - .25;
618 deathbleeding += bleeding;
619 bloodloss += bleeding * 3;
621 if (tutoriallevel != 1 && aitype != playercontrolled && bloodloss > damagetolerance * 2 / 3 && bloodloss < damagetolerance && creature == rabbittype) {
622 if (abs(Random() % 2) == 0) {
623 aitype = gethelptype;
626 aitype = attacktypecutoff;
634 * similar to DoBloodBig
636 bool Person::DoBloodBigWhere(float howmuch, int which, XYZ where)
640 static XYZ startpoint, endpoint, colpoint, movepoint;
641 static float rotationpoint;
643 static XYZ p1, p2, p3, p0;
647 float coordsx, coordsy;
650 if (bloodtoggle && decals && tutoriallevel != 1) {
653 where = DoRotation(where, 0, -yaw, 0);
661 // ray testing for a tri in the character model
662 whichtri = skeleton.drawmodel.LineCheck(&startpoint, &endpoint, &colpoint, &movepoint, &rotationpoint);
663 if (whichtri != -1) {
664 // low level geometry math
666 p1 = skeleton.drawmodel.vertex[skeleton.drawmodel.Triangles[whichtri].vertex[0]];
667 p2 = skeleton.drawmodel.vertex[skeleton.drawmodel.Triangles[whichtri].vertex[1]];
668 p3 = skeleton.drawmodel.vertex[skeleton.drawmodel.Triangles[whichtri].vertex[2]];
670 CrossProduct(p2-p1,p3-p1,&N);
671 CrossProduct(p0-p1,p3-p1,&temp);
672 s = dotproduct(&temp,&N)/findLength(&N);
673 CrossProduct(p2-p1,p1-p0,&temp);
674 t = dotproduct(&temp,&N)/findLength(&N);
677 bary.x = distsq(&p0, &p1);
678 bary.y = distsq(&p0, &p2);
679 bary.z = distsq(&p0, &p3);
681 total = bary.x + bary.y + bary.z;
690 total = bary.x + bary.y + bary.z;
696 gxx.x = skeleton.drawmodel.Triangles[whichtri].gx[0];
697 gxx.y = skeleton.drawmodel.Triangles[whichtri].gx[1];
698 gxx.z = skeleton.drawmodel.Triangles[whichtri].gx[2];
699 gyy.x = skeleton.drawmodel.Triangles[whichtri].gy[0];
700 gyy.y = skeleton.drawmodel.Triangles[whichtri].gy[1];
701 gyy.z = skeleton.drawmodel.Triangles[whichtri].gy[2];
702 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;
703 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;
705 //coordsx=skeleton.drawmodel.Triangles[whichtri].gx[1];
706 //coordsy=skeleton.drawmodel.Triangles[whichtri].gy[1];
708 if (bleeding <= 0 && spurt) {
710 for (int i = 0; i < 3; i++) {
711 // emit blood particles
712 // FIXME: more copypaste code
714 if (!skeleton.free) {
716 bloodvel = DoRotation(bloodvel, ((float)(Random() % 100)) / 4, yaw + ((float)(Random() % 100)) / 4, 0) * scale;
719 bloodvel -= DoRotation(skeleton.forward * 10 * scale, ((float)(Random() % 100)) / 4, ((float)(Random() % 100)) / 4, 0);
722 bloodvel += DoRotation(jointVel(head), ((float)(Random() % 100)) / 4, yaw + ((float)(Random() % 100)) / 4, 0) * scale;
724 bloodvel += DoRotation(velocity, ((float)(Random() % 100)) / 4, ((float)(Random() % 100)) / 4, 0) * scale;
726 Sprite::MakeSprite(bloodsprite, jointPos(head) * scale + coords, bloodvel, 1, 1, 1, .05, 1);
727 Sprite::MakeSprite(bloodflamesprite, jointPos(head) * scale + coords, bloodvel, 1, 1, 1, .3, 1);
729 if (!skeleton.free) {
730 Sprite::MakeSprite(bloodsprite, DoRotation((jointPos(head) + jointPos(neck)) / 2, 0, yaw, 0)*scale + coords, bloodvel, 1, 1, 1, .05, 1);
731 Sprite::MakeSprite(bloodflamesprite, DoRotation((jointPos(head) + jointPos(neck)) / 2, 0, yaw, 0)*scale + coords, bloodvel, 1, 1, 1, .3, 1);
736 // texture manipulation follows
738 int offsetx = 0, offsety = 0;
741 offsetx=abs(Random()%120);
743 if(which==220||which==215){
745 offsetx=abs(Random()%80);
748 offsetx = (1 + coordsy) * 512 - 291;
749 offsety = coordsx * 512 - 437;
756 if (creature == rabbittype)
757 for (i = 0; i < 512; i++) {
758 for (j = 0; j < 512; j++) {
759 if (bloodText[i * 512 * 3 + j * 3 + 0] <= which + 4 && bloodText[i * 512 * 3 + j * 3 + 0] >= which - 4) {
760 if (i < startx) startx = i;
761 if (j < starty) starty = j;
762 if (i > endx) endx = i;
763 if (j > endy) endy = j;
767 if (creature == wolftype)
768 for (i = 0; i < 512; i++) {
769 for (j = 0; j < 512; j++) {
770 if (wolfbloodText[i * 512 * 3 + j * 3 + 0] <= which + 4 && wolfbloodText[i * 512 * 3 + j * 3 + 0] >= which - 4) {
771 if (i < startx) startx = i;
772 if (j < starty) starty = j;
773 if (i > endx) endx = i;
774 if (j > endy) endy = j;
783 if (startx < 0) startx = 0;
784 if (starty < 0) starty = 0;
785 if (endx > 512 - 1) endx = 512 - 1;
786 if (endy > 512 - 1) endy = 512 - 1;
787 if (endx < startx) endx = startx;
788 if (endy < starty) endy = starty;
790 startx /= realtexdetail;
791 starty /= realtexdetail;
792 endx /= realtexdetail;
793 endy /= realtexdetail;
795 int texdetailint = realtexdetail;
797 if (creature == rabbittype)
798 for (i = startx; i < endx; i++) {
799 for (j = starty; j < endy; j++) {
800 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) {
801 color = Random() % 85 + 170;
802 where = i * skeleton.skinsize * 3 + j * 3;
803 if (skeleton.skinText[where + 0] > color / 2)
804 skeleton.skinText[where + 0] = color / 2;
805 skeleton.skinText[where + 1] = 0;
806 skeleton.skinText[where + 2] = 0;
807 } 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) {
808 color = Random() % 85 + 170;
809 where = i * skeleton.skinsize * 3 + j * 3;
810 if (skeleton.skinText[where + 0] > color / 2)
811 skeleton.skinText[where + 0] = color / 2;
812 skeleton.skinText[where + 1] = 0;
813 skeleton.skinText[where + 2] = 0;
817 if (creature == wolftype)
818 for (i = startx; i < endx; i++) {
819 for (j = starty; j < endy; j++) {
820 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) {
821 color = Random() % 85 + 170;
822 where = i * skeleton.skinsize * 3 + j * 3;
823 if (skeleton.skinText[where + 0] > color / 2)
824 skeleton.skinText[where + 0] = color / 2;
825 skeleton.skinText[where + 1] = 0;
826 skeleton.skinText[where + 2] = 0;
827 } 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) {
828 color = Random() % 85 + 170;
829 where = i * skeleton.skinsize * 3 + j * 3;
830 if (skeleton.skinText[where + 0] > color / 2)
831 skeleton.skinText[where + 0] = color / 2;
832 skeleton.skinText[where + 1] = 0;
833 skeleton.skinText[where + 2] = 0;
837 skeleton.drawmodel.textureptr.bind();
840 bleedy = (1 + coordsy) * 512;
841 bleedx = coordsx * 512;
842 bleedy /= realtexdetail;
843 bleedx /= realtexdetail;
848 if (bleedx > skeleton.skinsize - 1)
849 bleedx = skeleton.skinsize - 1;
850 if (bleedy > skeleton.skinsize - 1)
851 bleedy = skeleton.skinsize - 1;
852 direction = abs(Random() % 2) * 2 - 1;
857 bleeding = howmuch + (float)abs(Random() % 100) / 200 - .25;
858 deathbleeding += bleeding;
859 bloodloss += bleeding * 3;
861 if (tutoriallevel != 1 && aitype != playercontrolled && bloodloss > damagetolerance * 2 / 3 && bloodloss < damagetolerance && creature == rabbittype) {
862 if (abs(Random() % 2) == 0) {
863 aitype = gethelptype;
866 aitype = attacktypecutoff;
877 * guessing this performs a reversal
879 void Person::Reverse()
881 if (!((victim->aitype == playercontrolled
883 || staggerdelay <= 0)
884 && victim->animTarget != jumpupanim
885 && victim->animTarget != jumpdownanim
886 && (tutoriallevel != 1 || cananger)
890 if (normaldotproduct (victim->facing, victim->coords - coords) > 0
891 && (victim->id != 0 || difficulty >= 2)
892 && (creature != wolftype || victim->creature == wolftype))
895 if (animTarget == sweepanim) {
896 animTarget = sweepreversedanim;
897 animCurrent = sweepreversedanim;
898 victim->animCurrent = sweepreversalanim;
899 victim->animTarget = sweepreversalanim;
901 if (animTarget == spinkickanim) {
902 animTarget = spinkickreversedanim;
903 animCurrent = spinkickreversedanim;
904 victim->animCurrent = spinkickreversalanim;
905 victim->animTarget = spinkickreversalanim;
907 if (animTarget == upunchanim || animTarget == rabbittacklinganim) {
908 if (animTarget == rabbittacklinganim) {
911 victim->frameCurrent = 6;
912 victim->frameTarget = 7;
914 animTarget = upunchreversedanim;
915 animCurrent = upunchreversedanim;
916 victim->animCurrent = upunchreversalanim;
917 victim->animTarget = upunchreversalanim;
919 if (animTarget == staffhitanim && distsq(&victim->coords, &coords) < 2 && ((victim->id == 0 && victim->crouchkeydown) || Random() % 4 == 0)) {
920 if (victim->weaponactive != -1) {
921 victim->throwtogglekeydown = 1;
922 weapons[victim->weaponids[0]].owner = -1;
923 weapons[victim->weaponids[0]].velocity = victim->velocity * .2;
924 if (weapons[victim->weaponids[0]].velocity.x == 0)
925 weapons[victim->weaponids[0]].velocity.x = .1;
926 weapons[victim->weaponids[0]].tipvelocity = weapons[victim->weaponids[0]].velocity;
927 weapons[victim->weaponids[0]].missed = 1;
928 weapons[victim->weaponids[0]].freetime = 0;
929 weapons[victim->weaponids[0]].firstfree = 1;
930 weapons[victim->weaponids[0]].physics = 1;
931 victim->num_weapons--;
932 if (victim->num_weapons) {
933 victim->weaponids[0] = victim->weaponids[victim->num_weapons];
934 if (victim->weaponstuck == victim->num_weapons)
935 victim->weaponstuck = 0;
938 victim->weaponactive = -1;
939 for (int j = 0; j < numplayers; j++) {
940 player[j].wentforweapon = 0;
944 animTarget = staffhitreversedanim;
945 animCurrent = staffhitreversedanim;
946 victim->animCurrent = staffhitreversalanim;
947 victim->animTarget = staffhitreversalanim;
949 if (animTarget == staffspinhitanim && distsq(&victim->coords, &coords) < 2 && ((victim->id == 0 && victim->crouchkeydown) || Random() % 2 == 0)) {
950 if (victim->weaponactive != -1) {
951 victim->throwtogglekeydown = 1;
952 weapons[victim->weaponids[0]].owner = -1;
953 weapons[victim->weaponids[0]].velocity = victim->velocity * .2;
954 if (weapons[victim->weaponids[0]].velocity.x == 0)
955 weapons[victim->weaponids[0]].velocity.x = .1;
956 weapons[victim->weaponids[0]].tipvelocity = weapons[victim->weaponids[0]].velocity;
957 weapons[victim->weaponids[0]].missed = 1;
958 weapons[victim->weaponids[0]].freetime = 0;
959 weapons[victim->weaponids[0]].firstfree = 1;
960 weapons[victim->weaponids[0]].physics = 1;
961 victim->num_weapons--;
962 if (victim->num_weapons) {
963 victim->weaponids[0] = victim->weaponids[victim->num_weapons];
964 if (victim->weaponstuck == victim->num_weapons)
965 victim->weaponstuck = 0;
968 victim->weaponactive = -1;
969 for (int j = 0; j < numplayers; j++) {
970 player[j].wentforweapon = 0;
973 animTarget = staffspinhitreversedanim;
974 animCurrent = staffspinhitreversedanim;
975 victim->animCurrent = staffspinhitreversalanim;
976 victim->animTarget = staffspinhitreversalanim;
978 if (animTarget == swordslashanim && distsq(&victim->coords, &coords) < 2 && ((victim->id == 0 && victim->crouchkeydown) || Random() % 4 == 0)) {
979 if (victim->weaponactive != -1) {
980 victim->throwtogglekeydown = 1;
981 weapons[victim->weaponids[0]].owner = -1;
982 weapons[victim->weaponids[0]].velocity = victim->velocity * .2;
983 if (weapons[victim->weaponids[0]].velocity.x == 0)
984 weapons[victim->weaponids[0]].velocity.x = .1;
985 weapons[victim->weaponids[0]].tipvelocity = weapons[victim->weaponids[0]].velocity;
986 weapons[victim->weaponids[0]].missed = 1;
987 weapons[victim->weaponids[0]].freetime = 0;
988 weapons[victim->weaponids[0]].firstfree = 1;
989 weapons[victim->weaponids[0]].physics = 1;
990 victim->num_weapons--;
991 if (victim->num_weapons) {
992 victim->weaponids[0] = victim->weaponids[victim->num_weapons];
993 if (victim->weaponstuck == victim->num_weapons)
994 victim->weaponstuck = 0;
997 victim->weaponactive = -1;
998 for (int j = 0; j < numplayers; j++) {
999 player[j].wentforweapon = 0;
1002 animTarget = swordslashreversedanim;
1003 animCurrent = swordslashreversedanim;
1004 victim->animCurrent = swordslashreversalanim;
1005 victim->animTarget = swordslashreversalanim;
1007 if (animTarget == knifeslashstartanim && distsq(&victim->coords, &coords) < 2 && (victim->id == 0 || Random() % 4 == 0)) {
1008 if (victim->weaponactive != -1) {
1009 victim->throwtogglekeydown = 1;
1010 weapons[victim->weaponids[0]].owner = -1;
1011 weapons[victim->weaponids[0]].velocity = victim->velocity * .2;
1012 if (weapons[victim->weaponids[0]].velocity.x == 0)
1013 weapons[victim->weaponids[0]].velocity.x = .1;
1014 weapons[victim->weaponids[0]].tipvelocity = weapons[victim->weaponids[0]].velocity;
1015 weapons[victim->weaponids[0]].missed = 1;
1016 weapons[victim->weaponids[0]].freetime = 0;
1017 weapons[victim->weaponids[0]].firstfree = 1;
1018 weapons[victim->weaponids[0]].physics = 1;
1019 victim->num_weapons--;
1020 if (victim->num_weapons) {
1021 victim->weaponids[0] = victim->weaponids[victim->num_weapons];
1022 if (victim->weaponstuck == victim->num_weapons)
1023 victim->weaponstuck = 0;
1026 victim->weaponactive = -1;
1027 for (int j = 0; j < numplayers; j++) {
1028 player[j].wentforweapon = 0;
1031 animTarget = knifeslashreversedanim;
1032 animCurrent = knifeslashreversedanim;
1033 victim->animCurrent = knifeslashreversalanim;
1034 victim->animTarget = knifeslashreversalanim;
1036 if (animTarget != knifeslashstartanim && animTarget != staffhitanim && animTarget != staffspinhitanim && animTarget != winduppunchanim && animTarget != wolfslapanim && animTarget != swordslashanim && animTarget != swordslashanim) {
1037 victim->targettilt2 = targettilt2;
1038 victim->frameCurrent = frameCurrent;
1039 victim->frameTarget = frameTarget;
1040 victim->target = target;
1041 victim->velocity = 0;
1042 victim->oldcoords = victim->coords;
1043 victim->coords = coords;
1044 victim->targetyaw = targetyaw;
1045 victim->yaw = targetyaw;
1046 victim->victim = this;
1048 if (animTarget == winduppunchanim) {
1049 animTarget = winduppunchblockedanim;
1050 victim->animTarget = blockhighleftanim;
1051 victim->frameTarget = 1;
1052 victim->target = .5;
1053 victim->victim = this;
1054 victim->targetyaw = targetyaw + 180;
1056 if (animTarget == wolfslapanim) {
1057 animTarget = winduppunchblockedanim;
1058 victim->animTarget = blockhighleftanim;
1059 victim->frameTarget = 1;
1060 victim->target = .5;
1061 victim->victim = this;
1062 victim->targetyaw = targetyaw + 180;
1064 if ((animTarget == swordslashanim || animTarget == staffhitanim || animTarget == staffspinhitanim) && victim->weaponactive != -1) {
1065 animTarget = swordslashparriedanim;
1066 parriedrecently = .4;
1067 victim->parriedrecently = 0;
1068 victim->animTarget = swordslashparryanim;
1069 victim->frameTarget = 1;
1070 victim->target = .5;
1071 victim->victim = this;
1072 victim->targetyaw = targetyaw + 180;
1074 if (abs(Random() % 20) == 0 || weapons[victim->weaponids[victim->weaponactive]].getType() == knife) {
1075 if (victim->weaponactive != -1) {
1076 if (weapons[victim->weaponids[0]].getType() == staff || weapons[weaponids[0]].getType() == staff) {
1077 if (weapons[victim->weaponids[0]].getType() == staff)
1078 weapons[victim->weaponids[0]].damage += .2 + float(abs(Random() % 100) - 50) / 250;
1079 if (weapons[weaponids[0]].getType() == staff)
1080 weapons[weaponids[0]].damage += .2 + float(abs(Random() % 100) - 50) / 250;
1081 emit_sound_at(swordstaffsound, victim->coords);
1083 emit_sound_at(metalhitsound, victim->coords);
1087 victim->Puff(righthand);
1089 victim->frameTarget = 0;
1090 victim->animTarget = staggerbackhighanim;
1091 victim->targetyaw = targetyaw + 180;
1093 weapons[victim->weaponids[0]].owner = -1;
1094 aim = DoRotation(facing, 0, 90, 0) * 21;
1096 weapons[victim->weaponids[0]].velocity = aim * -.2;
1097 weapons[victim->weaponids[0]].tipvelocity = aim;
1098 weapons[victim->weaponids[0]].missed = 1;
1099 weapons[victim->weaponids[0]].hitsomething = 0;
1100 weapons[victim->weaponids[0]].freetime = 0;
1101 weapons[victim->weaponids[0]].firstfree = 1;
1102 weapons[victim->weaponids[0]].physics = 1;
1103 victim->num_weapons--;
1104 if (victim->num_weapons) {
1105 victim->weaponids[0] = victim->weaponids[num_weapons];
1106 if (victim->weaponstuck == victim->num_weapons)
1107 victim->weaponstuck = 0;
1109 victim->weaponactive = -1;
1110 for (int i = 0; i < numplayers; i++) {
1111 player[i].wentforweapon = 0;
1115 if (abs(Random() % 20) == 0) {
1116 if (weaponactive != -1) {
1117 if (weapons[victim->weaponids[0]].getType() == staff || weapons[weaponids[0]].getType() == staff) {
1118 if (weapons[victim->weaponids[0]].getType() == staff)
1119 weapons[victim->weaponids[0]].damage += .2 + float(abs(Random() % 100) - 50) / 250;
1120 if (weapons[weaponids[0]].getType() == staff)
1121 weapons[weaponids[0]].damage += .2 + float(abs(Random() % 100) - 50) / 250;
1123 emit_sound_at(swordstaffsound, coords);
1125 emit_sound_at(metalhitsound, coords);
1133 animTarget = staggerbackhighanim;
1134 targetyaw = targetyaw + 180;
1136 weapons[weaponids[0]].owner = -1;
1137 aim = DoRotation(facing, 0, 90, 0) * 21;
1139 weapons[weaponids[0]].velocity = aim * -.2;
1140 weapons[weaponids[0]].tipvelocity = aim;
1141 weapons[weaponids[0]].hitsomething = 0;
1142 weapons[weaponids[0]].missed = 1;
1143 weapons[weaponids[0]].freetime = 0;
1144 weapons[weaponids[0]].firstfree = 1;
1145 weapons[weaponids[0]].physics = 1;
1148 weaponids[0] = weaponids[num_weapons];
1149 if (weaponstuck == num_weapons)
1153 for (int i = 0; i < numplayers; i++) {
1154 player[i].wentforweapon = 0;
1161 if (animTarget == knifeslashstartanim || animTarget == swordslashanim || animTarget == staffhitanim || animTarget == staffspinhitanim) {
1162 if ((animTarget != staffhitanim && animTarget != staffspinhitanim) || distsq(&coords, &victim->coords) > .2) {
1163 victim->animTarget = dodgebackanim;
1164 victim->frameTarget = 0;
1168 rotatetarget = coords - victim->coords;
1169 Normalise(&rotatetarget);
1170 victim->targetyaw = -asin(0 - rotatetarget.x);
1171 victim->targetyaw *= 360 / 6.28;
1172 if (rotatetarget.z < 0)
1173 victim->targetyaw = 180 - victim->targetyaw;
1175 victim->targettilt2 = -asin(rotatetarget.y) * 360 / 6.28; //*-70;
1177 victim->lastattack3 = victim->lastattack2;
1178 victim->lastattack2 = victim->lastattack;
1179 victim->lastattack = victim->animTarget;
1181 victim->animTarget = sweepanim;
1182 victim->frameTarget = 0;
1186 rotatetarget = coords - victim->coords;
1187 Normalise(&rotatetarget);
1188 victim->targetyaw = -asin(0 - rotatetarget.x);
1189 victim->targetyaw *= 360 / 6.28;
1190 if (rotatetarget.z < 0)
1191 victim->targetyaw = 180 - victim->targetyaw;
1193 victim->targettilt2 = -asin(rotatetarget.y) * 360 / 6.28; //*-70;
1195 victim->lastattack3 = victim->lastattack2;
1196 victim->lastattack2 = victim->lastattack;
1197 victim->lastattack = victim->animTarget;
1202 victim->velocity = 0;
1204 if (aitype != playercontrolled)
1206 if (aitype != playercontrolled && Random() % 3 == 0 && escapednum < 2 && difficulty == 2)
1208 if (aitype != playercontrolled && Random() % 5 == 0 && escapednum < 2 && difficulty == 1)
1210 if (aitype != playercontrolled && Random() % 10 == 0 && escapednum < 2 && difficulty == 0)
1213 if (victim->id == 0 && animation[victim->animTarget].attack == reversal)
1220 void Person::DoDamage(float howmuch)
1222 // subtract health (temporary?)
1223 if (tutoriallevel != 1)
1224 damage += howmuch / power;
1227 damagedealt += howmuch / power;
1229 damagetaken += howmuch / power;
1232 if (id == 0 && (bonus == solidhit || bonus == twoxcombo || bonus == threexcombo || bonus == fourxcombo || bonus == megacombo))
1235 if (tutoriallevel != 1)
1236 permanentdamage += howmuch / 2 / power;
1237 if (tutoriallevel != 1)
1238 superpermanentdamage += howmuch / 4 / power;
1240 if (permanentdamage > damagetolerance / 2 && permanentdamage - howmuch < damagetolerance / 2 && Random() % 2)
1242 if ((permanentdamage > damagetolerance * .8 && Random() % 2 && !deathbleeding) || spurt)
1246 camerashake += howmuch / 100;
1247 if (id == 0 && ((howmuch > 50 && damage > damagetolerance / 2)))
1248 blackout = damage / damagetolerance;
1253 if (aitype == passivetype && damage < damagetolerance && ((tutoriallevel != 1 || cananger) && hostile))
1254 aitype = attacktypecutoff;
1255 if (tutoriallevel != 1 && aitype != playercontrolled && damage < damagetolerance && damage > damagetolerance * 2 / 3 && creature == rabbittype) {
1256 if (abs(Random() % 2) == 0) {
1257 aitype = gethelptype;
1260 aitype = attacktypecutoff;
1264 if (howmuch > damagetolerance * 50 && skeleton.free != 2) {
1267 for (int i = 0; i < skeleton.num_joints; i++) {
1269 flatvelocity2 = velocity;
1271 flatvelocity2 = skeleton.joints[i].velocity;
1273 flatfacing2 = DoRotation(DoRotation(DoRotation(skeleton.joints[i].position, 0, 0, tilt), tilt2, 0, 0), 0, yaw, 0) * scale + coords;
1275 flatfacing2 = skeleton.joints[i].position * scale + coords;
1276 flatvelocity2.x += (float)(abs(Random() % 100) - 50) / 10;
1277 flatvelocity2.y += (float)(abs(Random() % 100) - 50) / 10;
1278 flatvelocity2.z += (float)(abs(Random() % 100) - 50) / 10;
1279 Sprite::MakeSprite(bloodflamesprite, flatfacing2, flatvelocity2, 1, 1, 1, 3, 1);
1280 Sprite::MakeSprite(bloodsprite, flatfacing2, flatvelocity2, 1, 1, 1, .4, 1);
1281 Sprite::MakeSprite(cloudsprite, flatfacing2, flatvelocity2 * 0, .6, 0, 0, 1, .5);
1284 emit_sound_at(splattersound, coords);
1293 if (!dead && creature == wolftype) {
1294 award_bonus(0, Wolfbonus);
1301 if (tutoriallevel != 1 || id == 0)
1302 if (speechdelay <= 0 && !dead && aitype != playercontrolled) {
1303 int whichsound = -1;
1305 if (creature == wolftype) {
1306 int i = abs(Random() % 2);
1308 whichsound = snarlsound;
1310 whichsound = snarl2sound;
1311 envsound[numenvsounds] = coords;
1312 envsoundvol[numenvsounds] = 16;
1313 envsoundlife[numenvsounds] = .4;
1316 if (creature == rabbittype) {
1317 int i = abs(Random() % 2);
1319 whichsound = rabbitpainsound;
1320 if (i == 1 && damage > damagetolerance)
1321 whichsound = rabbitpain1sound;
1322 envsound[numenvsounds] = coords;
1323 envsoundvol[numenvsounds] = 16;
1324 envsoundlife[numenvsounds] = .4;
1326 //if(i==2)whichsound=rabbitpain2sound;
1329 if (whichsound != -1) {
1330 emit_sound_at(whichsound, coords);
1335 //if(permanentdamage>=damagetolerance&&howmuch<50)permanentdamage=damagetolerance-1;
1336 //if(damage>=damagetolerance&&howmuch<30&&!dead)damage=damagetolerance-1;
1340 * calculate/animate head facing direction?
1342 void Person::DoHead()
1344 static XYZ rotatearound;
1346 static float lookspeed = 500;
1348 if (!freeze && !winfreeze) {
1351 targetheadyaw = (float)((int)((0 - yaw - targetheadyaw + 180) * 100) % 36000) / 100;
1352 targetheadpitch = (float)((int)(targetheadpitch * 100) % 36000) / 100;
1354 while (targetheadyaw > 180)targetheadyaw -= 360;
1355 while (targetheadyaw < -180)targetheadyaw += 360;
1357 if (targetheadyaw > 160)
1358 targetheadpitch = targetheadpitch * -1;
1359 if (targetheadyaw < -160)
1360 targetheadpitch = targetheadpitch * -1;
1361 if (targetheadyaw > 160)
1362 targetheadyaw = targetheadyaw - 180;
1363 if (targetheadyaw < -160)
1364 targetheadyaw = targetheadyaw + 180;
1366 if (targetheadpitch > 120)
1367 targetheadpitch = 120;
1368 if (targetheadpitch < -120)
1369 targetheadpitch = -120;
1370 if (targetheadyaw > 120)
1371 targetheadyaw = 120;
1372 if (targetheadyaw < -120)
1373 targetheadyaw = -120;
1376 targetheadpitch = 0;
1378 if (targetheadyaw > 80)
1380 if (targetheadyaw < -80)
1381 targetheadyaw = -80;
1382 if (targetheadpitch > 50)
1383 targetheadpitch = 50;
1384 if (targetheadpitch < -50)
1385 targetheadpitch = -50;
1388 if (abs(headyaw - targetheadyaw) < multiplier * lookspeed)
1389 headyaw = targetheadyaw;
1390 else if (headyaw > targetheadyaw) {
1391 headyaw -= multiplier * lookspeed;
1392 } else if (headyaw < targetheadyaw) {
1393 headyaw += multiplier * lookspeed;
1396 if (abs(headpitch - targetheadpitch) < multiplier * lookspeed / 2)
1397 headpitch = targetheadpitch;
1398 else if (headpitch > targetheadpitch) {
1399 headpitch -= multiplier * lookspeed / 2;
1400 } else if (headpitch < targetheadpitch) {
1401 headpitch += multiplier * lookspeed / 2;
1404 rotatearound = jointPos(neck);
1405 jointPos(head) = rotatearound + DoRotation(jointPos(head) - rotatearound, headpitch, 0, 0);
1409 if (animTarget != bounceidleanim && animTarget != fightidleanim && animTarget != wolfidle && animTarget != knifefightidleanim && animTarget != drawrightanim && animTarget != drawleftanim && animTarget != walkanim) {
1410 facing = DoRotation(facing, headpitch * .4, 0, 0);
1411 facing = DoRotation(facing, 0, headyaw * .4, 0);
1414 if (animTarget == bounceidleanim || animTarget == fightidleanim || animTarget == wolfidle || animTarget == knifefightidleanim || animTarget == drawrightanim || animTarget == drawleftanim) {
1415 facing = DoRotation(facing, headpitch * .8, 0, 0);
1416 facing = DoRotation(facing, 0, headyaw * .8, 0);
1419 if (animTarget == walkanim) {
1420 facing = DoRotation(facing, headpitch * .6, 0, 0);
1421 facing = DoRotation(facing, 0, headyaw * .6, 0);
1424 skeleton.specialforward[0] = facing;
1425 //skeleton.specialforward[0]=DoRotation(facing,0,yaw,0);
1427 for (i = 0; i < skeleton.num_muscles; i++) {
1428 if (skeleton.muscles[i].visible && (skeleton.muscles[i].parent1->label == head || skeleton.muscles[i].parent2->label == head)) {
1429 skeleton.FindRotationMuscle(i, animTarget);
1436 * ragdolls character?
1438 void Person::RagDoll(bool checkcollision)
1443 if (!skeleton.free) {
1446 if (id == 0 && isFlip())
1453 facing = DoRotation(facing, 0, yaw, 0);
1455 skeleton.freetime = 0;
1457 skeleton.longdead = 0;
1460 skeleton.broken = 0;
1461 skeleton.spinny = 1;
1463 skeleton.freefall = 1;
1465 if (!isnormal(velocity.x)) velocity.x = 0;
1466 if (!isnormal(velocity.y)) velocity.y = 0;
1467 if (!isnormal(velocity.z)) velocity.z = 0;
1468 if (!isnormal(yaw)) yaw = 0;
1469 if (!isnormal(coords.x)) coords = 0;
1470 if (!isnormal(tilt)) tilt = 0;
1471 if (!isnormal(tilt2)) tilt2 = 0;
1473 for (i = 0; i < skeleton.num_joints; i++) {
1474 skeleton.joints[i].delay = 0;
1475 skeleton.joints[i].locked = 0;
1476 skeleton.joints[i].position = DoRotation(DoRotation(DoRotation(skeleton.joints[i].position, 0, 0, tilt), tilt2, 0, 0), 0, yaw, 0);
1477 if (!isnormal(skeleton.joints[i].position.x)) skeleton.joints[i].position = DoRotation(skeleton.joints[i].position, 0, yaw, 0);
1478 if (!isnormal(skeleton.joints[i].position.x)) skeleton.joints[i].position = skeleton.joints[i].position;
1479 if (!isnormal(skeleton.joints[i].position.x)) skeleton.joints[i].position = coords;
1480 skeleton.joints[i].position.y += .1;
1481 skeleton.joints[i].oldposition = skeleton.joints[i].position;
1482 skeleton.joints[i].realoldposition = skeleton.joints[i].position * scale + coords;
1485 for (i = 0; i < skeleton.num_joints; i++) {
1486 skeleton.joints[i].velocity = 0;
1487 skeleton.joints[i].velchange = 0;
1489 skeleton.DoConstraints(&coords, &scale);
1490 if (animation[animCurrent].height == lowheight || animation[animTarget].height == lowheight) {
1491 skeleton.DoConstraints(&coords, &scale);
1492 skeleton.DoConstraints(&coords, &scale);
1493 skeleton.DoConstraints(&coords, &scale);
1494 skeleton.DoConstraints(&coords, &scale);
1497 speed = animation[animTarget].speed[frameTarget] * 2;
1498 if (animation[animCurrent].speed[frameCurrent] > animation[animTarget].speed[frameTarget]) {
1499 speed = animation[animCurrent].speed[frameCurrent] * 2;
1502 speed = transspeed * 2;
1506 for (i = 0; i < skeleton.num_joints; i++) {
1507 if ((animation[animCurrent].attack != reversed || animCurrent == swordslashreversedanim) && animCurrent != rabbitkickanim && !isLanding() && !wasLanding() && animation[animCurrent].height == animation[animTarget].height)
1508 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);
1510 skeleton.joints[i].velocity = velocity / scale + facing * 5;
1511 change.x = (float)(Random() % 100) / 100;
1512 change.y = (float)(Random() % 100) / 100;
1513 change.z = (float)(Random() % 100) / 100;
1514 skeleton.joints[i].velocity += change;
1515 skeleton.joints[abs(Random() % skeleton.num_joints)].velocity -= change;
1517 change.x = (float)(Random() % 100) / 100;
1518 change.y = (float)(Random() % 100) / 100;
1519 change.z = (float)(Random() % 100) / 100;
1520 skeleton.joints[i].velchange += change;
1521 skeleton.joints[abs(Random() % skeleton.num_joints)].velchange -= change;
1524 if (checkcollision) {
1531 for (j = 0; j < skeleton.num_joints; j++) {
1532 average += skeleton.joints[j].position;
1536 coords += average * scale;
1537 for (j = 0; j < skeleton.num_joints; j++) {
1538 skeleton.joints[j].position -= average;
1541 whichpatchx = coords.x / (terrain.size / subdivision * terrain.scale);
1542 whichpatchz = coords.z / (terrain.size / subdivision * terrain.scale);
1543 if (terrain.patchobjectnum[whichpatchx][whichpatchz])
1544 for (l = 0; l < terrain.patchobjectnum[whichpatchx][whichpatchz]; l++) {
1545 i = terrain.patchobjects[whichpatchx][whichpatchz][l];
1548 if (SphereCheck(&lowpoint, 3, &colpoint, &objects.position[i], &objects.yaw[i], &objects.model[i]) != -1) {
1549 coords.x = lowpoint.x;
1550 coords.z = lowpoint.z;
1559 for (i = 0; i < skeleton.num_joints; i++) {
1560 velocity += skeleton.joints[i].velocity * scale;
1562 velocity /= skeleton.num_joints;
1565 if (Random() % 2 == 0) {
1566 if (weaponactive != -1 && animTarget != rabbitkickanim && num_weapons > 0) {
1567 weapons[weaponids[0]].owner = -1;
1568 weapons[weaponids[0]].hitsomething = 0;
1569 weapons[weaponids[0]].velocity = jointVel(righthand) * scale * -.3;
1570 weapons[weaponids[0]].velocity.x += .01;
1571 weapons[weaponids[0]].tipvelocity = jointVel(righthand) * scale;
1572 weapons[weaponids[0]].missed = 1;
1573 weapons[weaponids[0]].freetime = 0;
1574 weapons[weaponids[0]].firstfree = 1;
1575 weapons[weaponids[0]].physics = 1;
1578 weaponids[0] = weaponids[num_weapons];
1579 if (weaponstuck == num_weapons)
1583 for (i = 0; i < numplayers; i++) {
1584 player[i].wentforweapon = 0;
1589 animTarget = bounceidleanim;
1590 animCurrent = bounceidleanim;
1600 void Person::FootLand(int which, float opacity)
1602 static XYZ terrainlight;
1603 static XYZ footvel, footpoint;
1604 if (opacity >= 1 || skiddelay <= 0)
1608 footpoint = DoRotation(jointPos(leftfoot), 0, yaw, 0) * scale + coords;
1610 footpoint = DoRotation(jointPos(rightfoot), 0, yaw, 0) * scale + coords;
1611 //footpoint.y=coords.y;
1612 if (distsq(&footpoint, &viewer))
1613 Sprite::MakeSprite(cloudsprite, footpoint, footvel, 1, 1, 1, .5, .2 * opacity);
1614 } else if (environment == snowyenvironment && onterrain && terrain.getOpacity(coords.x, coords.z) < .2) {
1615 footvel = velocity / 5;
1619 footpoint = DoRotation(jointPos(leftfoot), 0, yaw, 0) * scale + coords;
1621 footpoint = DoRotation(jointPos(rightfoot), 0, yaw, 0) * scale + coords;
1622 footpoint.y = terrain.getHeight(footpoint.x, footpoint.z);
1623 terrainlight = terrain.getLighting(footpoint.x, footpoint.z);
1624 if (distsq(&footpoint, &viewer) < viewdistance * viewdistance / 4)
1625 Sprite::MakeSprite(cloudsprite, footpoint, footvel * .6, terrainlight.x, terrainlight.y, terrainlight.z, .5, .7 * opacity);
1626 if (opacity >= 1 || detail == 2)
1628 if (distsq(&footpoint, &viewer) < viewdistance * viewdistance / 4)
1629 terrain.MakeDecal(footprintdecal, footpoint, .2, 1 * opacity, yaw);
1630 } else if (environment == grassyenvironment && onterrain && terrain.getOpacity(coords.x, coords.z) < .2) {
1631 footvel = velocity / 5;
1635 footpoint = DoRotation(jointPos(leftfoot), 0, yaw, 0) * scale + coords;
1637 footpoint = DoRotation(jointPos(rightfoot), 0, yaw, 0) * scale + coords;
1638 footpoint.y = terrain.getHeight(footpoint.x, footpoint.z);
1639 terrainlight = terrain.getLighting(footpoint.x, footpoint.z);
1640 if (distsq(&footpoint, &viewer) < viewdistance * viewdistance / 4)
1641 Sprite::MakeSprite(cloudsprite, footpoint, footvel * .6, terrainlight.x * 90 / 255, terrainlight.y * 70 / 255, terrainlight.z * 8 / 255, .5, .5 * opacity);
1642 } else if (environment == desertenvironment && onterrain && terrain.getOpacity(coords.x, coords.z) < .2) {
1643 footvel = velocity / 5;
1647 footpoint = DoRotation(jointPos(leftfoot), 0, yaw, 0) * scale + coords;
1649 footpoint = DoRotation(jointPos(rightfoot), 0, yaw, 0) * scale + coords;
1650 footpoint.y = terrain.getHeight(footpoint.x, footpoint.z);
1651 terrainlight = terrain.getLighting(footpoint.x, footpoint.z);
1652 if (distsq(&footpoint, &viewer) < viewdistance * viewdistance / 4)
1653 Sprite::MakeSprite(cloudsprite, footpoint, footvel * .6, terrainlight.x * 190 / 255, terrainlight.y * 170 / 255, terrainlight.z * 108 / 255, .5, .7 * opacity);
1654 if (opacity >= 1 || detail == 2)
1656 if (distsq(&footpoint, &viewer) < viewdistance * viewdistance / 4)
1657 terrain.MakeDecal(footprintdecal, footpoint, .2, .25 * opacity, yaw);
1658 } else if (isLanding() || animTarget == jumpupanim || isLandhard()) {
1659 footvel = velocity / 5;
1663 footpoint = DoRotation(jointPos(leftfoot), 0, yaw, 0) * scale + coords;
1665 footpoint = DoRotation(jointPos(rightfoot), 0, yaw, 0) * scale + coords;
1666 //footpoint.y=coords.y;
1667 if (distsq(&footpoint, &viewer) < viewdistance * viewdistance / 4)
1668 Sprite::MakeSprite(cloudsprite, footpoint, footvel * .6, 1, 1, 1, .5, .2 * opacity);
1673 * make a puff effect at a body part (dust effect?)
1675 void Person::Puff(int whichlabel)
1677 static XYZ footvel, footpoint;
1680 footpoint = DoRotation(jointPos(whichlabel), 0, yaw, 0) * scale + coords;
1681 Sprite::MakeSprite(cloudimpactsprite, footpoint, footvel, 1, 1, 1, .9, .3);
1685 * I think I added this in an attempt to clean up code
1687 void Person::setAnimation(int animation)
1689 animTarget = animation;
1698 void Person::DoAnimations()
1700 if (!skeleton.free) {
1702 static float oldtarget;
1704 if (isIdle() && animCurrent != getIdle())
1705 normalsupdatedelay = 0;
1707 if (animTarget == tempanim || animCurrent == tempanim) {
1708 animation[tempanim] = tempanimation;
1710 if (animTarget == jumpupanim || animTarget == jumpdownanim || isFlip()) {
1716 vel[0] = velocity.x;
1717 vel[1] = velocity.y;
1718 vel[2] = velocity.z;
1721 OPENAL_3D_SetAttributes(channels[whooshsound], gLoc, vel);
1722 OPENAL_SetVolume(channels[whooshsound], 64 * findLength(&velocity) / 5);
1724 if (((velocity.y < -15) || (crouchkeydown && velocity.y < -8)) && abs(velocity.y) * 4 > fast_sqrt(velocity.x * velocity.x * velocity.z * velocity.z))
1726 if (!crouchkeydown && velocity.y >= -15)
1729 if ((animCurrent == jumpupanim || animTarget == jumpdownanim)/*&&velocity.y<40*/ && !isFlip() && (!isLanding() && !isLandhard()) && ((crouchkeydown && !crouchtogglekeydown))) {
1734 targfacing = DoRotation(targfacing, 0, targetyaw, 0);
1736 if (normaldotproduct(targfacing, velocity) >= -.3)
1737 animTarget = flipanim;
1739 animTarget = backflipanim;
1740 crouchtogglekeydown = 1;
1748 if (animation[animTarget].attack != reversed)
1750 if (!crouchkeydown || (isLanding() || isLandhard()) || (wasLanding() || wasLandhard())) {
1751 crouchtogglekeydown = 0;
1752 if (aitype == playercontrolled)
1755 if (!crouchtogglekeydown && animation[animTarget].attack == reversed && aitype == playercontrolled && (escapednum < 2 || reversaltrain))
1758 crouchtogglekeydown = 1;
1762 if (animation[animTarget].attack || animCurrent == getupfrombackanim || animCurrent == getupfromfrontanim) {
1764 normalsupdatedelay = 0;
1768 if (animTarget == rollanim && frameTarget == 3 && onfire) {
1770 emit_sound_at(fireendsound, coords);
1771 pause_sound(stream_firesound);
1775 if (animTarget == rabbittacklinganim && frameTarget == 1) {
1776 //if(victim->aitype==attacktypecutoff&&Random()%2==0&&victim->stunned<=0&&animation[victim->animTarget].attack==neutral&&victim->id!=0)Reverse();
1777 if (victim->aitype == attacktypecutoff && victim->stunned <= 0 && victim->surprised <= 0 && victim->id != 0)
1779 if (animTarget == rabbittacklinganim && frameTarget == 1 && !victim->isCrouch() && victim->animTarget != backhandspringanim) {
1780 if (normaldotproduct(victim->facing, facing) > 0)
1781 victim->animTarget = rabbittackledbackanim;
1783 victim->animTarget = rabbittackledfrontanim;
1784 victim->frameTarget = 2;
1787 victim->targetyaw = yaw;
1788 if (victim->aitype == gethelptype)
1789 victim->DoDamage(victim->damagetolerance - victim->damage);
1790 //victim->DoDamage(30);
1791 if (creature == wolftype) {
1793 emit_sound_at(clawslicesound, victim->coords);
1795 victim->DoBloodBig(1 / victim->armorhead, 210);
1797 award_bonus(id, TackleBonus,
1798 victim->aitype == gethelptype ? 50 : 0);
1802 if (!drawtogglekeydown && drawkeydown && (weaponactive == -1 || num_weapons == 1) && (animation[animTarget].label[frameTarget] || (animTarget != animCurrent && animCurrent == rollanim)) && num_weapons > 0 && creature != wolftype) {
1803 if (weapons[weaponids[0]].getType() == knife) {
1804 if (weaponactive == -1)
1806 else if (weaponactive == 0)
1809 if (weaponactive == -1) {
1810 emit_sound_at(knifesheathesound, coords);
1812 if (weaponactive != -1) {
1813 emit_sound_at(knifedrawsound, coords, 128);
1816 drawtogglekeydown = 1;
1819 if (tutoriallevel != 1 || id == 0)
1820 if ((animation[animTarget].label[frameTarget] && (animation[animTarget].label[frameTarget] < 5 || animation[animTarget].label[frameTarget] == 8))/*||(animTarget==rollanim&&frameTarget==animation[rollanim].numframes-1)*/) {
1823 if (terrain.getOpacity(coords.x, coords.z) < .2) {
1824 if (animation[animTarget].label[frameTarget] == 1)
1825 whichsound = footstepsound;
1827 whichsound = footstepsound2;
1828 if (animation[animTarget].label[frameTarget] == 1)
1830 if (animation[animTarget].label[frameTarget] == 2)
1832 if (animation[animTarget].label[frameTarget] == 3 && isRun()) {
1838 if (terrain.getOpacity(coords.x, coords.z) >= .2) {
1839 if (animation[animTarget].label[frameTarget] == 1)
1840 whichsound = footstepsound3;
1842 whichsound = footstepsound4;
1846 if (animation[animTarget].label[frameTarget] == 1)
1847 whichsound = footstepsound3;
1849 whichsound = footstepsound4;
1851 if (animation[animTarget].label[frameTarget] == 4 && (weaponactive == -1 || (animTarget != knifeslashstartanim && animTarget != knifethrowanim && animTarget != crouchstabanim && animTarget != swordgroundstabanim && animTarget != knifefollowanim))) {
1852 if (animation[animTarget].attack != neutral) {
1853 i = abs(Random() % 3);
1855 whichsound = lowwhooshsound;
1857 whichsound = midwhooshsound;
1859 whichsound = highwhooshsound;
1861 if (animation[animTarget].attack == neutral)
1862 whichsound = movewhooshsound;
1863 } else if (animation[animTarget].label[frameTarget] == 4)
1864 whichsound = knifeswishsound;
1865 if (animation[animTarget].label[frameTarget] == 8 && tutoriallevel != 1)
1866 whichsound = landsound2;
1868 emit_sound_at(whichsound, coords, 256.);
1871 if (whichsound == footstepsound || whichsound == footstepsound2 || whichsound == footstepsound3 || whichsound == footstepsound4) {
1872 envsound[numenvsounds] = coords;
1873 if (animTarget == wolfrunninganim || animTarget == rabbitrunninganim)
1874 envsoundvol[numenvsounds] = 15;
1876 envsoundvol[numenvsounds] = 6;
1877 envsoundlife[numenvsounds] = .4;
1881 if (animation[animTarget].label[frameTarget] == 3) {
1883 emit_sound_at(whichsound, coords, 128.);
1888 if (tutoriallevel != 1 || id == 0)
1889 if (speechdelay <= 0)
1890 if (animTarget != crouchstabanim && animTarget != swordgroundstabanim && animTarget != staffgroundsmashanim)
1891 if ((animation[animTarget].label[frameTarget] && (animation[animTarget].label[frameTarget] < 5 || animation[animTarget].label[frameTarget] == 8))/*||(animTarget==rollanim&&frameTarget==animation[rollanim].numframes-1)*/) {
1892 int whichsound = -1;
1893 if (animation[animTarget].label[frameTarget] == 4 && aitype != playercontrolled) {
1894 if (animation[animTarget].attack != neutral) {
1895 i = abs(Random() % 4);
1896 if (creature == rabbittype) {
1897 if (i == 0) whichsound = rabbitattacksound;
1898 if (i == 1) whichsound = rabbitattack2sound;
1899 if (i == 2) whichsound = rabbitattack3sound;
1900 if (i == 3) whichsound = rabbitattack4sound;
1902 if (creature == wolftype) {
1903 if (i == 0) whichsound = barksound;
1904 if (i == 1) whichsound = bark2sound;
1905 if (i == 2) whichsound = bark3sound;
1906 if (i == 3) whichsound = barkgrowlsound;
1910 //if(animation[animTarget].attack==neutral)whichsound=movewhooshsound;
1912 //else if(animation[animTarget].label[frameTarget]==4)whichsound=knifeswishsound;
1913 //if(animation[animTarget].label[frameTarget]==8)whichsound=landsound2;
1915 if (whichsound != -1) {
1916 emit_sound_at(whichsound, coords);
1922 if ((!wasLanding() && !wasLandhard()) && animCurrent != getIdle() && (isLanding() || isLandhard())) {
1928 currentoffset = targetoffset;
1929 frameTarget = frameCurrent;
1930 animCurrent = animTarget;
1933 if (animTarget == removeknifeanim && animation[animTarget].label[frameCurrent] == 5) {
1934 for (i = 0; i < weapons.size(); i++) {
1935 if (weapons[i].owner == -1)
1936 if (distsqflat(&coords, &weapons[i].position) < 4 && weaponactive == -1) {
1937 if (distsq(&coords, &weapons[i].position) >= 1) {
1938 if (weapons[i].getType() != staff) {
1939 emit_sound_at(knifedrawsound, coords, 128.);
1943 weapons[i].owner = id;
1944 if (num_weapons > 0) {
1945 weaponids[num_weapons] = weaponids[0];
1954 if (animTarget == crouchremoveknifeanim && animation[animTarget].label[frameCurrent] == 5) {
1955 for (i = 0; i < weapons.size(); i++) {
1956 bool willwork = true;
1957 if (weapons[i].owner != -1)
1958 if (player[weapons[i].owner].weaponstuck != -1)
1959 if (player[weapons[i].owner].weaponids[player[weapons[i].owner].weaponstuck] == i)
1960 if (player[weapons[i].owner].num_weapons > 1)
1962 if ((weapons[i].owner == -1) || (hasvictim && weapons[i].owner == victim->id && victim->skeleton.free))
1963 if (willwork && distsqflat(&coords, &weapons[i].position) < 3 && weaponactive == -1) {
1964 if (distsq(&coords, &weapons[i].position) < 1 || hasvictim) {
1965 bool fleshstuck = false;
1966 if (weapons[i].owner != -1)
1967 if (victim->weaponstuck != -1) {
1968 if (victim->weaponids[victim->weaponstuck] == i) {
1973 emit_sound_at(fleshstabremovesound, coords, 128.);
1975 if (weapons[i].getType() != staff) {
1976 emit_sound_at(knifedrawsound, coords, 128.);
1980 if (weapons[i].owner != -1) {
1982 victim = &player[weapons[i].owner];
1983 if (victim->num_weapons == 1)
1984 victim->num_weapons = 0;
1986 victim->num_weapons = 1;
1988 //victim->weaponactive=-1;
1989 victim->skeleton.longdead = 0;
1990 victim->skeleton.free = 1;
1991 victim->skeleton.broken = 0;
1993 for (int j = 0; j < victim->skeleton.num_joints; j++) {
1994 victim->skeleton.joints[j].velchange = 0;
1995 victim->skeleton.joints[j].locked = 0;
2001 Normalise(&relative);
2002 XYZ footvel, footpoint;
2004 footpoint = weapons[i].position;
2005 if (victim->weaponstuck != -1) {
2006 if (victim->weaponids[victim->weaponstuck] == i) {
2008 Sprite::MakeSprite(cloudimpactsprite, footpoint, footvel, 1, 0, 0, .8, .3);
2009 weapons[i].bloody = 2;
2010 weapons[i].blooddrip = 5;
2011 victim->weaponstuck = -1;
2014 if (victim->num_weapons > 0) {
2015 if (victim->weaponstuck != 0 && victim->weaponstuck != -1)
2016 victim->weaponstuck = 0;
2017 if (victim->weaponids[0] == i)
2018 victim->weaponids[0] = victim->weaponids[victim->num_weapons];
2021 victim->jointVel(abdomen) += relative * 6;
2022 victim->jointVel(neck) += relative * 6;
2023 victim->jointVel(rightshoulder) += relative * 6;
2024 victim->jointVel(leftshoulder) += relative * 6;
2026 weapons[i].owner = id;
2027 if (num_weapons > 0) {
2028 weaponids[num_weapons] = weaponids[0];
2037 if (animCurrent == drawleftanim && animation[animTarget].label[frameCurrent] == 5) {
2038 if (weaponactive == -1)
2040 else if (weaponactive == 0) {
2042 if (num_weapons == 2) {
2044 buffer = weaponids[0];
2045 weaponids[0] = weaponids[1];
2046 weaponids[1] = buffer;
2049 if (weaponactive == -1) {
2050 emit_sound_at(knifesheathesound, coords, 128.);
2052 if (weaponactive != -1) {
2053 emit_sound_at(knifedrawsound, coords, 128.);
2058 if ((animCurrent == walljumprightkickanim && animTarget == walljumprightkickanim) || (animCurrent == walljumpleftkickanim && animTarget == walljumpleftkickanim)) {
2059 XYZ rotatetarget = DoRotation(skeleton.forward, 0, yaw, 0);
2060 Normalise(&rotatetarget);
2061 targetyaw = -asin(0 - rotatetarget.x);
2062 targetyaw *= 360 / 6.28;
2063 if (rotatetarget.z < 0)
2064 targetyaw = 180 - targetyaw;
2066 if (animTarget == walljumprightkickanim)
2068 if (animTarget == walljumpleftkickanim)
2074 if ((animTarget == rabbitrunninganim || animTarget == wolfrunninganim) && frameTarget == 3 && (jumpkeydown || attackkeydown || id != 0))
2077 if (distsq(&victim->coords, &/*player[i].*/coords) < 5 && victim->aitype == gethelptype && (attackkeydown) && !victim->skeleton.free && victim->isRun() && victim->runninghowlong >= 1)
2082 if ((animTarget == rabbitrunninganim || animTarget == wolfrunninganim) && id == 0) {
2083 animTarget = rabbittackleanim;
2085 emit_sound_at(jumpsound, coords);
2093 targetloc = velocity;
2094 Normalise(&targetloc);
2095 targetloc += coords;
2096 for (i = 0; i < numplayers; i++) {
2098 if (distsq(&targetloc, &player[i].coords) < closestdist || closestdist == 0) {
2099 closestdist = distsq(&targetloc, &player[i].coords);
2103 if (closestid != -1)
2104 if (closestdist < 5 && !player[closestid].dead && animation[player[closestid].animTarget].height != lowheight && player[closestid].animTarget != backhandspringanim) {
2106 victim = &player[closestid];
2107 coords = victim->coords;
2108 animCurrent = rabbittacklinganim;
2109 animTarget = rabbittacklinganim;
2113 if (coords.z != victim->coords.z || coords.x != victim->coords.x) {
2114 rotatetarget = coords - victim->coords;
2115 Normalise(&rotatetarget);
2116 targetyaw = -asin(0 - rotatetarget.x);
2117 targetyaw *= 360 / 6.28;
2118 if (rotatetarget.z < 0)
2119 targetyaw = 180 - targetyaw;
2121 if (animTarget != rabbitrunninganim) {
2122 emit_sound_at(jumpsound, coords, 128.);
2128 float damagemult = 1 * power;
2129 if (creature == wolftype)
2130 damagemult = 2.5 * power;
2132 damagemult /= victim->damagetolerance / 200;
2134 //if(onfire)damagemult=3;
2135 if ((animation[animTarget].attack == normalattack || animTarget == walljumprightkickanim || animTarget == walljumpleftkickanim) && (!feint) && (victim->skeleton.free != 2 || animTarget == killanim || animTarget == dropkickanim || animTarget == crouchstabanim || animTarget == swordgroundstabanim || animTarget == staffgroundsmashanim)) {
2136 if (animTarget == spinkickanim && animation[animTarget].label[frameCurrent] == 5) {
2137 if (distsq(&coords, &victim->coords) < (scale * 5) * (scale * 5) * 3 && 3 && animation[victim->animTarget].height != lowheight) {
2141 if (Random() % 2 || creature == wolftype) {
2144 if (creature == wolftype)
2147 if (tutoriallevel != 1) {
2148 emit_sound_at(heavyimpactsound, victim->coords, 128.);
2150 if (creature == wolftype) {
2151 emit_sound_at(clawslicesound, victim->coords, 128.);
2153 victim->DoBloodBig(2 / victim->armorhead, 175);
2157 relative = victim->coords - coords;
2159 Normalise(&relative);
2160 relative = DoRotation(relative, 0, -90, 0);
2161 for (i = 0; i < victim->skeleton.num_joints; i++) {
2162 victim->skeleton.joints[i].velocity += relative * damagemult * 40;
2164 victim->jointVel(head) += relative * damagemult * 200;
2167 victim->DoDamage(damagemult * 100 / victim->protectionhead);
2173 if (animTarget == wolfslapanim && animation[animTarget].label[frameCurrent] == 5) {
2174 if (distsq(&coords, &victim->coords) < (scale * 5) * (scale * 5) * 3 && 3 && animation[victim->animTarget].height != lowheight) {
2178 if (Random() % 2 || creature == wolftype) {
2180 if (creature == wolftype)
2183 emit_sound_at(whooshhitsound, victim->coords);
2184 if (creature == wolftype) {
2185 emit_sound_at(clawslicesound, victim->coords, 128.);
2187 victim->DoBloodBig(2, 175);
2191 relative = victim->coords - coords;
2193 Normalise(&relative);
2195 Normalise(&relative);
2196 relative = DoRotation(relative, 0, 90, 0);
2197 for (i = 0; i < victim->skeleton.num_joints; i++) {
2198 victim->skeleton.joints[i].velocity += relative * damagemult * 20;
2200 victim->jointVel(head) += relative * damagemult * 100;
2203 victim->DoDamage(damagemult * 50 / victim->protectionhead);
2207 if (animTarget == walljumprightkickanim && animation[animTarget].label[frameCurrent] == 5) {
2208 if (distsq(&coords, &victim->coords) < (scale * 5) * (scale * 5) * 3 && animation[victim->animTarget].height != lowheight) {
2214 if (tutoriallevel != 1) {
2215 emit_sound_at(heavyimpactsound, victim->coords, 160.);
2217 if (creature == wolftype) {
2218 emit_sound_at(clawslicesound, victim->coords, 128.);
2220 victim->DoBloodBig(2 / victim->armorhead, 175);
2226 Normalise(&relative);
2227 relative = DoRotation(relative, 0, -90, 0);
2228 for (i = 0; i < victim->skeleton.num_joints; i++) {
2229 victim->skeleton.joints[i].velocity += relative * damagemult * 40;
2231 victim->jointVel(head) += relative * damagemult * 200;
2234 victim->DoDamage(damagemult * 150 / victim->protectionhead);
2236 if (victim->damage > victim->damagetolerance)
2237 award_bonus(id, style);
2243 if (animTarget == walljumpleftkickanim && animation[animTarget].label[frameCurrent] == 5) {
2244 if (distsq(&coords, &victim->coords) < (scale * 5) * (scale * 5) * 3 && animation[victim->animTarget].height != lowheight) {
2250 if (tutoriallevel != 1) {
2251 emit_sound_at(heavyimpactsound, victim->coords, 160.);
2253 if (creature == wolftype) {
2254 emit_sound_at(clawslicesound, victim->coords, 128.);
2256 victim->DoBloodBig(2 / victim->armorhead, 175);
2262 Normalise(&relative);
2263 relative = DoRotation(relative, 0, 90, 0);
2264 for (i = 0; i < victim->skeleton.num_joints; i++) {
2265 victim->skeleton.joints[i].velocity += relative * damagemult * 40;
2267 victim->jointVel(head) += relative * damagemult * 200;
2270 victim->DoDamage(damagemult * 150 / victim->protectionhead);
2272 if (victim->damage > victim->damagetolerance)
2273 award_bonus(id, style);
2279 if (animTarget == blockhighleftstrikeanim && animation[animTarget].label[frameCurrent] == 5) {
2280 if (distsq(&coords, &victim->coords) < (scale * 5) * (scale * 5) * 3 && animation[victim->animTarget].height != lowheight) {
2288 emit_sound_at(whooshhitsound, victim->coords);
2291 relative = victim->coords - coords;
2293 Normalise(&relative);
2294 for (i = 0; i < victim->skeleton.num_joints; i++) {
2295 victim->skeleton.joints[i].velocity += relative * damagemult * 30;
2297 victim->jointVel(head) += relative * damagemult * 100;
2300 victim->DoDamage(damagemult * 50 / victim->protectionhead);
2304 if (animTarget == killanim && animation[animTarget].label[frameCurrent] == 8) {
2305 if (distsq(&coords, &victim->coords) < (scale * 5) * (scale * 5) * 3 && victim->dead) {
2309 emit_sound_at(whooshhitsound, victim->coords, 128.);
2311 victim->skeleton.longdead = 0;
2312 victim->skeleton.free = 1;
2313 victim->skeleton.broken = 0;
2314 victim->skeleton.spinny = 1;
2316 for (i = 0; i < victim->skeleton.num_joints; i++) {
2317 victim->skeleton.joints[i].velchange = 0;
2318 victim->skeleton.joints[i].delay = 0;
2319 victim->skeleton.joints[i].locked = 0;
2320 //victim->skeleton.joints[i].velocity=0;
2326 Normalise(&relative);
2327 for (i = 0; i < victim->skeleton.num_joints; i++) {
2328 victim->skeleton.joints[i].velocity.y = relative.y * 10;
2329 victim->skeleton.joints[i].position.y += relative.y * .3;
2330 victim->skeleton.joints[i].oldposition.y += relative.y * .3;
2331 victim->skeleton.joints[i].realoldposition.y += relative.y * .3;
2333 victim->Puff(abdomen);
2334 victim->jointVel(abdomen).y = relative.y * 400;
2338 if (animTarget == killanim && animation[animTarget].label[frameCurrent] == 5) {
2339 if (distsq(&coords, &victim->coords) < (scale * 5) * (scale * 5) * 9 && victim->dead) {
2343 if (tutoriallevel != 1) {
2344 emit_sound_at(heavyimpactsound, coords, 128.);
2347 relative = victim->coords - coords;
2349 Normalise(&relative);
2350 for (i = 0; i < victim->skeleton.num_joints; i++) {
2351 victim->skeleton.joints[i].velocity += relative * damagemult * 90;
2353 victim->Puff(abdomen);
2354 if (victim->dead != 2 && victim->permanentdamage > victim->damagetolerance - 250 && autoslomo) {
2358 victim->DoDamage(damagemult * 500 / victim->protectionhigh);
2359 victim->jointVel(abdomen) += relative * damagemult * 300;
2363 if (animTarget == dropkickanim && animation[animTarget].label[frameCurrent] == 7) {
2364 if (distsq(&coords, &victim->coords) < (scale * 5) * (scale * 5) * 9 && victim->skeleton.free) {
2368 if (tutoriallevel != 1) {
2369 emit_sound_at(thudsound, coords);
2372 victim->skeleton.longdead = 0;
2373 victim->skeleton.free = 1;
2374 victim->skeleton.broken = 0;
2375 victim->skeleton.spinny = 1;
2377 for (i = 0; i < victim->skeleton.num_joints; i++) {
2378 victim->skeleton.joints[i].velchange = 0;
2379 //victim->skeleton.joints[i].delay=0;
2380 victim->skeleton.joints[i].locked = 0;
2383 relative = victim->coords - coords;
2384 Normalise(&relative);
2386 Normalise(&relative);
2387 for (i = 0; i < victim->skeleton.num_joints; i++) {
2388 victim->skeleton.joints[i].velocity += relative * damagemult * 20;
2393 victim->Puff(abdomen);
2394 victim->DoDamage(damagemult * 20 / victim->protectionhigh);
2395 victim->jointVel(abdomen) += relative * damagemult * 200;
2404 if ((animTarget == crouchstabanim || animTarget == swordgroundstabanim) && animation[animTarget].label[frameCurrent] == 5) {
2405 //if(id==0)camerashake+=.4;
2408 if (!victim->skeleton.free)
2412 terrain.MakeDecal(blooddecalfast, (weapons[weaponids[weaponactive]].tippoint * .8 + weapons[weaponids[weaponactive]].position * .2), .08, .6, Random() % 360);
2413 emit_sound_at(knifesheathesound, coords, 128.);
2416 if (victim && hasvictim) {
2417 if (distsq(&coords, &victim->coords) < (scale * 5) * (scale * 5) * 3) {
2419 XYZ where, startpoint, endpoint, movepoint, colpoint;
2420 float rotationpoint;
2422 if (weapons[weaponids[weaponactive]].getType() == knife) {
2423 where = (weapons[weaponids[weaponactive]].tippoint * .6 + weapons[weaponids[weaponactive]].position * .4);
2424 where -= victim->coords;
2425 if (!victim->skeleton.free)
2426 where = DoRotation(where, 0, -victim->yaw, 0);
2429 startpoint.y += 100;
2433 if (weapons[weaponids[weaponactive]].getType() == sword) {
2434 where = weapons[weaponids[weaponactive]].position;
2435 where -= victim->coords;
2436 if (!victim->skeleton.free)
2437 where = DoRotation(where, 0, -victim->yaw, 0);
2439 where = weapons[weaponids[weaponactive]].tippoint;
2440 where -= victim->coords;
2441 if (!victim->skeleton.free)
2442 where = DoRotation(where, 0, -victim->yaw, 0);
2445 if (weapons[weaponids[weaponactive]].getType() == staff) {
2446 where = weapons[weaponids[weaponactive]].position;
2447 where -= victim->coords;
2448 if (!victim->skeleton.free)
2449 where = DoRotation(where, 0, -victim->yaw, 0);
2451 where = weapons[weaponids[weaponactive]].tippoint;
2452 where -= victim->coords;
2453 if (!victim->skeleton.free)
2454 where = DoRotation(where, 0, -victim->yaw, 0);
2459 whichtri = victim->skeleton.drawmodel.LineCheck(&startpoint, &endpoint, &colpoint, &movepoint, &rotationpoint);
2461 if (whichtri != -1) {
2462 if (victim->dead != 2) {
2463 victim->DoDamage(abs((victim->damagetolerance - victim->permanentdamage) * 2));
2465 award_bonus(id, FinishedBonus);
2468 weapons[weaponids[weaponactive]].bloody = 2;
2470 victim->skeleton.longdead = 0;
2471 victim->skeleton.free = 1;
2472 victim->skeleton.broken = 0;
2474 for (i = 0; i < victim->skeleton.num_joints; i++) {
2475 victim->skeleton.joints[i].velchange = 0;
2476 victim->skeleton.joints[i].locked = 0;
2477 //victim->skeleton.joints[i].velocity=0;
2479 emit_sound_at(fleshstabsound, coords, 128);
2482 if (whichtri != -1 || weapons[weaponids[weaponactive]].bloody) {
2483 weapons[weaponids[weaponactive]].blooddrip += 5;
2484 weapons[weaponids[weaponactive]].blooddripdelay = 0;
2486 if (whichtri == -1) {
2488 emit_sound_at(knifesheathesound, coords, 128.);
2494 if ((animTarget == crouchstabanim || animTarget == swordgroundstabanim) && animation[animTarget].label[frameCurrent] == 6) {
2496 emit_sound_at(knifedrawsound, coords, 128);
2499 if (victim && hasvictim) {
2500 XYZ footvel, footpoint;
2502 emit_sound_at(fleshstabremovesound, coords, 128.);
2505 footpoint = (weapons[weaponids[weaponactive]].tippoint * .8 + weapons[weaponids[weaponactive]].position * .2);
2507 if (weapons[weaponids[weaponactive]].getType() == sword) {
2508 XYZ where, startpoint, endpoint, movepoint;
2509 float rotationpoint;
2512 where = weapons[weaponids[weaponactive]].position;
2513 where -= victim->coords;
2514 if (!victim->skeleton.free)
2515 where = DoRotation(where, 0, -victim->yaw, 0);
2517 where = weapons[weaponids[weaponactive]].tippoint;
2518 where -= victim->coords;
2519 if (!victim->skeleton.free)
2520 where = DoRotation(where, 0, -victim->yaw, 0);
2525 whichtri = victim->skeleton.drawmodel.LineCheck(&startpoint, &endpoint, &footpoint, &movepoint, &rotationpoint);
2526 footpoint += victim->coords;
2528 if (whichtri == -1) {
2529 footpoint = (weapons[weaponids[weaponactive]].tippoint * .8 + weapons[weaponids[weaponactive]].position * .2);
2532 if (weapons[weaponids[weaponactive]].getType() == staff) {
2533 XYZ where, startpoint, endpoint, movepoint;
2534 float rotationpoint;
2537 where = weapons[weaponids[weaponactive]].position;
2538 where -= victim->coords;
2539 if (!victim->skeleton.free)
2540 where = DoRotation(where, 0, -victim->yaw, 0);
2542 where = weapons[weaponids[weaponactive]].tippoint;
2543 where -= victim->coords;
2544 if (!victim->skeleton.free)
2545 where = DoRotation(where, 0, -victim->yaw, 0);
2550 whichtri = victim->skeleton.drawmodel.LineCheck(&startpoint, &endpoint, &footpoint, &movepoint, &rotationpoint);
2551 footpoint += victim->coords;
2553 if (whichtri == -1) {
2554 footpoint = (weapons[weaponids[weaponactive]].tippoint * .8 + weapons[weaponids[weaponactive]].position * .2);
2557 hasvictim = victim->DoBloodBigWhere(2, 220, footpoint);
2559 if (distsq(&coords, &victim->coords) < (scale * 5) * (scale * 5) * 3) {
2560 victim->skeleton.longdead = 0;
2561 victim->skeleton.free = 1;
2562 victim->skeleton.broken = 0;
2564 for (i = 0; i < victim->skeleton.num_joints; i++) {
2565 victim->skeleton.joints[i].velchange = 0;
2566 victim->skeleton.joints[i].locked = 0;
2567 //victim->skeleton.joints[i].velocity=0;
2573 Normalise(&relative);
2574 //victim->Puff(abdomen);
2576 Sprite::MakeSprite(cloudimpactsprite, footpoint, footvel, 1, 0, 0, .8, .3);
2578 if (victim->bloodloss < victim->damagetolerance) {
2579 victim->bloodloss += 1000;
2583 victim->jointVel(abdomen) += relative * damagemult * 20;
2587 if (!hasvictim && onterrain) {
2588 weapons[weaponids[weaponactive]].bloody = 0;
2589 weapons[weaponids[weaponactive]].blooddrip = 0;
2593 if (animTarget == upunchanim && animation[animTarget].label[frameCurrent] == 5) {
2594 if (distsq(&coords, &victim->coords) < (scale * 5) * (scale * 5) * 3) {
2602 if (tutoriallevel != 1) {
2603 emit_sound_at(heavyimpactsound, victim->coords, 128);
2608 relative = victim->coords - coords;
2610 Normalise(&relative);
2611 for (i = 0; i < victim->skeleton.num_joints; i++) {
2612 victim->skeleton.joints[i].velocity = relative * 30;
2614 victim->jointVel(head) += relative * damagemult * 150;
2616 victim->frameTarget = 0;
2617 victim->animTarget = staggerbackhardanim;
2618 victim->targetyaw = targetyaw + 180;
2620 victim->stunned = 1;
2623 victim->Puff(abdomen);
2624 victim->DoDamage(damagemult * 60 / victim->protectionhigh);
2631 if (animTarget == winduppunchanim && animation[animTarget].label[frameCurrent] == 5) {
2632 if (distsq(&coords, &victim->coords) < (scale * 5) * (scale * 5) * 2) {
2636 if (victim->damage <= victim->damagetolerance - 60 && normaldotproduct(victim->facing, victim->coords - coords) < (scale * 5) * (scale * 5) * 0 && animation[victim->animTarget].height != lowheight) {
2637 if (tutoriallevel != 1) {
2638 emit_sound_at(thudsound, victim->coords);
2640 } else if (victim->damage <= victim->damagetolerance - 60 && normaldotproduct(victim->facing, victim->coords - coords) < (scale * 5) * (scale * 5) * 0 && animation[victim->animTarget].height == lowheight) {
2641 if (tutoriallevel != 1) {
2642 emit_sound_at(whooshhitsound, victim->coords);
2645 if (tutoriallevel != 1) {
2646 emit_sound_at(heavyimpactsound, victim->coords);
2650 if (victim->damage > victim->damagetolerance - 60 || normaldotproduct(victim->facing, victim->coords - coords) > 0 || animation[victim->animTarget].height == lowheight)
2653 relative = victim->coords - coords;
2655 Normalise(&relative);
2657 Normalise(&relative);
2658 for (i = 0; i < victim->skeleton.num_joints; i++) {
2659 victim->skeleton.joints[i].velocity = relative * 5;
2661 victim->jointVel(abdomen) += relative * damagemult * 400;
2663 victim->frameTarget = 0;
2664 victim->animTarget = staggerbackhardanim;
2665 victim->targetyaw = targetyaw + 180;
2667 victim->stunned = 1;
2669 victim->Puff(abdomen);
2670 victim->DoDamage(damagemult * 60 / victim->protectionhigh);
2676 if (animTarget == blockhighleftanim && animation[animTarget].label[frameCurrent] == 5) {
2677 if (distsq(&coords, &victim->coords) < (scale * 5) * (scale * 5) * 4) {
2678 if (victim->id == 0)
2680 emit_sound_at(landsound2, victim->coords);
2686 if (animTarget == swordslashparryanim && animation[animTarget].label[frameCurrent] == 5) {
2687 if (distsq(&coords, &victim->coords) < (scale * 5) * (scale * 5) * 4) {
2688 if (victim->id == 0)
2691 if (weaponactive != -1) {
2692 if (weapons[victim->weaponids[0]].getType() == staff || weapons[weaponids[0]].getType() == staff) {
2693 if (weapons[victim->weaponids[0]].getType() == staff)
2694 weapons[victim->weaponids[0]].damage += .2 + float(abs(Random() % 100) - 50) / 250;
2695 if (weapons[weaponids[0]].getType() == staff)
2696 weapons[weaponids[0]].damage += .2 + float(abs(Random() % 100) - 50) / 250;
2698 emit_sound_at(swordstaffsound, victim->coords);
2700 emit_sound_at(metalhitsound, victim->coords);
2708 if (animTarget == knifethrowanim && animation[animTarget].label[frameCurrent] == 5) {
2709 if (weaponactive != -1) {
2712 weapons[weaponids[0]].owner = -1;
2713 aim = victim->coords + DoRotation(victim->jointPos(abdomen), 0, victim->yaw, 0) * victim->scale + victim->velocity * findDistance(&victim->coords, &coords) / 50 - (coords + DoRotation(jointPos(righthand), 0, yaw, 0) * scale);
2715 /*if(victim->animTarget==jumpupanim||victim->animTarget==jumpdownanim){
2716 aim=DoRotation(aim,(float)abs(Random()%15)-7,(float)abs(Random()%15)-7,0);
2718 weapons[weaponids[0]].velocity = aim * 50;
2719 weapons[weaponids[0]].tipvelocity = aim * 50;
2720 weapons[weaponids[0]].missed = 0;
2721 weapons[weaponids[0]].hitsomething = 0;
2722 weapons[weaponids[0]].freetime = 0;
2723 weapons[weaponids[0]].firstfree = 1;
2724 weapons[weaponids[0]].physics = 0;
2727 weaponids[0] = weaponids[num_weapons];
2733 if (animTarget == knifeslashstartanim && animation[animTarget].label[frameCurrent] == 5) {
2735 if (distsq(&coords, &victim->coords) < (scale * 5) * (scale * 5) * 4.5 &&/*animation[victim->animTarget].height!=lowheight&&*/victim->animTarget != dodgebackanim && victim->animTarget != rollanim) {
2737 if (tutoriallevel != 1)
2738 victim->DoBloodBig(1.5 / victim->armorhigh, 225);
2740 award_bonus(id, Slicebonus);
2741 if (tutoriallevel != 1) {
2742 emit_sound_at(knifeslicesound, victim->coords);
2744 //victim->jointVel(abdomen)+=relative*damagemult*200;
2745 if (animation[victim->animTarget].attack && (victim->aitype != playercontrolled || victim->animTarget == knifeslashstartanim) && (victim->creature == rabbittype || victim->deathbleeding <= 0)) {
2746 if (victim->id != 0 || difficulty == 2) {
2747 victim->frameTarget = 0;
2748 victim->animTarget = staggerbackhardanim;
2749 victim->targetyaw = targetyaw + 180;
2753 victim->lowreversaldelay = 0;
2754 victim->highreversaldelay = 0;
2755 if (aitype != playercontrolled)
2756 weaponmissdelay = .6;
2758 if (tutoriallevel != 1)
2759 if (bloodtoggle && !weapons[weaponids[weaponactive]].bloody)
2760 weapons[weaponids[weaponactive]].bloody = 1;
2761 if (tutoriallevel != 1)
2762 weapons[weaponids[weaponactive]].blooddrip += 3;
2764 XYZ footvel, footpoint;
2766 if (skeleton.free) {
2767 footpoint = (victim->jointPos(abdomen) + victim->jointPos(neck)) / 2 * victim->scale + victim->coords;
2769 if (!skeleton.free) {
2770 footpoint = DoRotation((victim->jointPos(abdomen) + victim->jointPos(neck)) / 2, 0, victim->yaw, 0) * victim->scale + victim->coords;
2772 if (tutoriallevel != 1) {
2774 Sprite::MakeSprite(cloudimpactsprite, footpoint, footvel, 1, 0, 0, .6, .3);
2775 footvel = DoRotation(facing, 0, 90, 0) * .8;
2777 Sprite::MakeSprite(bloodsprite, footpoint, DoRotation(footvel * 7, (float)(Random() % 20), (float)(Random() % 20), 0), 1, 1, 1, .05, .9);
2778 Sprite::MakeSprite(bloodsprite, footpoint, DoRotation(footvel * 3, (float)(Random() % 20), (float)(Random() % 20), 0), 1, 1, 1, .05, .9);
2779 Sprite::MakeSprite(bloodflamesprite, footpoint, footvel * 5, 1, 1, 1, .2, 1);
2780 Sprite::MakeSprite(bloodflamesprite, footpoint, footvel * 2, 1, 1, 1, .2, 1);
2782 if (tutoriallevel == 1) {
2783 Sprite::MakeSprite(cloudimpactsprite, footpoint, footvel, 1, 1, 1, .6, .3);
2785 victim->DoDamage(damagemult * 0);
2788 if (animTarget == swordslashanim && animation[animTarget].label[frameCurrent] == 5 && victim->animTarget != rollanim) {
2789 if (distsq(&coords, &victim->coords) < (scale * 5) * (scale * 5) * 6.5 && victim->animTarget != dodgebackanim) {
2790 if (victim->weaponactive == -1 || normaldotproduct(victim->facing, victim->coords - coords) > 0 || (Random() % 2 == 0)) {
2791 award_bonus(id, Slashbonus);
2793 if (tutoriallevel != 1) {
2794 if (normaldotproduct(victim->facing, victim->coords - coords) < 0)
2795 victim->DoBloodBig(2 / victim->armorhigh, 190);
2797 victim->DoBloodBig(2 / victim->armorhigh, 185);
2798 victim->deathbleeding = 1;
2799 emit_sound_at(swordslicesound, victim->coords);
2801 //victim->jointVel(abdomen)+=relative*damagemult*200;
2802 if (tutoriallevel != 1) {
2803 victim->frameTarget = 0;
2804 victim->animTarget = staggerbackhardanim;
2805 victim->targetyaw = targetyaw + 180;
2809 if (tutoriallevel != 1) {
2810 if (bloodtoggle && !weapons[weaponids[weaponactive]].bloody)
2811 weapons[weaponids[weaponactive]].bloody = 1;
2812 weapons[weaponids[weaponactive]].blooddrip += 3;
2814 float bloodlossamount;
2815 bloodlossamount = 200 + abs((float)(Random() % 40)) - 20;
2816 victim->bloodloss += bloodlossamount / victim->armorhigh;
2817 //victim->bloodloss+=100*(6.5-distsq(&coords,&victim->coords));
2818 victim->DoDamage(damagemult * 0);
2820 XYZ footvel, footpoint;
2822 if (skeleton.free) {
2823 footpoint = (victim->jointPos(abdomen) + victim->jointPos(neck)) / 2 * victim->scale + victim->coords;
2825 if (!skeleton.free) {
2826 footpoint = DoRotation((victim->jointPos(abdomen) + victim->jointPos(neck)) / 2, 0, victim->yaw, 0) * victim->scale + victim->coords;
2829 Sprite::MakeSprite(cloudimpactsprite, footpoint, footvel, 1, 0, 0, .9, .3);
2830 footvel = DoRotation(facing, 0, 90, 0) * .8;
2832 Sprite::MakeSprite(bloodsprite, footpoint, DoRotation(footvel * 7, (float)(Random() % 20), (float)(Random() % 20), 0), 1, 1, 1, .05, .9);
2833 Sprite::MakeSprite(bloodsprite, footpoint, DoRotation(footvel * 3, (float)(Random() % 20), (float)(Random() % 20), 0), 1, 1, 1, .05, .9);
2834 Sprite::MakeSprite(bloodflamesprite, footpoint, footvel * 5, 1, 1, 1, .3, 1);
2835 Sprite::MakeSprite(bloodflamesprite, footpoint, footvel * 2, 1, 1, 1, .3, 1);
2838 if (victim->weaponactive != -1) {
2839 if (weapons[victim->weaponids[0]].getType() == staff || weapons[weaponids[0]].getType() == staff) {
2840 if (weapons[victim->weaponids[0]].getType() == staff)
2841 weapons[victim->weaponids[0]].damage += .2 + float(abs(Random() % 100) - 50) / 250;
2842 if (weapons[weaponids[0]].getType() == staff)
2843 weapons[weaponids[0]].damage += .2 + float(abs(Random() % 100) - 50) / 250;
2845 emit_sound_at(swordstaffsound, victim->coords);
2847 emit_sound_at(metalhitsound, victim->coords);
2853 victim->Puff(righthand);
2855 victim->frameTarget = 0;
2856 victim->animTarget = staggerbackhighanim;
2857 victim->targetyaw = targetyaw + 180;
2859 weapons[victim->weaponids[0]].owner = -1;
2860 aim = DoRotation(facing, 0, 90, 0) * 21;
2862 weapons[victim->weaponids[0]].velocity = aim * -.2;
2863 weapons[victim->weaponids[0]].tipvelocity = aim;
2864 weapons[victim->weaponids[0]].missed = 1;
2865 weapons[weaponids[0]].hitsomething = 0;
2866 weapons[victim->weaponids[0]].freetime = 0;
2867 weapons[victim->weaponids[0]].firstfree = 1;
2868 weapons[victim->weaponids[0]].physics = 1;
2869 victim->num_weapons--;
2870 if (victim->num_weapons) {
2871 victim->weaponids[0] = victim->weaponids[num_weapons];
2872 if (victim->weaponstuck == victim->num_weapons)
2873 victim->weaponstuck = 0;
2875 victim->weaponactive = -1;
2876 for (i = 0; i < numplayers; i++) {
2877 player[i].wentforweapon = 0;
2884 if (animTarget == staffhitanim && animation[animTarget].label[frameCurrent] == 5 && victim->animTarget != rollanim) {
2885 if (distsq(&coords, &victim->coords) < (scale * 5) * (scale * 5) * 6.5 && victim->animTarget != dodgebackanim && victim->animTarget != sweepanim) {
2886 if (tutoriallevel != 1) {
2887 weapons[weaponids[0]].damage += .4 + float(abs(Random() % 100) - 50) / 250;
2891 if (Random() % 2 || creature == wolftype) {
2894 emit_sound_at(staffheadsound, victim->coords);
2898 relative = victim->coords - coords;
2900 Normalise(&relative);
2901 relative = DoRotation(relative, 0, 90, 0);
2903 Normalise(&relative);
2904 for (i = 0; i < victim->skeleton.num_joints; i++) {
2905 victim->skeleton.joints[i].velocity += relative * damagemult * 60;
2907 victim->jointVel(head) += relative * damagemult * 230;
2908 victim->jointVel(neck) += relative * damagemult * 230;
2911 if (tutoriallevel != 1) {
2912 victim->DoDamage(damagemult * 120 / victim->protectionhigh);
2914 award_bonus(id, solidhit, 30);
2919 if (animTarget == staffspinhitanim && animation[animTarget].label[frameCurrent] == 5 && victim->animTarget != rollanim) {
2920 if (distsq(&coords, &victim->coords) < (scale * 5) * (scale * 5) * 6.5 && victim->animTarget != dodgebackanim && victim->animTarget != sweepanim) {
2921 if (tutoriallevel != 1) {
2922 weapons[weaponids[0]].damage += .6 + float(abs(Random() % 100) - 50) / 250;
2926 if (Random() % 2 || creature == wolftype) {
2929 emit_sound_at(staffheadsound, victim->coords);
2933 relative = victim->coords - coords;
2935 Normalise(&relative);
2936 relative = DoRotation(relative, 0, -90, 0);
2937 for (i = 0; i < victim->skeleton.num_joints; i++) {
2938 victim->skeleton.joints[i].velocity += relative * damagemult * 40;
2940 victim->jointVel(head) += relative * damagemult * 220;
2941 victim->jointVel(neck) += relative * damagemult * 220;
2944 if (tutoriallevel != 1) {
2945 victim->DoDamage(damagemult * 350 / victim->protectionhead);
2947 award_bonus(id, solidhit, 60);
2952 if (animTarget == staffgroundsmashanim && animation[animTarget].label[frameCurrent] == 5) {
2953 if (distsq(&coords, &victim->coords) < (scale * 5) * (scale * 5) * 6.5) {
2955 if (tutoriallevel != 1) {
2957 weapons[weaponids[0]].damage += .4 + float(abs(Random() % 100) - 50) / 500;
2960 if (Random() % 2 || creature == wolftype) {
2963 emit_sound_at(staffbodysound, victim->coords);
2965 victim->skeleton.longdead = 0;
2966 victim->skeleton.free = 1;
2967 victim->skeleton.broken = 0;
2969 for (i = 0; i < victim->skeleton.num_joints; i++) {
2970 victim->skeleton.joints[i].velchange = 0;
2971 victim->skeleton.joints[i].locked = 0;
2972 //victim->skeleton.joints[i].velocity=0;
2978 /*relative=victim->coords-coords;
2980 Normalise(&relative);
2981 relative=DoRotation(relative,0,90,0);*/
2983 Normalise(&relative);
2984 if (!victim->dead) {
2985 for (i = 0; i < victim->skeleton.num_joints; i++) {
2986 victim->skeleton.joints[i].velocity = relative * damagemult * 40;
2989 victim->jointVel(abdomen) += relative * damagemult * 40;
2992 for (i = 0; i < victim->skeleton.num_joints; i++) {
2993 victim->skeleton.joints[i].velocity = relative * damagemult * abs(Random() % 20);
2996 //victim->jointVel(abdomen)+=relative*damagemult*20;
2998 victim->Puff(abdomen);
2999 if (tutoriallevel != 1) {
3000 victim->DoDamage(damagemult * 100 / victim->protectionhigh);
3002 if (!victim->dead) {
3003 award_bonus(id, solidhit, 40);
3009 if (animTarget == lowkickanim && animation[animTarget].label[frameCurrent] == 5) {
3010 if (distsq(&coords, &victim->coords) < (scale * 5) * (scale * 5) * 3 && animation[victim->animTarget].height != highheight) {
3015 relative = victim->coords - coords;
3017 Normalise(&relative);
3021 if (animation[victim->animTarget].height == lowheight) {
3027 for (i = 0; i < victim->skeleton.num_joints; i++) {
3028 victim->skeleton.joints[i].velocity += relative * damagemult * 40;
3030 victim->jointVel(head) += relative * damagemult * 200;
3031 if (tutoriallevel != 1) {
3032 emit_sound_at(heavyimpactsound, victim->coords, 128.);
3035 victim->DoDamage(damagemult * 100 / victim->protectionhead);
3036 if (victim->howactive == typesleeping)
3037 victim->DoDamage(damagemult * 150 / victim->protectionhead);
3038 if (creature == wolftype) {
3039 emit_sound_at(clawslicesound, victim->coords, 128.);
3041 victim->DoBloodBig(2 / victim->armorhead, 175);
3044 if (victim->damage >= victim->damagetolerance)
3046 for (i = 0; i < victim->skeleton.num_joints; i++) {
3047 victim->skeleton.joints[i].velocity += relative * damagemult * 10;
3049 victim->jointVel(abdomen) += relative * damagemult * 200;
3050 victim->frameTarget = 0;
3051 victim->animTarget = staggerbackhighanim;
3052 victim->targetyaw = targetyaw + 180;
3054 if (tutoriallevel != 1) {
3055 emit_sound_at(landsound2, victim->coords, 128.);
3057 victim->Puff(abdomen);
3058 victim->DoDamage(damagemult * 30 / victim->protectionhigh);
3059 if (creature == wolftype) {
3060 emit_sound_at(clawslicesound, victim->coords, 128.);
3062 victim->DoBloodBig(2 / victim->armorhigh, 170);
3069 if (animTarget == sweepanim && animation[animTarget].label[frameCurrent] == 5) {
3070 if (victim->animTarget != jumpupanim && distsq(&coords, &victim->coords) < (scale * 5) * (scale * 5) * 3 && victim != this) {
3074 if (tutoriallevel != 1) {
3075 emit_sound_at(landsound2, victim->coords, 128.);
3078 relative = victim->coords - coords;
3080 Normalise(&relative);
3082 if (animation[victim->animTarget].height == middleheight || animation[victim->animCurrent].height == middleheight || victim->damage >= victim->damagetolerance - 40) {
3085 for (i = 0; i < victim->skeleton.num_joints; i++) {
3086 victim->skeleton.joints[i].velocity += relative * damagemult * 15;
3088 relative = DoRotation(relative, 0, -90, 0);
3090 for (i = 0; i < victim->skeleton.num_joints; i++) {
3091 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)
3092 victim->skeleton.joints[i].velocity = relative * 80;
3094 victim->Puff(rightankle);
3095 victim->Puff(leftankle);
3096 victim->DoDamage(damagemult * 40 / victim->protectionlow);
3098 if (victim->damage >= victim->damagetolerance)
3100 for (i = 0; i < victim->skeleton.num_joints; i++) {
3101 victim->skeleton.joints[i].velocity += relative * damagemult * 10;
3103 relative = DoRotation(relative, 0, -90, 0);
3104 for (i = 0; i < victim->skeleton.num_joints; i++) {
3105 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)
3106 victim->skeleton.joints[i].velocity += relative * damagemult * 80;
3108 victim->jointVel(abdomen) += relative * damagemult * 200;
3109 victim->frameTarget = 0;
3110 victim->animTarget = staggerbackhighanim;
3111 victim->targetyaw = targetyaw + 180;
3113 if (tutoriallevel != 1) {
3114 emit_sound_at(landsound2, victim->coords, 128.);
3116 victim->Puff(abdomen);
3117 victim->DoDamage(damagemult * 30 / victim->protectionlow);
3125 if (animation[animTarget].attack == reversal && (!victim->feint || (victim->lastattack == victim->lastattack2 && victim->lastattack2 == victim->lastattack3 && Random() % 2) || animTarget == knifefollowanim)) {
3126 if (animTarget == spinkickreversalanim && animation[animTarget].label[frameCurrent] == 7) {
3134 if (tutoriallevel != 1) {
3135 emit_sound_at(heavyimpactsound, victim->coords, 128.);
3137 if (creature == wolftype) {
3138 emit_sound_at(clawslicesound, victim->coords, 128);
3140 victim->DoBloodBig(2 / victim->armorhigh, 170);
3144 relative = victim->coords - oldcoords;
3146 Normalise(&relative);
3147 //relative=DoRotation(relative,0,-90,0);
3148 for (i = 0; i < victim->skeleton.num_joints; i++) {
3149 victim->skeleton.joints[i].velocity += relative * damagemult * 40;
3151 victim->jointVel(abdomen) += relative * damagemult * 200;
3153 victim->Puff(abdomen);
3154 victim->DoDamage(damagemult * 150 / victim->protectionhigh);
3156 award_bonus(id, Reversal);
3159 if ((animTarget == swordslashreversalanim || animTarget == knifeslashreversalanim || animTarget == staffhitreversalanim || animTarget == staffspinhitreversalanim) && animation[animTarget].label[frameCurrent] == 5) {
3160 if (victim->weaponactive != -1 && victim->num_weapons > 0) {
3161 if (weapons[victim->weaponids[victim->weaponactive]].owner == victim->id) {
3162 weapons[victim->weaponids[victim->weaponactive]].owner = id;
3164 if (num_weapons > 0) {
3165 weaponids[num_weapons] = weaponids[victim->weaponactive];
3168 weaponids[0] = victim->weaponids[victim->weaponactive];
3169 victim->num_weapons--;
3170 if (victim->num_weapons > 0) {
3171 victim->weaponids[victim->weaponactive] = victim->weaponids[victim->num_weapons];
3172 //if(victim->weaponstuck==victim->num_weapons)victim->weaponstuck=0;
3174 victim->weaponactive = -1;
3179 if (animTarget == staffhitreversalanim && animation[animTarget].label[frameCurrent] == 5) {
3187 emit_sound_at(whooshhitsound, victim->coords, 128.);
3190 relative = victim->coords - oldcoords;
3192 Normalise(&relative);
3193 //relative=DoRotation(relative,0,-90,0);
3194 for (i = 0; i < victim->skeleton.num_joints; i++) {
3195 victim->skeleton.joints[i].velocity += relative * damagemult * 30;
3197 victim->jointVel(abdomen) += relative * damagemult * 200;
3200 victim->DoDamage(damagemult * 70 / victim->protectionhigh);
3203 if (animTarget == staffspinhitreversalanim && animation[animTarget].label[frameCurrent] == 7) {
3212 award_bonus(id, staffreversebonus);
3214 if (tutoriallevel != 1) {
3215 emit_sound_at(heavyimpactsound, victim->coords, 128.);
3218 award_bonus(id, staffreversebonus); // Huh, again?
3221 relative = victim->coords - oldcoords;
3223 Normalise(&relative);
3224 //relative=DoRotation(relative,0,-90,0);
3225 for (i = 0; i < victim->skeleton.num_joints; i++) {
3226 victim->skeleton.joints[i].velocity += relative * damagemult * 30;
3228 victim->jointVel(abdomen) += relative * damagemult * 200;
3231 victim->DoDamage(damagemult * 70 / victim->protectionhigh);
3234 if (animTarget == upunchreversalanim && animation[animTarget].label[frameCurrent] == 7) {
3240 Normalise(&relative);
3243 for (i = 0; i < victim->skeleton.num_joints; i++) {
3244 victim->skeleton.joints[i].velocity += relative * damagemult * 70;
3246 victim->jointVel(lefthand) *= .1;
3247 victim->jointVel(leftwrist) *= .2;
3248 victim->jointVel(leftelbow) *= .5;
3249 victim->jointVel(leftshoulder) *= .7;
3250 victim->jointVel(righthand) *= .1;
3251 victim->jointVel(rightwrist) *= .2;
3252 victim->jointVel(rightelbow) *= .5;
3253 victim->jointVel(rightshoulder) *= .7;
3255 victim->Puff(abdomen);
3256 victim->DoDamage(damagemult * 90 / victim->protectionhigh);
3258 award_bonus(id, Reversal);
3262 if (weaponactive != -1 || creature == wolftype)
3264 if (creature == rabbittype && weaponactive != -1)
3265 if (weapons[weaponids[0]].getType() == staff)
3268 if (weaponactive != -1) {
3269 victim->DoBloodBig(2 / victim->armorhigh, 225);
3270 emit_sound_at(knifeslicesound, victim->coords);
3271 if (bloodtoggle && !weapons[weaponids[weaponactive]].bloody)
3272 weapons[weaponids[weaponactive]].bloody = 1;
3273 weapons[weaponids[weaponactive]].blooddrip += 3;
3275 if (weaponactive == -1 && creature == wolftype) {
3277 emit_sound_at(clawslicesound, victim->coords, 128.);
3279 victim->DoBloodBig(2 / victim->armorhigh, 175);
3286 if (animTarget == swordslashreversalanim && animation[animTarget].label[frameCurrent] == 7) {
3292 Normalise(&relative);
3295 for (i = 0; i < victim->skeleton.num_joints; i++) {
3296 victim->skeleton.joints[i].velocity += relative * damagemult * 70;
3298 victim->jointVel(lefthand) *= .1 - 1;
3299 victim->jointVel(leftwrist) *= .2 - 1;
3300 victim->jointVel(leftelbow) *= .5 - 1;
3301 victim->jointVel(leftshoulder) *= .7 - 1;
3302 victim->jointVel(righthand) *= .1 - 1;
3303 victim->jointVel(rightwrist) *= .2 - 1;
3304 victim->jointVel(rightelbow) *= .5 - 1;
3305 victim->jointVel(rightshoulder) *= .7 - 1;
3307 award_bonus(id, swordreversebonus);
3310 if (hasvictim && animTarget == knifeslashreversalanim && animation[animTarget].label[frameCurrent] == 7) {
3318 if (tutoriallevel != 1) {
3319 emit_sound_at(heavyimpactsound, victim->coords, 128.);
3323 relative = victim->coords - oldcoords;
3325 Normalise(&relative);
3326 relative = DoRotation(relative, 0, -90, 0);
3327 for (i = 0; i < victim->skeleton.num_joints; i++) {
3328 victim->skeleton.joints[i].velocity += relative * damagemult * 40;
3330 victim->jointVel(abdomen) += relative * damagemult * 200;
3332 victim->Puff(abdomen);
3333 victim->DoDamage(damagemult * 30 / victim->protectionhigh);
3335 award_bonus(id, Reversal);
3338 if (hasvictim && animTarget == sneakattackanim && animation[animTarget].label[frameCurrent] == 7) {
3341 victim->skeleton.spinny = 0;
3343 relative = facing * -1;
3345 Normalise(&relative);
3346 if (victim->id == 0)
3348 for (i = 0; i < victim->skeleton.num_joints; i++) {
3349 victim->skeleton.joints[i].velocity += relative * damagemult * 40;
3351 //victim->DoDamage(1000);
3352 victim->damage = victim->damagetolerance;
3353 victim->permanentdamage = victim->damagetolerance - 1;
3356 if (weaponactive != -1 || creature == wolftype)
3358 if (creature == rabbittype && weaponactive != -1)
3359 if (weapons[weaponids[0]].getType() == staff)
3362 if (weaponactive != -1) {
3363 victim->DoBloodBig(200, 225);
3364 emit_sound_at(knifeslicesound, victim->coords);
3366 weapons[weaponids[weaponactive]].bloody = 2;
3367 weapons[weaponids[weaponactive]].blooddrip += 5;
3370 if (creature == wolftype && weaponactive == -1) {
3371 emit_sound_at(clawslicesound, victim->coords, 128.);
3373 victim->DoBloodBig(2, 175);
3376 award_bonus(id, spinecrusher);
3379 if (hasvictim && (animTarget == knifefollowanim || animTarget == knifesneakattackanim) && animation[animTarget].label[frameCurrent] == 5) {
3380 if (weaponactive != -1 && victim->bloodloss < victim->damagetolerance) {
3382 if (animTarget == knifefollowanim)
3383 victim->DoBloodBig(200, 210);
3384 if (animTarget == knifesneakattackanim) {
3385 /*victim->DoBloodBig(200,195);
3390 bloodvel=DoRotation(bloodvel,((float)(Random()%100))/4,yaw+((float)(Random()%100))/4,0)*scale;
3391 Sprite::MakeSprite(bloodsprite, DoRotation(jointPos(neck),0,yaw,0)*scale+coords,bloodvel, 1,1,1, .05, 1);
3393 XYZ footvel, footpoint;
3395 footpoint = weapons[weaponids[0]].tippoint;
3397 Sprite::MakeSprite(cloudimpactsprite, footpoint, footvel, 1, 0, 0, .9, .3);
3398 footvel = (weapons[weaponids[0]].tippoint - weapons[weaponids[0]].position);
3399 Sprite::MakeSprite(bloodsprite, footpoint, DoRotation(footvel * 7, (float)(Random() % 20), (float)(Random() % 20), 0), 1, 1, 1, .05, .9);
3400 Sprite::MakeSprite(bloodsprite, footpoint, DoRotation(footvel * 3, (float)(Random() % 20), (float)(Random() % 20), 0), 1, 1, 1, .05, .9);
3401 Sprite::MakeSprite(bloodflamesprite, footpoint, footvel * 5, 1, 1, 1, .3, 1);
3402 Sprite::MakeSprite(bloodflamesprite, footpoint, footvel * 2, 1, 1, 1, .3, 1);
3403 victim->DoBloodBig(200, 195);
3404 award_bonus(id, tracheotomy);
3406 if (animTarget == knifefollowanim) {
3407 award_bonus(id, Stabbonus);
3408 XYZ footvel, footpoint;
3410 footpoint = weapons[weaponids[0]].tippoint;
3412 Sprite::MakeSprite(cloudimpactsprite, footpoint, footvel, 1, 0, 0, .9, .3);
3413 footvel = (weapons[weaponids[0]].tippoint - weapons[weaponids[0]].position) * -1;
3414 Sprite::MakeSprite(bloodsprite, footpoint, DoRotation(footvel * 7, (float)(Random() % 20), (float)(Random() % 20), 0), 1, 1, 1, .05, .9);
3415 Sprite::MakeSprite(bloodsprite, footpoint, DoRotation(footvel * 3, (float)(Random() % 20), (float)(Random() % 20), 0), 1, 1, 1, .05, .9);
3416 Sprite::MakeSprite(bloodflamesprite, footpoint, footvel * 5, 1, 1, 1, .2, 1);
3417 Sprite::MakeSprite(bloodflamesprite, footpoint, footvel * 2, 1, 1, 1, .2, 1);
3420 victim->bloodloss += 10000;
3421 victim->velocity = 0;
3422 emit_sound_at(fleshstabsound, victim->coords);
3424 weapons[weaponids[weaponactive]].bloody = 2;
3425 weapons[weaponids[weaponactive]].blooddrip += 5;
3429 if (hasvictim && (animTarget == knifefollowanim || animTarget == knifesneakattackanim) && animation[animTarget].label[frameCurrent] == 6) {
3431 victim->velocity = 0;
3432 for (i = 0; i < victim->skeleton.num_joints; i++) {
3433 victim->skeleton.joints[i].velocity = 0;
3435 if (animTarget == knifefollowanim) {
3437 for (i = 0; i < victim->skeleton.num_joints; i++) {
3438 victim->skeleton.joints[i].velocity = 0;
3441 if (weaponactive != -1 && animation[victim->animTarget].attack != reversal) {
3442 emit_sound_at(fleshstabremovesound, victim->coords);
3444 weapons[weaponids[weaponactive]].bloody = 2;
3445 weapons[weaponids[weaponactive]].blooddrip += 5;
3447 XYZ footvel, footpoint;
3449 footpoint = weapons[weaponids[0]].tippoint;
3451 Sprite::MakeSprite(cloudimpactsprite, footpoint, footvel, 1, 0, 0, .9, .3);
3452 footvel = (weapons[weaponids[0]].tippoint - weapons[weaponids[0]].position) * -1;
3453 Sprite::MakeSprite(bloodsprite, footpoint, DoRotation(footvel * 7, (float)(Random() % 20), (float)(Random() % 20), 0), 1, 1, 1, .05, .9);
3454 Sprite::MakeSprite(bloodsprite, footpoint, DoRotation(footvel * 3, (float)(Random() % 20), (float)(Random() % 20), 0), 1, 1, 1, .05, .9);
3455 Sprite::MakeSprite(bloodflamesprite, footpoint, footvel * 5, 1, 1, 1, .3, 1);
3456 Sprite::MakeSprite(bloodflamesprite, footpoint, footvel * 2, 1, 1, 1, .3, 1);
3460 if (hasvictim && (animTarget == swordsneakattackanim) && animation[animTarget].label[frameCurrent] == 5) {
3461 if (weaponactive != -1 && victim->bloodloss < victim->damagetolerance) {
3462 award_bonus(id, backstab);
3466 XYZ footvel, footpoint;
3468 footpoint = (weapons[weaponids[0]].tippoint + weapons[weaponids[0]].position) / 2;
3470 Sprite::MakeSprite(cloudimpactsprite, footpoint, footvel, 1, 0, 0, .9, .3);
3471 footvel = (weapons[weaponids[0]].tippoint - weapons[weaponids[0]].position);
3472 Sprite::MakeSprite(bloodsprite, footpoint, DoRotation(footvel * 7, (float)(Random() % 20), (float)(Random() % 20), 0), 1, 1, 1, .05, .9);
3473 Sprite::MakeSprite(bloodsprite, footpoint, DoRotation(footvel * 3, (float)(Random() % 20), (float)(Random() % 20), 0), 1, 1, 1, .05, .9);
3474 Sprite::MakeSprite(bloodflamesprite, footpoint, DoRotation(footvel * 5, (float)(Random() % 20), (float)(Random() % 20), 0), 1, 1, 1, .3, 1);
3475 Sprite::MakeSprite(bloodflamesprite, footpoint, DoRotation(footvel * 3, (float)(Random() % 20), (float)(Random() % 20), 0), 1, 1, 1, .3, 1);
3476 victim->DoBloodBig(200, 180);
3477 victim->DoBloodBig(200, 215);
3478 victim->bloodloss += 10000;
3479 victim->velocity = 0;
3480 emit_sound_at(fleshstabsound, victim->coords);
3482 weapons[weaponids[weaponactive]].bloody = 2;
3483 weapons[weaponids[weaponactive]].blooddrip += 5;
3487 if (hasvictim && animTarget == swordsneakattackanim && animation[animTarget].label[frameCurrent] == 6) {
3489 victim->velocity = 0;
3490 for (i = 0; i < victim->skeleton.num_joints; i++) {
3491 victim->skeleton.joints[i].velocity = 0;
3493 if (weaponactive != -1) {
3494 emit_sound_at(fleshstabremovesound, victim->coords);
3496 weapons[weaponids[weaponactive]].bloody = 2;
3497 weapons[weaponids[weaponactive]].blooddrip += 5;
3499 XYZ footvel, footpoint;
3501 footpoint = weapons[weaponids[0]].tippoint;
3503 Sprite::MakeSprite(cloudimpactsprite, footpoint, footvel, 1, 0, 0, .9, .3);
3504 footvel = (weapons[weaponids[0]].tippoint - weapons[weaponids[0]].position) * -1;
3505 Sprite::MakeSprite(bloodsprite, footpoint, DoRotation(footvel * 7, (float)(Random() % 20), (float)(Random() % 20), 0), 1, 1, 1, .05, .9);
3506 Sprite::MakeSprite(bloodsprite, footpoint, DoRotation(footvel * 3, (float)(Random() % 20), (float)(Random() % 20), 0), 1, 1, 1, .05, .9);
3507 Sprite::MakeSprite(bloodflamesprite, footpoint, footvel * 5, 1, 1, 1, .3, 1);
3508 Sprite::MakeSprite(bloodflamesprite, footpoint, footvel * 2, 1, 1, 1, .3, 1);
3512 if (animTarget == sweepreversalanim && animation[animTarget].label[frameCurrent] == 7) {
3520 if (weaponactive == -1) {
3521 if (tutoriallevel != 1) {
3522 emit_sound_at(heavyimpactsound, victim->coords, 128.);
3527 if (weaponactive != -1 || creature == wolftype)
3529 if (creature == rabbittype && weaponactive != -1)
3530 if (weapons[weaponids[0]].getType() == staff)
3533 if (weaponactive != -1) {
3534 victim->DoBloodBig(2 / victim->armorhead, 225);
3535 emit_sound_at(knifeslicesound, victim->coords);
3536 if (bloodtoggle && !weapons[weaponids[weaponactive]].bloody)
3537 weapons[weaponids[weaponactive]].bloody = 1;
3538 weapons[weaponids[weaponactive]].blooddrip += 3;
3540 if (weaponactive == -1 && creature == wolftype) {
3541 emit_sound_at(clawslicesound, victim->coords, 128.);
3543 victim->DoBloodBig(2 / victim->armorhead, 175);
3547 award_bonus(id, Reversal);
3552 //relative=victim->coords-oldcoords;
3553 relative = facing * -1;
3555 Normalise(&relative);
3556 relative = DoRotation(relative, 0, 90, 0);
3558 Normalise(&relative);
3559 for (i = 0; i < victim->skeleton.num_joints; i++) {
3560 victim->skeleton.joints[i].velocity += relative * damagemult * 20;
3562 victim->jointVel(head) += relative * damagemult * 200;
3563 if (victim->damage < victim->damagetolerance - 100)
3564 victim->velocity = relative * 200;
3565 victim->DoDamage(damagemult * 100 / victim->protectionhead);
3566 victim->velocity = 0;
3569 if (animTarget == sweepreversalanim && ((animation[animTarget].label[frameCurrent] == 9 && victim->damage < victim->damagetolerance) || (animation[animTarget].label[frameCurrent] == 7 && victim->damage > victim->damagetolerance))) {
3573 //relative=victim->coords-oldcoords;
3574 relative = facing * -1;
3576 Normalise(&relative);
3577 relative = DoRotation(relative, 0, 90, 0);
3579 Normalise(&relative);
3580 for (i = 0; i < victim->skeleton.num_joints; i++) {
3581 victim->skeleton.joints[i].velocity += relative * damagemult * 20;
3583 victim->jointVel(head) += relative * damagemult * 200;
3586 if (hasvictim && (animTarget == spinkickreversalanim || animTarget == sweepreversalanim || animTarget == rabbitkickreversalanim || animTarget == upunchreversalanim || animTarget == jumpreversalanim || animTarget == swordslashreversalanim || animTarget == knifeslashreversalanim || animTarget == rabbittacklereversal || animTarget == wolftacklereversal || animTarget == staffhitreversalanim || animTarget == staffspinhitreversalanim))
3587 if (victim->damage > victim->damagetolerance && bonus != reverseko) {
3588 award_bonus(id, reverseko);
3594 if (frameTarget > animation[animCurrent].numframes - 1) {
3597 animTarget = getIdle();
3601 if (animCurrent == rabbittackleanim || animCurrent == rabbittacklinganim) {
3602 animTarget = rollanim;
3604 emit_sound_at(movewhooshsound, coords, 128.);
3606 if (animCurrent == staggerbackhighanim) {
3607 animTarget = getIdle();
3609 if (animCurrent == staggerbackhardanim) {
3610 animTarget = getIdle();
3612 if (animCurrent == removeknifeanim) {
3613 animTarget = getIdle();
3615 if (animCurrent == crouchremoveknifeanim) {
3616 animTarget = getCrouch();
3618 if (animCurrent == backhandspringanim) {
3619 animTarget = getIdle();
3621 if (animCurrent == dodgebackanim) {
3622 animTarget = getIdle();
3624 if (animCurrent == drawleftanim) {
3625 animTarget = getIdle();
3627 if (animCurrent == drawrightanim || animCurrent == crouchdrawrightanim) {
3628 animTarget = getIdle();
3629 if (animCurrent == crouchdrawrightanim) {
3630 animTarget = getCrouch();
3632 if (weaponactive == -1)
3634 else if (weaponactive == 0) {
3636 if (num_weapons == 2) {
3638 buffer = weaponids[0];
3639 weaponids[0] = weaponids[1];
3640 weaponids[1] = buffer;
3644 if (weaponactive == -1) {
3645 emit_sound_at(knifesheathesound, coords, 128.);
3647 if (weaponactive != -1) {
3648 emit_sound_at(knifedrawsound, coords, 128.);
3651 if (animCurrent == rollanim) {
3652 animTarget = getCrouch();
3657 if (animTarget == walljumprightkickanim) {
3660 if (animTarget == walljumpleftkickanim) {
3663 animTarget = jumpdownanim;
3665 if (animCurrent == climbanim) {
3666 animTarget = getCrouch();
3668 coords += facing * .1;
3669 if (!isnormal(coords.x))
3680 if (animTarget == rabbitkickreversalanim) {
3681 animTarget = getCrouch();
3684 if (animTarget == jumpreversalanim) {
3685 animTarget = getCrouch();
3688 if (animTarget == walljumprightanim || animTarget == walljumpbackanim || animTarget == walljumpfrontanim) {
3689 if (attackkeydown && animTarget != walljumpfrontanim) {
3691 float closestdist = -1;
3694 for (i = 0; i < numplayers; i++) {
3695 if (id != i && player[i].coords.y < coords.y && !player[i].skeleton.free) {
3696 distance = distsq(&player[i].coords, &coords);
3697 if (closestdist == -1 || distance < closestdist) {
3698 closestdist = distance;
3703 if (closestdist > 0 && closest >= 0 && closestdist < 16) {
3704 victim = &player[closest];
3705 animTarget = walljumprightkickanim;
3707 XYZ rotatetarget = victim->coords - coords;
3708 Normalise(&rotatetarget);
3709 yaw = -asin(0 - rotatetarget.x);
3711 if (rotatetarget.z < 0)
3713 targettilt2 = -asin(rotatetarget.y) * 360 / 6.28;
3714 velocity = (victim->coords - coords) * 4;
3719 if (animTarget == walljumpbackanim) {
3720 animTarget = backflipanim;
3722 velocity = facing * -8;
3725 resume_stream(whooshsound);
3727 if (animTarget == walljumprightanim) {
3728 animTarget = rightflipanim;
3732 velocity = DoRotation(facing, 0, 30, 0) * -8;
3735 if (animTarget == walljumpfrontanim) {
3736 animTarget = frontflipanim;
3740 velocity = facing * 8;
3744 resume_stream(whooshsound);
3746 if (animTarget == walljumpleftanim) {
3747 if (attackkeydown) {
3749 float closestdist = -1;
3752 for (i = 0; i < numplayers; i++) {
3753 if (id != i && player[i].coords.y < coords.y && !player[i].skeleton.free) {
3754 distance = distsq(&player[i].coords, &coords);
3755 if (closestdist == -1 || distance < closestdist) {
3756 closestdist = distance;
3761 if (closestdist > 0 && closest >= 0 && closestdist < 16) {
3762 victim = &player[closest];
3763 animTarget = walljumpleftkickanim;
3765 XYZ rotatetarget = victim->coords - coords;
3766 Normalise(&rotatetarget);
3767 yaw = -asin(0 - rotatetarget.x);
3769 if (rotatetarget.z < 0)
3771 targettilt2 = -asin(rotatetarget.y) * 360 / 6.28;
3772 velocity = (victim->coords - coords) * 4;
3777 if (animTarget != walljumpleftkickanim) {
3778 animTarget = leftflipanim;
3782 velocity = DoRotation(facing, 0, -30, 0) * -8;
3786 resume_stream(whooshsound);
3788 if (animTarget == sneakattackanim) {
3789 animCurrent = getCrouch();
3790 animTarget = getCrouch();
3797 transspeed = 1000000;
3798 targetheadyaw += 180;
3799 coords -= facing * .7;
3801 coords.y = terrain.getHeight(coords.x, coords.z);
3805 if (animTarget == knifesneakattackanim || animTarget == swordsneakattackanim) {
3806 animTarget = getIdle();
3809 coords.y = terrain.getHeight(coords.x, coords.z);
3813 if (animCurrent == knifefollowanim) {
3814 animTarget = getIdle();
3817 if (animation[animTarget].attack == reversal && animCurrent != sneakattackanim && animCurrent != knifesneakattackanim && animCurrent != swordsneakattackanim && animCurrent != knifefollowanim) {
3818 float ycoords = oldcoords.y;
3819 animTarget = getStop();
3824 transspeed = 1000000;
3825 targetheadyaw += 180;
3826 if (!isnormal(coords.x))
3828 if (animCurrent == spinkickreversalanim || animCurrent == swordslashreversalanim)
3829 oldcoords = coords + facing * .5;
3830 else if (animCurrent == sweepreversalanim)
3831 oldcoords = coords + facing * 1.1;
3832 else if (animCurrent == upunchreversalanim) {
3833 oldcoords = coords + facing * 1.5;
3836 targetheadyaw += 180;
3839 } else if (animCurrent == knifeslashreversalanim) {
3840 oldcoords = coords + facing * .5;
3843 targetheadyaw += 90;
3846 } else if (animCurrent == staffspinhitreversalanim) {
3849 targetheadyaw += 180;
3854 oldcoords.y = terrain.getHeight(oldcoords.x, oldcoords.z);
3856 oldcoords.y = ycoords;
3857 currentoffset = coords - oldcoords;
3863 if (animCurrent == knifesneakattackedanim || animCurrent == swordsneakattackedanim) {
3868 if (animation[animTarget].attack == reversed) {
3870 if (animTarget == sweepreversedanim)
3872 animTarget = backhandspringanim;
3874 emit_sound_at(landsound, coords, 128);
3876 if (animCurrent == upunchreversedanim || animCurrent == swordslashreversedanim) {
3877 animTarget = rollanim;
3880 coords += (DoRotation(jointPos(leftfoot), 0, yaw, 0) + DoRotation(jointPos(rightfoot), 0, yaw, 0)) / 2 * scale;
3881 coords.y = oldcoords.y;
3883 if (animCurrent == knifeslashreversedanim) {
3884 animTarget = rollanim;
3889 coords += (DoRotation(jointPos(leftfoot), 0, yaw, 0) + DoRotation(jointPos(rightfoot), 0, yaw, 0)) / 2 * scale;
3890 coords.y = oldcoords.y;
3894 animTarget = jumpdownanim;
3897 animTarget = getIdle();
3899 animTarget = getIdle();
3900 if (animCurrent == spinkickanim || animCurrent == getupfrombackanim || animCurrent == getupfromfrontanim || animCurrent == lowkickanim) {
3901 animTarget = getIdle();
3903 coords += (DoRotation(jointPos(leftfoot), 0, yaw, 0) + DoRotation(jointPos(rightfoot), 0, yaw, 0)) / 2 * scale;
3904 coords.y = oldcoords.y;
3905 //coords+=DoRotation(animation[animCurrent].offset,0,yaw,0)*scale;
3906 targetoffset.y = coords.y;
3908 targetoffset.y = terrain.getHeight(coords.x, coords.z);
3909 currentoffset = DoRotation(animation[animCurrent].offset * -1, 0, yaw, 0) * scale;
3910 currentoffset.y -= (coords.y - targetoffset.y);
3911 coords.y = targetoffset.y;
3913 normalsupdatedelay = 0;
3915 if (animCurrent == upunchanim) {
3916 animTarget = getStop();
3917 normalsupdatedelay = 0;
3920 if (animCurrent == rabbitkickanim && animTarget != backflipanim) {
3924 if (num_weapons > 0)
3925 if (weapons[0].getType() == staff)
3931 rabbitkickragdoll = 1;
3933 if (animCurrent == rabbitkickreversedanim) {
3939 skeleton.spinny = 0;
3940 SolidHitBonus(!id); // FIXME: tricky id
3944 animTarget = rollanim;
3947 pause_sound(whooshsound);
3951 if (animCurrent == rabbittackledbackanim || animCurrent == rabbittackledfrontanim) {
3955 skeleton.spinny = 0;
3957 if (animCurrent == jumpreversedanim) {
3963 skeleton.spinny = 0;
3964 SolidHitBonus(!id); // FIXME: tricky id
3968 animTarget = rollanim;
3969 coords += facing * 2;
3971 pause_sound(whooshsound);
3976 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) {
3977 animTarget = getupfromfrontanim;
3979 } else if (animation[animCurrent].attack == normalattack) {
3980 animTarget = getIdle();
3983 if (animCurrent == blockhighleftanim && aitype != playercontrolled) {
3984 animTarget = blockhighleftstrikeanim;
3986 if (animCurrent == knifeslashstartanim || animCurrent == knifethrowanim || animCurrent == swordslashanim || animCurrent == staffhitanim || animCurrent == staffgroundsmashanim || animCurrent == staffspinhitanim) {
3987 animTarget = getIdle();
3990 if (animCurrent == spinkickanim && victim->skeleton.free) {
3991 if (creature == rabbittype)
3992 animTarget = fightidleanim;
3997 if (isIdle() && !wasIdle())
3998 normalsupdatedelay = 0;
4000 if (animCurrent == jumpupanim && velocity.y < 0 && !isFlip()) {
4001 animTarget = jumpdownanim;
4004 if (!skeleton.free) {
4006 if (!transspeed && animation[animTarget].attack != 2 && animation[animTarget].attack != 3) {
4007 if (!isRun() || !wasRun()) {
4008 if (animation[animTarget].speed[frameTarget] > animation[animCurrent].speed[frameCurrent])
4009 target += multiplier * animation[animTarget].speed[frameTarget] * speed * 2;
4010 if (animation[animTarget].speed[frameTarget] <= animation[animCurrent].speed[frameCurrent])
4011 target += multiplier * animation[animCurrent].speed[frameCurrent] * speed * 2;
4013 if (isRun() && wasRun()) {
4015 tempspeed = velspeed;
4016 if (tempspeed < 10 * speedmult)
4017 tempspeed = 10 * speedmult;
4018 target += multiplier * animation[animTarget].speed[frameCurrent] * speed * 1.7 * tempspeed / (speed * 45 * scale);
4020 } else if (transspeed)
4021 target += multiplier * transspeed * speed * 2;
4023 if (!isRun() || !wasRun()) {
4024 if (animation[animTarget].speed[frameTarget] > animation[animCurrent].speed[frameCurrent])
4025 target += multiplier * animation[animTarget].speed[frameTarget] * 2;
4026 if (animation[animTarget].speed[frameTarget] <= animation[animCurrent].speed[frameCurrent])
4027 target += multiplier * animation[animCurrent].speed[frameCurrent] * 2;
4031 if (animCurrent != animTarget)
4032 target = (target + oldtarget) / 2;
4035 frameCurrent = frameTarget;
4039 rot = targetrot * target;
4040 yaw += rot - oldrot;
4046 if (animCurrent != oldanimCurrent || animTarget != oldanimTarget || ((frameCurrent != oldframeCurrent || frameTarget != oldframeTarget) && !calcrot)) {
4048 for (i = 0; i < skeleton.num_joints; i++) {
4049 skeleton.joints[i].position = animation[animCurrent].position[i][frameCurrent];
4052 skeleton.FindForwards();
4054 for (i = 0; i < skeleton.num_muscles; i++) {
4055 if (skeleton.muscles[i].visible) {
4056 skeleton.FindRotationMuscle(i, animTarget);
4059 for (i = 0; i < skeleton.num_muscles; i++) {
4060 if (skeleton.muscles[i].visible) {
4061 if (isnormal((float)((int)(skeleton.muscles[i].rotate1 * 100) % 36000) / 100))
4062 skeleton.muscles[i].oldrotate1 = (float)((int)(skeleton.muscles[i].rotate1 * 100) % 36000) / 100;
4063 if (isnormal((float)((int)(skeleton.muscles[i].rotate2 * 100) % 36000) / 100))
4064 skeleton.muscles[i].oldrotate2 = (float)((int)(skeleton.muscles[i].rotate2 * 100) % 36000) / 100;
4065 if (isnormal((float)((int)(skeleton.muscles[i].rotate3 * 100) % 36000) / 100))
4066 skeleton.muscles[i].oldrotate3 = (float)((int)(skeleton.muscles[i].rotate3 * 100) % 36000) / 100;
4071 for (i = 0; i < skeleton.num_joints; i++) {
4072 skeleton.joints[i].position = animation[animTarget].position[i][frameTarget];
4075 skeleton.FindForwards();
4077 for (i = 0; i < skeleton.num_muscles; i++) {
4078 if (skeleton.muscles[i].visible) {
4079 skeleton.FindRotationMuscle(i, animTarget);
4082 for (i = 0; i < skeleton.num_muscles; i++) {
4083 if (skeleton.muscles[i].visible) {
4084 if (isnormal((float)((int)(skeleton.muscles[i].rotate1 * 100) % 36000) / 100))
4085 skeleton.muscles[i].newrotate1 = (float)((int)(skeleton.muscles[i].rotate1 * 100) % 36000) / 100;
4086 if (isnormal((float)((int)(skeleton.muscles[i].rotate2 * 100) % 36000) / 100))
4087 skeleton.muscles[i].newrotate2 = (float)((int)(skeleton.muscles[i].rotate2 * 100) % 36000) / 100;
4088 if (isnormal((float)((int)(skeleton.muscles[i].rotate3 * 100) % 36000) / 100))
4089 skeleton.muscles[i].newrotate3 = (float)((int)(skeleton.muscles[i].rotate3 * 100) % 36000) / 100;
4090 if (skeleton.muscles[i].newrotate3 > skeleton.muscles[i].oldrotate3 + 180) skeleton.muscles[i].newrotate3 -= 360;
4091 if (skeleton.muscles[i].newrotate3 < skeleton.muscles[i].oldrotate3 - 180) skeleton.muscles[i].newrotate3 += 360;
4092 if (skeleton.muscles[i].newrotate2 > skeleton.muscles[i].oldrotate2 + 180) skeleton.muscles[i].newrotate2 -= 360;
4093 if (skeleton.muscles[i].newrotate2 < skeleton.muscles[i].oldrotate2 - 180) skeleton.muscles[i].newrotate2 += 360;
4094 if (skeleton.muscles[i].newrotate1 > skeleton.muscles[i].oldrotate1 + 180) skeleton.muscles[i].newrotate1 -= 360;
4095 if (skeleton.muscles[i].newrotate1 < skeleton.muscles[i].oldrotate1 - 180) skeleton.muscles[i].newrotate1 += 360;
4099 if (frameCurrent >= animation[animCurrent].numframes)
4100 frameCurrent = animation[animCurrent].numframes - 1;
4102 oldanimCurrent = animCurrent;
4103 oldanimTarget = animTarget;
4104 oldframeTarget = frameTarget;
4105 oldframeCurrent = frameCurrent;
4107 for (i = 0; i < skeleton.num_joints; i++) {
4108 skeleton.joints[i].velocity = (animation[animCurrent].position[i][frameCurrent] * (1 - target) + animation[animTarget].position[i][frameTarget] * (target) - skeleton.joints[i].position) / multiplier;
4109 skeleton.joints[i].position = animation[animCurrent].position[i][frameCurrent] * (1 - target) + animation[animTarget].position[i][frameTarget] * (target);
4111 offset = currentoffset * (1 - target) + targetoffset * target;
4112 for (i = 0; i < skeleton.num_muscles; i++) {
4113 if (skeleton.muscles[i].visible) {
4114 skeleton.muscles[i].rotate1 = skeleton.muscles[i].oldrotate1 * (1 - target) + skeleton.muscles[i].newrotate1 * (target);
4115 skeleton.muscles[i].rotate2 = skeleton.muscles[i].oldrotate2 * (1 - target) + skeleton.muscles[i].newrotate2 * (target);
4116 skeleton.muscles[i].rotate3 = skeleton.muscles[i].oldrotate3 * (1 - target) + skeleton.muscles[i].newrotate3 * (target);
4121 if (isLanding() && landhard) {
4124 animTarget = getLandhard();
4131 //skeleton.DoConstraints();
4138 void Person::DoStuff()
4140 static XYZ terrainnormal;
4141 static XYZ flatfacing;
4142 static XYZ flatvelocity;
4143 static float flatvelspeed;
4147 static int bloodsize;
4148 static int startx, starty, endx, endy;
4149 static GLubyte color;
4150 static XYZ bloodvel;
4152 onfiredelay -= multiplier;
4153 if (onfiredelay < 0 && onfire) {
4154 if (Random() % 2 == 0) {
4160 crouchkeydowntime += multiplier;
4162 crouchkeydowntime = 0;
4163 jumpkeydowntime += multiplier;
4164 if (!jumpkeydown && skeleton.free)
4165 jumpkeydowntime = 0;
4167 if (hostile || damage > 0 || bloodloss > 0)
4170 if (isIdle() || isRun())
4173 if (num_weapons == 1 && weaponactive != -1)
4177 blooddimamount -= multiplier * .3;
4178 speechdelay -= multiplier;
4179 texupdatedelay -= multiplier;
4180 interestdelay -= multiplier;
4181 flamedelay -= multiplier;
4182 parriedrecently -= multiplier;
4189 speed = 1.1 * speedmult;
4191 speed = 1.0 * speedmult;
4193 rabbitkickragdoll = 0;
4197 if (id != 0 && (creature == rabbittype || difficulty != 2))
4199 if (id != 0 && creature == wolftype && difficulty == 2) {
4201 if (aitype != passivetype) {
4203 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) {
4209 if (animTarget == wolfrunninganim && !superruntoggle) {
4210 animTarget = getRun();
4214 if (weaponactive == -1 && num_weapons > 0) {
4215 if (weapons[weaponids[0]].getType() == staff) {
4221 burnt += multiplier;
4222 /*if(aitype!=playercontrolled)*///deathbleeding=5;
4223 /*if(aitype!=playercontrolled)*/
4227 OPENAL_SetVolume(channels[stream_firesound], 256 + 256 * findLength(&velocity) / 3);
4229 if (animTarget == jumpupanim || animTarget == jumpdownanim || isFlip()) {
4235 vel[0] = velocity.x;
4236 vel[1] = velocity.y;
4237 vel[2] = velocity.z;
4240 OPENAL_3D_SetAttributes(channels[whooshsound], gLoc, vel);
4241 OPENAL_SetVolume(channels[whooshsound], 64 * findLength(&velocity) / 5);
4245 while (flamedelay < 0 && onfire) {
4247 howmany = abs(Random() % (skeleton.num_joints));
4249 flatvelocity = (coords - oldcoords) / multiplier / 2; //velocity/2;
4251 flatvelocity = skeleton.joints[howmany].velocity * scale / 2;
4253 flatfacing = DoRotation(DoRotation(DoRotation(skeleton.joints[howmany].position, 0, 0, tilt), tilt2, 0, 0), 0, yaw, 0) * scale + coords;
4255 flatfacing = skeleton.joints[howmany].position * scale + coords;
4256 Sprite::MakeSprite(flamesprite, flatfacing, flatvelocity, 1, 1, 1, .6 + (float)abs(Random() % 100) / 200 - .25, 1);
4259 while (flamedelay < 0 && !onfire && tutoriallevel == 1 && id != 0) {
4261 howmany = abs(Random() % (skeleton.num_joints));
4263 flatvelocity = (coords - oldcoords) / multiplier / 2; //velocity/2;
4265 flatvelocity = skeleton.joints[howmany].velocity * scale / 2;
4267 flatfacing = DoRotation(DoRotation(DoRotation(skeleton.joints[howmany].position, 0, 0, tilt), tilt2, 0, 0), 0, yaw, 0) * scale + coords;
4269 flatfacing = skeleton.joints[howmany].position * scale + coords;
4270 Sprite::MakeSprite(breathsprite, flatfacing, flatvelocity, 1, 1, 1, .6 + (float)abs(Random() % 100) / 200 - .25, .3);
4274 bleeding -= multiplier * .3;
4275 if (bloodtoggle == 2) {
4276 skeleton.drawmodel.textureptr.bind();
4277 if (bleeding <= 0 && (detail != 2 || osx))
4282 if (neckspurtamount > 0) {
4283 neckspurtamount -= multiplier;
4284 neckspurtdelay -= multiplier * 3;
4285 neckspurtparticledelay -= multiplier * 3;
4286 if (neckspurtparticledelay < 0 && neckspurtdelay > 2) {
4289 if (!skeleton.free) {
4290 bloodvel.z = 5 * neckspurtamount;
4291 bloodvel = DoRotation(bloodvel, ((float)(Random() % 100)) / 40, yaw + ((float)(Random() % 100)) / 40, 0) * scale;
4293 if (skeleton.free) {
4294 bloodvel -= DoRotation(skeleton.forward * 10 * scale, ((float)(Random() % 100)) / 40, ((float)(Random() % 100)) / 40, 0);
4297 bloodvel += DoRotation(jointVel(head), ((float)(Random() % 100)) / 40, yaw + ((float)(Random() % 100)) / 40, 0) * scale;
4299 bloodvel += DoRotation(velocity, ((float)(Random() % 100)) / 40, ((float)(Random() % 100)) / 40, 0) * scale;
4301 Sprite::MakeSprite(bloodsprite, (jointPos(neck) + (jointPos(neck) - jointPos(head)) / 5)*scale + coords, bloodvel, 1, 1, 1, .05, .9);
4303 Sprite::MakeSprite(bloodsprite, DoRotation(jointPos(neck) + (jointPos(neck) - jointPos(head)) / 5, 0, yaw, 0)*scale + coords, bloodvel, 1, 1, 1, .05, .9);
4304 neckspurtparticledelay = .05;
4306 if (neckspurtdelay < 0) {
4311 if (deathbleeding > 0 && dead != 2) {
4312 if (deathbleeding < 5)
4313 bleeddelay -= deathbleeding * multiplier / 4;
4315 bleeddelay -= 5 * multiplier / 4;
4316 if (bleeddelay < 0 && bloodtoggle) {
4322 bloodvel += DoRotation(jointVel(abdomen), ((float)(Random() % 100)) / 4, yaw + ((float)(Random() % 100)) / 4, 0) * scale;
4324 bloodvel += DoRotation(velocity, ((float)(Random() % 100)) / 4, ((float)(Random() % 100)) / 4, 0) * scale;
4326 Sprite::MakeSprite(bloodsprite, jointPos(abdomen) * scale + coords, bloodvel, 1, 1, 1, .05, 1);
4328 Sprite::MakeSprite(bloodsprite, DoRotation((jointPos(abdomen) + jointPos(abdomen)) / 2, 0, yaw, 0)*scale + coords, bloodvel, 1, 1, 1, .05, 1);
4331 bloodloss += deathbleeding * multiplier * 80;
4332 deathbleeding -= multiplier * 1.6;
4333 //if(id==0)deathbleeding-=multiplier*.2;
4334 if (deathbleeding < 0)
4336 if (bloodloss > damagetolerance && animation[animTarget].attack == neutral) {
4337 if (weaponactive != -1) {
4338 weapons[weaponids[0]].owner = -1;
4339 weapons[weaponids[0]].velocity = velocity * scale * -.3;
4340 weapons[weaponids[0]].velocity.x += .01;
4341 weapons[weaponids[0]].tipvelocity = velocity * scale;
4342 weapons[weaponids[0]].missed = 1;
4343 weapons[weaponids[0]].hitsomething = 0;
4344 weapons[weaponids[0]].freetime = 0;
4345 weapons[weaponids[0]].firstfree = 1;
4346 weapons[weaponids[0]].physics = 1;
4349 weaponids[0] = weaponids[num_weapons];
4350 if (weaponstuck == num_weapons)
4354 for (i = 0; i < numplayers; i++) {
4355 player[i].wentforweapon = 0;
4367 if (!dead && creature == wolftype) {
4368 award_bonus(0, Wolfbonus);
4371 if (animTarget == knifefollowedanim && !skeleton.free) {
4372 for (i = 0; i < skeleton.num_joints; i++) {
4373 skeleton.joints[i].velocity = 0;
4374 skeleton.joints[i].velocity.y = -2;
4377 if (id != 0 && unconscioustime > .1) {
4385 if (texupdatedelay < 0 && bleeding > 0 && bloodtoggle == 2 && distsq(&viewer, &coords) < 9) {
4386 texupdatedelay = .12;
4388 bloodsize = 5 - realtexdetail;
4392 startx = bleedy; //abs(Random()%(skeleton.skinsize-bloodsize-1));
4393 starty = bleedx; //abs(Random()%(skeleton.skinsize-bloodsize-1));
4394 endx = startx + bloodsize;
4395 endy = starty + bloodsize;
4405 if (endx > skeleton.skinsize - 1) {
4406 endx = skeleton.skinsize - 1;
4409 if (endy > skeleton.skinsize - 1) {
4410 endy = skeleton.skinsize - 1;
4418 for (i = startx; i < endx; i++) {
4419 for (j = starty; j < endy; j++) {
4420 if (Random() % 2 == 0) {
4421 color = Random() % 85 + 170;
4422 if (skeleton.skinText[i * skeleton.skinsize * 3 + j * 3 + 0] > color / 2)
4423 skeleton.skinText[i * skeleton.skinsize * 3 + j * 3 + 0] = color / 2;
4424 skeleton.skinText[i * skeleton.skinsize * 3 + j * 3 + 1] = 0;
4425 skeleton.skinText[i * skeleton.skinsize * 3 + j * 3 + 2] = 0;
4429 if (!osx && detail > 1) {
4430 skeleton.drawmodel.textureptr.bind();
4434 if (!skeleton.free) {
4435 bleedy -= 4 / realtexdetail;
4437 bleedx += (abs(Random() % 3) - 1) * 2 / realtexdetail;
4439 bleedx += (abs(Random() % 3) - 1) * 4 / realtexdetail;
4441 if (skeleton.free) {
4442 bleedx += 4 * direction / realtexdetail;
4444 bleedy += (abs(Random() % 3) - 1) * 2 / realtexdetail;
4446 bleedy += (abs(Random() % 3) - 1) * 4 / realtexdetail;
4450 if (abs(righthandmorphness - targetrighthandmorphness) < multiplier * 4) {
4451 righthandmorphness = targetrighthandmorphness;
4452 righthandmorphstart = righthandmorphend;
4453 } else if (righthandmorphness > targetrighthandmorphness) {
4454 righthandmorphness -= multiplier * 4;
4455 } else if (righthandmorphness < targetrighthandmorphness) {
4456 righthandmorphness += multiplier * 4;
4459 if (abs(lefthandmorphness - targetlefthandmorphness) < multiplier * 4) {
4460 lefthandmorphness = targetlefthandmorphness;
4461 lefthandmorphstart = lefthandmorphend;
4462 } else if (lefthandmorphness > targetlefthandmorphness) {
4463 lefthandmorphness -= multiplier * 4;
4464 } else if (lefthandmorphness < targetlefthandmorphness) {
4465 lefthandmorphness += multiplier * 4;
4468 if (creature == rabbittype || targettailmorphness == 5 || targettailmorphness == 0) {
4469 if (abs(tailmorphness - targettailmorphness) < multiplier * 10) {
4470 tailmorphness = targettailmorphness;
4471 tailmorphstart = tailmorphend;
4472 } else if (tailmorphness > targettailmorphness) {
4473 tailmorphness -= multiplier * 10;
4474 } else if (tailmorphness < targettailmorphness) {
4475 tailmorphness += multiplier * 10;
4479 if (creature == wolftype) {
4480 if (abs(tailmorphness - targettailmorphness) < multiplier * 4) {
4481 tailmorphness = targettailmorphness;
4482 tailmorphstart = tailmorphend;
4483 } else if (tailmorphness > targettailmorphness) {
4484 tailmorphness -= multiplier * 2;
4485 } else if (tailmorphness < targettailmorphness) {
4486 tailmorphness += multiplier * 2;
4490 if (headmorphend == 3 || headmorphstart == 3) {
4491 if (abs(headmorphness - targetheadmorphness) < multiplier * 7) {
4492 headmorphness = targetheadmorphness;
4493 headmorphstart = headmorphend;
4494 } else if (headmorphness > targetheadmorphness) {
4495 headmorphness -= multiplier * 7;
4496 } else if (headmorphness < targetheadmorphness) {
4497 headmorphness += multiplier * 7;
4499 } else if (headmorphend == 5 || headmorphstart == 5) {
4500 if (abs(headmorphness - targetheadmorphness) < multiplier * 10) {
4501 headmorphness = targetheadmorphness;
4502 headmorphstart = headmorphend;
4503 } else if (headmorphness > targetheadmorphness) {
4504 headmorphness -= multiplier * 10;
4505 } else if (headmorphness < targetheadmorphness) {
4506 headmorphness += multiplier * 10;
4509 if (abs(headmorphness - targetheadmorphness) < multiplier * 4) {
4510 headmorphness = targetheadmorphness;
4511 headmorphstart = headmorphend;
4512 } else if (headmorphness > targetheadmorphness) {
4513 headmorphness -= multiplier * 4;
4514 } else if (headmorphness < targetheadmorphness) {
4515 headmorphness += multiplier * 4;
4519 if (abs(chestmorphness - targetchestmorphness) < multiplier) {
4520 chestmorphness = targetchestmorphness;
4521 chestmorphstart = chestmorphend;
4522 } else if (chestmorphness > targetchestmorphness) {
4523 chestmorphness -= multiplier;
4524 } else if (chestmorphness < targetchestmorphness) {
4525 chestmorphness += multiplier;
4528 if (dead != 2 && howactive <= typesleeping) {
4529 if (chestmorphstart == 0 && chestmorphend == 0) {
4531 targetchestmorphness = 1;
4534 if (chestmorphstart != 0 && chestmorphend != 0) {
4536 targetchestmorphness = 1;
4538 if (environment == snowyenvironment) {
4542 footvel = DoRotation(skeleton.specialforward[0], 0, yaw, 0) * -1;
4544 footvel = skeleton.specialforward[0] * -1;
4546 footpoint = DoRotation((jointPos(head) + jointPos(neck)) / 2, 0, yaw, 0) * scale + coords;
4548 footpoint = ((jointPos(head) + jointPos(neck)) / 2) * scale + coords;
4549 if (animTarget == sleepanim)
4550 footvel = DoRotation(footvel, 0, 90, 0);
4551 Sprite::MakeSprite(breathsprite, footpoint + footvel * .2, footvel * .4, 1, 1, 1, .4, .3);
4555 if (!dead && howactive < typesleeping) {
4556 blinkdelay -= multiplier * 2;
4557 if (headmorphstart == 0 && headmorphend == 0 && blinkdelay <= 0) {
4559 targetheadmorphness = 1;
4561 blinkdelay = (float)(abs(Random() % 40)) / 5;
4563 if (headmorphstart == 3 && headmorphend == 3) {
4565 targetheadmorphness = 1;
4570 twitchdelay -= multiplier * 1.5;
4571 if (animTarget != hurtidleanim) {
4572 if (headmorphstart == 0 && headmorphend == 0 && twitchdelay <= 0) {
4574 targetheadmorphness = 1;
4576 twitchdelay = (float)(abs(Random() % 40)) / 5;
4578 if (headmorphstart == 5 && headmorphend == 5) {
4580 targetheadmorphness = 1;
4584 if ((isIdle() || isCrouch()) && animTarget != hurtidleanim) {
4585 twitchdelay3 -= multiplier * 1;
4586 if (Random() % 2 == 0) {
4587 if (righthandmorphstart == 0 && righthandmorphend == 0 && twitchdelay3 <= 0) {
4588 righthandmorphness = 0;
4589 targetrighthandmorphness = 1;
4590 righthandmorphend = 1;
4591 if (Random() % 2 == 0)twitchdelay3 = (float)(abs(Random() % 40)) / 5;
4593 if (righthandmorphstart == 1 && righthandmorphend == 1) {
4594 righthandmorphness = 0;
4595 targetrighthandmorphness = 1;
4596 righthandmorphend = 0;
4599 if (Random() % 2 == 0) {
4600 if (lefthandmorphstart == 0 && lefthandmorphend == 0 && twitchdelay3 <= 0) {
4601 lefthandmorphness = 0;
4602 targetlefthandmorphness = 1;
4603 lefthandmorphend = 1;
4604 twitchdelay3 = (float)(abs(Random() % 40)) / 5;
4606 if (lefthandmorphstart == 1 && lefthandmorphend == 1) {
4607 lefthandmorphness = 0;
4608 targetlefthandmorphness = 1;
4609 lefthandmorphend = 0;
4615 if (creature == rabbittype) {
4616 if (howactive < typesleeping)
4617 twitchdelay2 -= multiplier * 1.5;
4619 twitchdelay2 -= multiplier * 0.5;
4620 if (howactive <= typesleeping) {
4621 if (tailmorphstart == 0 && tailmorphend == 0 && twitchdelay2 <= 0) {
4623 targettailmorphness = 1;
4625 twitchdelay2 = (float)(abs(Random() % 40)) / 5;
4627 if (tailmorphstart == 1 && tailmorphend == 1) {
4629 targettailmorphness = 1;
4632 if (tailmorphstart == 2 && tailmorphend == 2) {
4634 targettailmorphness = 1;
4641 if (creature == wolftype) {
4642 twitchdelay2 -= multiplier * 1.5;
4643 if (tailmorphend != 0)
4644 if ((isRun() || animTarget == jumpupanim || animTarget == jumpdownanim || animTarget == backflipanim) && !skeleton.free) {
4646 targettailmorphness = 1;
4650 if (tailmorphend != 5)
4651 if (animTarget == flipanim || animTarget == frontflipanim || animTarget == rollanim || skeleton.free) {
4653 targettailmorphness = 1;
4657 if (twitchdelay2 <= 0) {
4658 if (((tailmorphstart == 0 && tailmorphend == 0) || (tailmorphstart == 5 && tailmorphend == 5))) {
4660 targettailmorphness = 1;
4663 if (tailmorphstart == 1 && tailmorphend == 1) {
4665 targettailmorphness = 1;
4668 if (tailmorphstart == 2 && tailmorphend == 2) {
4670 targettailmorphness = 1;
4673 if (tailmorphstart == 3 && tailmorphend == 3) {
4675 targettailmorphness = 1;
4678 if (tailmorphstart == 4 && tailmorphend == 4) {
4680 targettailmorphness = 1;
4687 unconscioustime = 0;
4689 if (dead == 1 || howactive == typesleeping) {
4690 unconscioustime += multiplier;
4691 //If unconscious, close eyes and mouth
4692 if (righthandmorphend != 0)
4693 righthandmorphness = 0;
4694 righthandmorphend = 0;
4695 targetrighthandmorphness = 1;
4697 if (lefthandmorphend != 0)
4698 lefthandmorphness = 0;
4699 lefthandmorphend = 0;
4700 targetlefthandmorphness = 1;
4702 if (headmorphend != 3 && headmorphend != 5)
4705 targetheadmorphness = 1;
4709 if (howactive > typesleeping) {
4712 if (bloodtoggle && !bled) {
4713 terrain.MakeDecal(blooddecalslow, headpoint, .8, .5, 0);
4715 if (bloodtoggle && !bled)
4716 for (l = 0; l < terrain.patchobjectnum[whichpatchx][whichpatchz]; l++) {
4717 j = terrain.patchobjects[whichpatchx][whichpatchz][l];
4718 XYZ point = DoRotation(headpoint - objects.position[j], 0, -objects.yaw[j], 0);
4722 objects.model[j].MakeDecal(blooddecalslow, &point, &size, &opacity, &yaw);
4727 if (dead == 2 || howactive > typesleeping) {
4728 //If dead, open mouth and hands
4729 if (righthandmorphend != 0)
4730 righthandmorphness = 0;
4731 righthandmorphend = 0;
4732 targetrighthandmorphness = 1;
4734 if (lefthandmorphend != 0)
4735 lefthandmorphness = 0;
4736 lefthandmorphend = 0;
4737 targetlefthandmorphness = 1;
4739 if (headmorphend != 2)
4742 targetheadmorphness = 1;
4745 if (stunned > 0 && !dead && headmorphend != 2) {
4746 if (headmorphend != 4)
4749 targetheadmorphness = 1;
4752 if (damage > damagetolerance && !dead) {
4755 unconscioustime = 0;
4757 if (creature == wolftype) {
4758 award_bonus(0, Wolfbonus);
4763 if (weaponactive != -1) {
4764 weapons[weaponids[0]].owner = -1;
4765 weapons[weaponids[0]].velocity = velocity * scale * -.3;
4766 weapons[weaponids[0]].velocity.x += .01;
4767 weapons[weaponids[0]].tipvelocity = velocity * scale;
4768 weapons[weaponids[0]].missed = 1;
4769 weapons[weaponids[0]].hitsomething = 0;
4770 weapons[weaponids[0]].freetime = 0;
4771 weapons[weaponids[0]].firstfree = 1;
4772 weapons[weaponids[0]].physics = 1;
4775 weaponids[0] = weaponids[num_weapons];
4776 if (weaponstuck == num_weapons)
4780 for (i = 0; i < numplayers; i++) {
4781 player[i].wentforweapon = 0;
4787 if ((id == 0 || distsq(&coords, &viewer) < 50) && autoslomo) {
4795 //if(dead)damage-=multiplier/4;
4797 damage -= multiplier * 13;
4798 //if(!dead&&deathbleeding<=0&&id==0)bloodloss-=multiplier*4;
4800 permanentdamage -= multiplier * 4;
4801 if (isIdle() || isCrouch()) {
4803 permanentdamage -= multiplier * 4;
4804 //if(!dead&&deathbleeding<=0&&id==0)bloodloss-=multiplier*4;
4808 if (permanentdamage < 0)
4809 permanentdamage = 0;
4810 if (superpermanentdamage < 0)
4811 superpermanentdamage = 0;
4812 if (permanentdamage < superpermanentdamage) {
4813 permanentdamage = superpermanentdamage;
4815 if (damage < permanentdamage) {
4816 damage = permanentdamage;
4818 if (dead == 1 && damage < damagetolerance) {
4822 for (i = 0; i < skeleton.num_joints; i++) {
4823 skeleton.joints[i].velocity = 0;
4826 if (permanentdamage > damagetolerance && dead != 2) {
4829 if (weaponactive != -1) {
4830 weapons[weaponids[0]].owner = -1;
4831 weapons[weaponids[0]].velocity = velocity * scale * -.3;
4832 weapons[weaponids[0]].velocity.x += .01;
4833 weapons[weaponids[0]].tipvelocity = velocity * scale;
4834 weapons[weaponids[0]].missed = 1;
4835 weapons[weaponids[0]].hitsomething = 0;
4836 weapons[weaponids[0]].freetime = 0;
4837 weapons[weaponids[0]].firstfree = 1;
4838 weapons[weaponids[0]].physics = 1;
4841 weaponids[0] = weaponids[num_weapons];
4842 if (weaponstuck == num_weapons)
4846 for (i = 0; i < numplayers; i++) {
4847 player[i].wentforweapon = 0;
4853 if (!dead && creature == wolftype) {
4854 award_bonus(0, Wolfbonus);
4857 if (unconscioustime < .1 && (bonus != spinecrusher || bonustime > 1) && (bonus != FinishedBonus || bonustime > 1) && bloodloss < damagetolerance)
4858 award_bonus(id, touchofdeath);
4859 if (id != 0 && unconscioustime > .1) {
4867 emit_sound_at(breaksound, coords);
4870 if (skeleton.free == 1) {
4872 pause_sound(whooshsound);
4875 //If knocked over, open hands and close mouth
4876 if (righthandmorphend != 0)
4877 righthandmorphness = 0;
4878 righthandmorphend = 0;
4879 targetrighthandmorphness = 1;
4881 if (lefthandmorphend != 0)
4882 lefthandmorphness = 0;
4883 lefthandmorphend = 0;
4884 targetlefthandmorphness = 1;
4886 if (headmorphend != 3 && headmorphend != 5 && headmorphstart != 3 && headmorphstart != 5) {
4887 if (headmorphend != 0)
4890 targetheadmorphness = 1;
4894 skeleton.DoGravity(&scale);
4896 damageamount = skeleton.DoConstraints(&coords, &scale) * 5;
4897 if (damage > damagetolerance - damageamount && !dead && (bonus != spinecrusher || bonustime > 1) && (bonus != style || bonustime > 1) && (bonus != cannon || bonustime > 1))
4898 award_bonus(id, deepimpact);
4899 DoDamage(damageamount / ((protectionhigh + protectionhead + protectionlow) / 3));
4903 for (j = 0; j < skeleton.num_joints; j++) {
4904 average += skeleton.joints[j].position;
4908 coords += average * scale;
4909 for (j = 0; j < skeleton.num_joints; j++) {
4910 skeleton.joints[j].position -= average;
4912 average /= multiplier;
4914 //velocity=jointVel(groin)*scale;
4916 for (i = 0; i < skeleton.num_joints; i++) {
4917 velocity += skeleton.joints[i].velocity * scale;
4919 velocity /= skeleton.num_joints;
4921 if (!isnormal(velocity.x) && velocity.x) {
4925 if (findLength(&average) < 10 && dead && skeleton.free) {
4926 skeleton.longdead += (2000 - findLength(&average)) * multiplier + multiplier;
4927 if (skeleton.longdead > 2000) {
4928 if (skeleton.longdead > 6000) {
4930 pause_sound(whooshsound);
4935 if (dead == 2 && bloodloss < damagetolerance) {
4937 headpoint = (jointPos(head) + jointPos(neck)) / 2 * scale + coords;
4939 if (bloodtoggle && !bled) {
4940 terrain.MakeDecal(blooddecal, headpoint, .2 * 1.2, .5, 0);
4942 if (bloodtoggle && !bled)
4943 for (l = 0; l < terrain.patchobjectnum[whichpatchx][whichpatchz]; l++) {
4944 j = terrain.patchobjects[whichpatchx][whichpatchz][l];
4945 XYZ point = DoRotation(headpoint - objects.position[j], 0, -objects.yaw[j], 0);
4946 float size = .2 * 1.2;
4949 objects.model[j].MakeDecal(blooddecal, &point, &size, &opacity, &yaw);
4953 if (dead == 2 && bloodloss >= damagetolerance) {
4955 headpoint = (jointPos(abdomen) + jointPos(neck)) / 2 * scale + coords;
4958 if (bloodtoggle && !bled) {
4959 terrain.MakeDecal(blooddecalslow, headpoint, .8, .5, 0);
4961 if (bloodtoggle && !bled)
4962 for (l = 0; l < terrain.patchobjectnum[whichpatchx][whichpatchz]; l++) {
4963 j = terrain.patchobjects[whichpatchx][whichpatchz][l];
4964 XYZ point = DoRotation(headpoint - objects.position[j], 0, -objects.yaw[j], 0);
4968 objects.model[j].MakeDecal(blooddecalslow, &point, &size, &opacity, &yaw);
4975 if (!dead && crouchkeydown && skeleton.freetime > .5 && id == 0 && skeleton.free) {
4976 bool canrecover = 1;
4977 XYZ startpoint, endpoint, colpoint, colviewer, coltarget;
4978 startpoint = coords;
4981 if (terrain.lineTerrain(startpoint, endpoint, &colpoint) != -1)
4983 if (velocity.y < -30)
4985 for (i = 0; i < objects.numobjects; i++) {
4986 if (objects.type[i] != treeleavestype && objects.type[i] != bushtype && objects.type[i] != firetype) {
4987 colviewer = startpoint;
4988 coltarget = endpoint;
4989 if (objects.model[i].LineCheck(&colviewer, &coltarget, &colpoint, &objects.position[i], &objects.yaw[i]) != -1)
4998 terrainnormal = jointPos(groin) - jointPos(abdomen);
4999 if (joint(groin).locked && joint(abdomen).locked) {
5000 terrainnormal = jointPos(groin) - jointPos(abdomen);
5001 middle = (jointPos(groin) + jointPos(abdomen)) / 2;
5003 if (joint(abdomen).locked && joint(neck).locked) {
5004 terrainnormal = jointPos(abdomen) - jointPos(neck);
5005 middle = (jointPos(neck) + jointPos(abdomen)) / 2;
5007 if (joint(groin).locked && joint(neck).locked) {
5008 terrainnormal = jointPos(groin) - jointPos(neck);
5009 middle = (jointPos(groin) + jointPos(neck)) / 2;
5011 Normalise(&terrainnormal);
5013 targetyaw = -asin(0 - terrainnormal.x);
5014 targetyaw *= 360 / 6.28;
5015 if (terrainnormal.z < 0)
5016 targetyaw = 180 - targetyaw;
5021 animTarget = flipanim;
5022 crouchtogglekeydown = 1;
5027 animCurrent = tempanim;
5030 //tilt2=targettilt2;
5032 //if(middle.y>0)targetoffset.y=middle.y+1;
5034 for (i = 0; i < skeleton.num_joints; i++) {
5035 tempanimation.position[i][0] = skeleton.joints[i].position;
5036 tempanimation.position[i][0] = DoRotation(tempanimation.position[i][0], 0, -yaw, 0);
5041 if (findLength(&average) < 10 && !dead && skeleton.free) {
5042 skeleton.longdead += (2000 - findLength(&average)) * multiplier + multiplier;
5043 if (skeleton.longdead > (damage + 500) * 1.5) {
5045 pause_sound(whooshsound);
5051 terrainnormal = jointPos(groin) - jointPos(abdomen);
5052 if (joint(groin).locked && joint(abdomen).locked) {
5053 terrainnormal = jointPos(groin) - jointPos(abdomen);
5054 middle = (jointPos(groin) + jointPos(abdomen)) / 2;
5056 if (joint(abdomen).locked && joint(neck).locked) {
5057 terrainnormal = jointPos(abdomen) - jointPos(neck);
5058 middle = (jointPos(neck) + jointPos(abdomen)) / 2;
5060 if (joint(groin).locked && joint(neck).locked) {
5061 terrainnormal = jointPos(groin) - jointPos(neck);
5062 middle = (jointPos(groin) + jointPos(neck)) / 2;
5064 Normalise(&terrainnormal);
5066 targetyaw = -asin(0 - terrainnormal.x);
5067 targetyaw *= 360 / 6.28;
5068 if (terrainnormal.z < 0)
5069 targetyaw = 180 - targetyaw;
5072 targettilt2 = asin(terrainnormal.y) * 180 / 3.14 * -1;
5075 if (skeleton.forward.y < 0) {
5076 animTarget = getupfrombackanim;
5080 if (skeleton.forward.y > -.3) {
5081 animTarget = getupfromfrontanim;
5089 if ((Random() % 8 == 0 && id != 0 && creature == rabbittype) || (Random() % 2 == 0 && id != 0 && creature == wolftype) || (id == 0 && crouchkeydown && (forwardkeydown || backkeydown || leftkeydown || rightkeydown))) {
5090 animTarget = rollanim;
5091 targetyaw = lookyaw;
5108 if ( !leftkeydown && !rightkeydown)
5115 if (abs(targettilt2) > 50)
5117 animCurrent = tempanim;
5120 tilt2 = targettilt2;
5122 if (middle.y > 0 && animTarget != rollanim)
5123 targetoffset.y = middle.y + 1;
5125 for (i = 0; i < skeleton.num_joints; i++) {
5126 tempanimation.position[i][0] = skeleton.joints[i].position;
5127 tempanimation.position[i][0] = DoRotation(tempanimation.position[i][0], 0, -yaw, 0);
5134 if (num_weapons > 0)
5135 if (weapons[0].getType() == staff)
5137 if (!skeleton.freefall && freefall && ((jumpkeydown && jumpkeydowntime < .2) || (hasstaff && rabbitkickragdoll)) && !dead) {
5138 if (velocity.y > -30) {
5140 tempvelocity = velocity;
5141 Normalise(&tempvelocity);
5142 targetyaw = -asin(0 - tempvelocity.x);
5143 targetyaw *= 360 / 6.28;
5145 targetyaw = 180 - targetyaw;
5149 if (dotproduct(&skeleton.forward, &tempvelocity) < 0) {
5150 animTarget = rollanim;
5153 animTarget = backhandspringanim;
5159 emit_sound_at(movewhooshsound, coords, 128.);
5161 animCurrent = animTarget;
5162 frameCurrent = frameTarget - 1;
5174 if (skeleton.freefall == 0)
5179 if (aitype != passivetype || skeleton.free == 1)
5180 if (findLengthfast(&velocity) > .1)
5181 for (i = 0; i < objects.numobjects; i++) {
5182 if (objects.type[i] == firetype)
5183 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) {
5185 if (!objects.onfire[i]) {
5186 emit_sound_at(firestartsound, objects.position[i]);
5188 objects.onfire[i] = 1;
5191 if (objects.onfire[i]) {
5196 if (objects.type[i] == bushtype)
5197 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) {
5199 if (!objects.onfire[i]) {
5200 emit_sound_at(firestartsound, objects.position[i]);
5202 objects.onfire[i] = 1;
5206 if (objects.onfire[i]) {
5210 if (objects.messedwith[i] <= 0) {
5214 emit_sound_at(bushrustle, coords, 40 * findLength(&velocity));
5217 envsound[numenvsounds] = coords;
5218 envsoundvol[numenvsounds] = 4 * findLength(&velocity);
5219 envsoundlife[numenvsounds] = .4;
5224 if (environment == grassyenvironment)
5225 howmany = findLength(&velocity) * 4;
5226 if (environment == snowyenvironment)
5227 howmany = findLength(&velocity) * 2;
5229 if (environment != desertenvironment)
5230 for (j = 0; j < howmany; j++) {
5231 tempvel.x = float(abs(Random() % 100) - 50) / 20;
5232 tempvel.y = float(abs(Random() % 100) - 50) / 20;
5233 tempvel.z = float(abs(Random() % 100) - 50) / 20;
5236 pos.x += float(abs(Random() % 100) - 50) / 200;
5237 pos.y += float(abs(Random() % 100) - 50) / 200;
5238 pos.z += float(abs(Random() % 100) - 50) / 200;
5239 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);
5240 Sprite::setLastSpriteSpecial(1);
5242 howmany = findLength(&velocity) * 4;
5244 if (environment == snowyenvironment)
5245 for (j = 0; j < howmany; j++) {
5246 tempvel.x = float(abs(Random() % 100) - 50) / 20;
5247 tempvel.y = float(abs(Random() % 100) - 50) / 20;
5248 tempvel.z = float(abs(Random() % 100) - 50) / 20;
5251 pos.x += float(abs(Random() % 100) - 50) / 200;
5252 pos.y += float(abs(Random() % 100) - 50) / 200;
5253 pos.z += float(abs(Random() % 100) - 50) / 200;
5254 Sprite::MakeSprite(splintersprite, pos, tempvel * .3 + velocity * float(abs(Random() % 100)) / 100 / 2, 1, 1, 1, .1, 1);
5255 Sprite::setLastSpriteSpecial(2);
5258 objects.rotx[i] += velocity.x * multiplier * 6;
5259 objects.roty[i] += velocity.z * multiplier * 6;
5260 objects.messedwith[i] = .5;
5263 if (objects.type[i] == treeleavestype && environment != desertenvironment) {
5264 if (objects.pitch[i] == 0)
5267 tempcoord = coords - objects.position[i];
5268 tempcoord = DoRotation(tempcoord, 0, -objects.yaw[i], 0);
5269 tempcoord = DoRotation(tempcoord, -objects.pitch[i], 0, 0);
5270 tempcoord += objects.position[i];
5272 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]) {
5273 if (objects.messedwith[i] <= 0) {
5277 emit_sound_at(bushrustle, coords, 40 * findLength(&velocity));
5280 envsound[numenvsounds] = coords;
5281 envsoundvol[numenvsounds] = 4 * findLength(&velocity);
5282 envsoundlife[numenvsounds] = .4;
5287 if (environment == grassyenvironment)
5288 howmany = findLength(&velocity) * 4;
5289 if (environment == snowyenvironment)
5290 howmany = findLength(&velocity) * 2;
5292 if (environment != desertenvironment)
5293 for (j = 0; j < howmany; j++) {
5294 tempvel.x = float(abs(Random() % 100) - 50) / 20;
5295 tempvel.y = float(abs(Random() % 100) - 50) / 20;
5296 tempvel.z = float(abs(Random() % 100) - 50) / 20;
5298 pos += velocity * .1;
5300 pos.x += float(abs(Random() % 100) - 50) / 150;
5301 pos.y += float(abs(Random() % 100) - 50) / 150;
5302 pos.z += float(abs(Random() % 100) - 50) / 150;
5303 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);
5304 Sprite::setLastSpriteSpecial(1);
5306 howmany = findLength(&velocity) * 4;
5308 if (environment == snowyenvironment)
5309 for (j = 0; j < howmany; j++) {
5310 tempvel.x = float(abs(Random() % 100) - 50) / 20;
5311 tempvel.y = float(abs(Random() % 100) - 50) / 20;
5312 tempvel.z = float(abs(Random() % 100) - 50) / 20;
5314 pos += velocity * .1;
5316 pos.x += float(abs(Random() % 100) - 50) / 150;
5317 pos.y += float(abs(Random() % 100) - 50) / 150;
5318 pos.z += float(abs(Random() % 100) - 50) / 150;
5319 Sprite::MakeSprite(splintersprite, pos, tempvel * .3 + velocity * float(abs(Random() % 100)) / 100 / 2, 1, 1, 1, .1, 1);
5320 Sprite::setLastSpriteSpecial(2);
5323 objects.messedwith[i] = .5;
5328 if (!skeleton.free) {
5331 if ((stunned > 0 || surprised > 0) && numplayers > 2 && aitype != passivetype)
5334 if (aitype != passivetype && victim->skeleton.free && !victim->dead)
5336 if (tutoriallevel == 1 && id != 0)
5338 if (play && aitype != playercontrolled) {
5339 int whichsound = -1;
5340 i = abs(Random() % 4);
5341 if (speechdelay <= 0) {
5342 if (creature == rabbittype) {
5344 whichsound = rabbitchitter;
5346 whichsound = rabbitchitter2;
5348 if (creature == wolftype) {
5350 whichsound = growlsound;
5352 whichsound = growl2sound;
5357 if (whichsound != -1) {
5358 emit_sound_at(whichsound, coords);
5362 if (animTarget == staggerbackhighanim)
5364 if (animTarget == staggerbackhardanim)
5366 staggerdelay -= multiplier;
5367 if (animTarget != crouchstabanim && animTarget != swordgroundstabanim && animTarget != staffgroundsmashanim)
5369 if (velocity.y < -30 && animTarget == jumpdownanim)
5371 if (animCurrent != getIdle() && wasIdle() && animTarget != getIdle() && isIdle()) {
5372 animTarget = getIdle();
5376 weaponmissdelay -= multiplier;
5377 highreversaldelay -= multiplier;
5378 lowreversaldelay -= multiplier;
5379 lastcollide -= multiplier;
5380 skiddelay -= multiplier;
5381 if (!isnormal(velocity.x) && velocity.x) {
5384 if (!isnormal(targettilt) && targettilt) {
5387 if (!isnormal(targettilt2) && targettilt2) {
5390 if (!isnormal(targetyaw) && targetyaw) {
5394 if (animTarget == bounceidleanim || animTarget == wolfidle || animTarget == walkanim || animTarget == drawrightanim || animTarget == crouchdrawrightanim || animTarget == drawleftanim || animTarget == fightidleanim || animTarget == fightsidestep || animTarget == hanganim || isCrouch() || animTarget == backhandspringanim) {
5395 //open hands and close mouth
5396 if (righthandmorphend != 0 && righthandmorphness == targetrighthandmorphness) {
5397 righthandmorphness = 0;
5398 righthandmorphend = 0;
5399 targetrighthandmorphness = 1;
5402 if (lefthandmorphend != 0 && lefthandmorphness == targetlefthandmorphness) {
5403 lefthandmorphness = 0;
5404 lefthandmorphend = 0;
5405 targetlefthandmorphness = 1;
5408 if (headmorphend != 3 && headmorphend != 5 && headmorphstart != 3 && headmorphstart != 5 && headmorphend != 0 && headmorphness == targetheadmorphness) {
5411 targetheadmorphness = 1;
5415 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) {
5416 //open hands and mouth
5417 if (righthandmorphend != 0 && righthandmorphness == targetrighthandmorphness) {
5418 righthandmorphness = 0;
5419 righthandmorphend = 0;
5420 targetrighthandmorphness = 1;
5423 if (lefthandmorphend != 0 && lefthandmorphness == targetlefthandmorphness) {
5424 lefthandmorphness = 0;
5425 lefthandmorphend = 0;
5426 targetlefthandmorphness = 1;
5429 if (headmorphend != 1 && headmorphness == targetheadmorphness) {
5432 targetheadmorphness = 1;
5436 if (animTarget == jumpupanim || animTarget == crouchstabanim || animTarget == swordgroundstabanim || animTarget == swordfightidlebothanim || animTarget == blockhighleftanim || animTarget == blockhighleftanim) {
5437 //close hands and mouth
5438 if (righthandmorphend != 1 && righthandmorphness == targetrighthandmorphness) {
5439 righthandmorphness = 0;
5440 righthandmorphend = 1;
5441 targetrighthandmorphness = 1;
5444 if (lefthandmorphend != 1 && lefthandmorphness == targetlefthandmorphness) {
5445 lefthandmorphness = 0;
5446 lefthandmorphend = 1;
5447 targetlefthandmorphness = 1;
5450 if (headmorphend != 0 && headmorphness == targetheadmorphness) {
5453 targetheadmorphness = 1;
5457 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) {
5458 //close hands and yell
5459 if (righthandmorphend != 1 && righthandmorphness == targetrighthandmorphness) {
5460 righthandmorphness = 0;
5461 righthandmorphend = 1;
5462 targetrighthandmorphness = 1;
5465 if (lefthandmorphend != 1 && lefthandmorphness == targetlefthandmorphness) {
5466 lefthandmorphness = 0;
5467 lefthandmorphend = 1;
5468 targetlefthandmorphness = 1;
5471 if (headmorphend != 2 && headmorphness == targetheadmorphness) {
5474 targetheadmorphness = 1;
5481 if (victim != this && !victim->dead && victim->aitype != passivetype && victim->aitype != searchtype && aitype != passivetype && aitype != searchtype && victim->id < numplayers && aitype != passivetype) {
5482 behind = (normaldotproduct(facing, coords - victim->coords) > 0);
5486 if (!dead && animTarget != hurtidleanim)
5487 if (behind || animTarget == killanim || animTarget == knifethrowanim || animTarget == knifefollowanim || animTarget == spinkickreversalanim || animTarget == rabbitkickreversedanim || animTarget == jumpreversedanim) {
5488 if (headmorphend != 4 || headmorphness == targetheadmorphness) {
5491 targetheadmorphness = 1;
5495 if (weaponactive != -1) {
5496 if (weapons[weaponids[weaponactive]].getType() != staff) {
5497 righthandmorphstart = 1;
5498 righthandmorphend = 1;
5500 if (weapons[weaponids[weaponactive]].getType() == staff) {
5501 righthandmorphstart = 2;
5502 righthandmorphend = 2;
5504 targetrighthandmorphness = 1;
5507 terrainnormal = terrain.getNormal(coords.x, coords.z);
5509 if (animation[animTarget].attack != reversal) {
5510 if (!isnormal(coords.x))
5518 flatfacing = DoRotation(flatfacing, 0, yaw, 0);
5519 facing = flatfacing;
5520 ReflectVector(&facing, terrainnormal);
5523 if (isRun() || animTarget == sneakanim || animTarget == rollanim || animTarget == walkanim) {
5525 targettilt2 = -facing.y * 20;
5530 if (!isRun() && !animation[animTarget].attack && animTarget != getupfromfrontanim && animTarget != getupfrombackanim && animTarget != sneakanim)
5532 if (animTarget == jumpupanim || animTarget == jumpdownanim || isFlip()) {
5533 flatvelocity = velocity;
5535 flatvelspeed = findLength(&flatvelocity);
5536 targettilt = flatvelspeed * fast_sqrt(abs(velocity.y) * .7) * normaldotproduct(DoRotation(flatfacing, 0, -90, 0), flatvelocity);
5537 targettilt2 = flatvelspeed * fast_sqrt(abs(velocity.y) * .7) * normaldotproduct(flatfacing, flatvelocity);
5542 if (targettilt > 25)
5544 if (targettilt < -25)
5548 if (targettilt2 > 45)
5550 if (targettilt2 < -45)
5552 if (abs(tilt2 - targettilt2) < multiplier * 400)
5553 tilt2 = targettilt2;
5554 else if (tilt2 > targettilt2) {
5555 tilt2 -= multiplier * 400;
5556 } else if (tilt2 < targettilt2) {
5557 tilt2 += multiplier * 400;
5559 if (!animation[animTarget].attack && animTarget != getupfrombackanim && animTarget != getupfromfrontanim) {
5566 if (!isnormal(targettilt) && targettilt) {
5569 if (!isnormal(targettilt2) && targettilt2) {
5574 //if(!creature==wolftype||animTarget==rabbitkickanim)
5575 if (animTarget == rabbittackleanim) {
5576 velocity += facing * multiplier * speed * 700 * scale;
5577 velspeed = findLength(&velocity);
5578 if (velspeed > speed * 65 * scale) {
5579 velocity /= velspeed;
5580 velspeed = speed * 65 * scale;
5581 velocity *= velspeed;
5583 velocity.y += gravity * multiplier * 20;
5584 ReflectVector(&velocity, terrain.getNormal(coords.x, coords.z));
5585 velspeed = findLength(&velocity);
5586 velocity = flatfacing * velspeed;
5588 if (animTarget != rabbitrunninganim && animTarget != wolfrunninganim) {
5589 if (isRun() || animTarget == rabbitkickanim) {
5590 velocity += facing * multiplier * speed * 700 * scale;
5591 velspeed = findLength(&velocity);
5592 if (velspeed > speed * 45 * scale) {
5593 velocity /= velspeed;
5594 velspeed = speed * 45 * scale;
5595 velocity *= velspeed;
5597 velocity.y += gravity * multiplier * 20;
5598 ReflectVector(&velocity, terrain.getNormal(coords.x, coords.z));
5599 velspeed = findLength(&velocity);
5600 if (velspeed < speed * 30 * scale)
5601 velspeed = speed * 30 * scale;
5602 velocity = flatfacing * velspeed;
5604 } else if (isRun()) {
5605 velocity += facing * multiplier * speed * 700 * scale;
5606 velspeed = findLength(&velocity);
5607 if (creature == rabbittype) {
5608 if (velspeed > speed * 55 * scale) {
5609 velocity /= velspeed;
5610 velspeed = speed * 55 * scale;
5611 velocity *= velspeed;
5614 if (creature == wolftype) {
5615 if (velspeed > speed * 75 * scale) {
5616 velocity /= velspeed;
5617 velspeed = speed * 75 * scale;
5618 velocity *= velspeed;
5621 velocity.y += gravity * multiplier * 20;
5622 ReflectVector(&velocity, terrain.getNormal(coords.x, coords.z));
5623 velspeed = findLength(&velocity);
5624 velocity = flatfacing * velspeed;
5627 if (animTarget == rollanim && animation[animTarget].label[frameTarget] != 6) {
5628 velocity += facing * multiplier * speed * 700 * scale;
5629 velspeed = findLength(&velocity);
5630 if (velspeed > speed * 45 * scale) {
5631 velocity /= velspeed;
5632 velspeed = speed * 45 * scale;
5633 velocity *= velspeed;
5635 velocity.y += gravity * multiplier * 20;
5636 ReflectVector(&velocity, terrain.getNormal(coords.x, coords.z));
5637 velspeed = findLength(&velocity);
5638 velocity = flatfacing * velspeed;
5642 /*if(animCurrent==rollanim&&(isCrouch()||isIdle())){
5643 velocity+=facing*multiplier*speed*700*scale;
5644 velspeed=findLength(&velocity);
5645 if(velspeed>speed*25*scale){
5647 velspeed=speed*25*scale;
5650 velocity.y+=gravity*multiplier*20;
5651 ReflectVector(&velocity,terrain.getNormal(coords.x,coords.z));
5652 velspeed=findLength(&velocity);
5653 velocity=flatfacing*velspeed;
5656 if (animTarget == sneakanim || animTarget == walkanim) {
5657 velocity += facing * multiplier * speed * 700 * scale;
5658 velspeed = findLength(&velocity);
5659 if (velspeed > speed * 12 * scale) {
5660 velocity /= velspeed;
5661 velspeed = speed * 12 * scale;
5662 velocity *= velspeed;
5664 velocity.y += gravity * multiplier * 20;
5665 ReflectVector(&velocity, terrain.getNormal(coords.x, coords.z));
5666 velspeed = findLength(&velocity);
5667 velocity = flatfacing * velspeed;
5670 if ((animTarget == fightidleanim || animTarget == knifefightidleanim) && (animCurrent == bounceidleanim || animCurrent == hurtidleanim)) {
5671 velocity += facing * multiplier * speed * 700 * scale;
5672 velspeed = findLength(&velocity);
5673 if (velspeed > speed * 2 * scale) {
5674 velocity /= velspeed;
5675 velspeed = speed * 2 * scale;
5676 velocity *= velspeed;
5678 velocity.y += gravity * multiplier * 20;
5679 ReflectVector(&velocity, terrain.getNormal(coords.x, coords.z));
5680 velspeed = findLength(&velocity);
5681 velocity = flatfacing * velspeed;
5685 if ((animTarget == bounceidleanim || animCurrent == hurtidleanim) && (animCurrent == fightidleanim || animCurrent == knifefightidleanim)) {
5686 velocity -= facing * multiplier * speed * 700 * scale;
5687 velspeed = findLength(&velocity);
5688 if (velspeed > speed * 2 * scale) {
5689 velocity /= velspeed;
5690 velspeed = speed * 2 * scale;
5691 velocity *= velspeed;
5693 velocity.y += gravity * multiplier * 20;
5694 ReflectVector(&velocity, terrain.getNormal(coords.x, coords.z));
5695 velspeed = findLength(&velocity);
5696 velocity = flatfacing * velspeed * -1;
5699 if (animTarget == fightsidestep) {
5700 velocity += DoRotation(facing * multiplier * speed * 700 * scale, 0, -90, 0);
5701 velspeed = findLength(&velocity);
5702 if (velspeed > speed * 12 * scale) {
5703 velocity /= velspeed;
5704 velspeed = speed * 12 * scale;
5705 velocity *= velspeed;
5707 velocity.y += gravity * multiplier * 20;
5708 ReflectVector(&velocity, terrain.getNormal(coords.x, coords.z));
5709 velspeed = findLength(&velocity);
5710 velocity = DoRotation(flatfacing * velspeed, 0, -90, 0);
5713 if (animTarget == staggerbackhighanim) {
5714 coords -= facing * multiplier * speed * 16 * scale;
5717 if (animTarget == staggerbackhardanim && animation[staggerbackhardanim].label[frameTarget] != 6) {
5718 coords -= facing * multiplier * speed * 20 * scale;
5722 if (animTarget == backhandspringanim) {
5723 //coords-=facing*multiplier*50*scale;
5724 velocity += facing * multiplier * speed * 700 * scale * -1;
5725 velspeed = findLength(&velocity);
5726 if (velspeed > speed * 50 * scale) {
5727 velocity /= velspeed;
5728 velspeed = speed * 50 * scale;
5729 velocity *= velspeed;
5731 velocity.y += gravity * multiplier * 20;
5732 ReflectVector(&velocity, terrain.getNormal(coords.x, coords.z));
5733 velspeed = findLength(&velocity);
5734 velocity = flatfacing * velspeed * -1;
5736 if (animTarget == dodgebackanim) {
5737 //coords-=facing*multiplier*50*scale;
5738 velocity += facing * multiplier * speed * 700 * scale * -1;
5739 velspeed = findLength(&velocity);
5740 if (velspeed > speed * 60 * scale) {
5741 velocity /= velspeed;
5742 velspeed = speed * 60 * scale;
5743 velocity *= velspeed;
5745 velocity.y += gravity * multiplier * 20;
5746 ReflectVector(&velocity, terrain.getNormal(coords.x, coords.z));
5747 velspeed = findLength(&velocity);
5748 velocity = flatfacing * velspeed * -1;
5751 if (animTarget == jumpupanim || animTarget == jumpdownanim || isFlip()) {
5752 velspeed = findLength(&velocity);
5756 if (animTarget == jumpupanim || animTarget == jumpdownanim || isFlip()) {
5757 velocity.y += gravity * multiplier;
5760 if (animTarget != climbanim && animTarget != hanganim && !isWallJump())
5761 coords += velocity * multiplier;
5763 if (coords.y < terrain.getHeight(coords.x, coords.z) && (animTarget == jumpdownanim || animTarget == jumpupanim || isFlip())) {
5764 if (isFlip() && animation[animTarget].label[frameTarget] == 7)
5767 if (animTarget == jumpupanim) {
5769 animTarget = getIdle();
5776 pause_sound(whooshsound);
5777 OPENAL_SetVolume(channels[whooshsound], 0);
5780 if (animTarget == jumpdownanim || isFlip()) {
5781 if (isFlip())jumppower = -4;
5782 animTarget = getLanding();
5783 emit_sound_at(landsound, coords, 128.);
5786 envsound[numenvsounds] = coords;
5787 envsoundvol[numenvsounds] = 16;
5788 envsoundlife[numenvsounds] = .4;
5794 if (animTarget != jumpupanim && animTarget != jumpdownanim && !isFlip() && animTarget != climbanim && animTarget != hanganim && !isWallJump())
5795 coords.y += gravity * multiplier * 2;
5796 if (animTarget != jumpupanim && animTarget != jumpdownanim && !isFlip() && coords.y < terrain.getHeight(coords.x, coords.z)) {
5797 coords.y = terrain.getHeight(coords.x, coords.z);
5802 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)) {
5803 velspeed = findLength(&velocity);
5805 if (velspeed < multiplier * 300 * scale) {
5808 velocity -= velocity / velspeed * multiplier * 300 * scale;
5809 if (velspeed > 5 && (isLanding() || isLandhard())) {
5810 skiddingdelay += multiplier;
5811 if (skiddelay <= 0) {
5821 velspeed = findLength(&velocity);
5823 if (velspeed < multiplier * 600 * scale) {
5826 velocity -= velocity / velspeed * multiplier * 600 * scale;
5828 if (velspeed > 5 && (isLanding() || isLandhard())) {
5829 skiddingdelay += multiplier;
5830 if (skiddelay <= 0) {
5839 if (skiddingdelay < 0)
5840 skiddingdelay += multiplier;
5841 if (skiddingdelay > .02 && !forwardkeydown && !backkeydown && !leftkeydown && !rightkeydown && !jumpkeydown && isLanding() && !landhard) {
5843 if (!onterrain || environment == grassyenvironment) {
5844 emit_sound_at(skidsound, coords, 128 * velspeed / 10);
5846 emit_sound_at(snowskidsound, coords, 128 * velspeed / 10);
5850 if (animation[animTarget].attack == normalattack && animTarget != rabbitkickanim && !victim->skeleton.free) {
5851 terrainnormal = victim->coords - coords;
5852 Normalise(&terrainnormal);
5853 targetyaw = -asin(0 - terrainnormal.x);
5854 targetyaw *= 360 / 6.28;
5855 if (terrainnormal.z < 0)
5856 targetyaw = 180 - targetyaw;
5857 targettilt2 = -asin(terrainnormal.y) * 360 / 6.28; //*-70;
5860 if (animation[animTarget].attack == reversal && animTarget != rabbittacklinganim) {
5861 targetyaw = victim->targetyaw;
5863 if (animTarget == rabbittacklinganim) {
5864 coords = victim->coords;
5867 skeleton.oldfree = skeleton.free;
5871 midterrain.x = terrain.size * terrain.scale / 2;
5872 midterrain.z = terrain.size * terrain.scale / 2;
5873 if (distsqflat(&coords, &midterrain) > (terrain.size * terrain.scale / 2 - viewdistance) * (terrain.size * terrain.scale / 2 - viewdistance)) {
5875 tempposit = coords - midterrain;
5877 Normalise(&tempposit);
5878 tempposit *= (terrain.size * terrain.scale / 2 - viewdistance);
5879 coords.x = tempposit.x + midterrain.x;
5880 coords.z = tempposit.z + midterrain.z;
5886 * inverse kinematics helper function
5888 void IKHelper(Person *p, float interp)
5890 XYZ point, newpoint, change, change2;
5891 float heightleft, heightright;
5893 // TODO: implement localToWorld and worldToLocal
5894 // but keep in mind it won't be the same math if player is ragdolled or something
5895 // - localToWorldStanding / worldToLocalStanding (or crouching or...?)
5896 // then comb through code for places where to use it
5898 // point = localToWorld(jointPos(leftfoot))
5899 point = DoRotation(p->jointPos(leftfoot), 0, p->yaw, 0) * p->scale + p->coords;
5900 // adjust height of foot
5901 heightleft = terrain.getHeight(point.x, point.z) + .04;
5902 point.y = heightleft;
5903 change = p->jointPos(leftankle) - p->jointPos(leftfoot);
5904 change2 = p->jointPos(leftknee) - p->jointPos(leftfoot);
5905 // jointPos(leftfoot) = interpolate(worldToLocal(point), jointPos(leftfoot), interp)
5906 p->jointPos(leftfoot) = DoRotation((point - p->coords) / p->scale, 0, -p->yaw, 0) * interp + p->jointPos(leftfoot) * (1 - interp);
5907 // move ankle along with foot
5908 p->jointPos(leftankle) = p->jointPos(leftfoot) + change;
5909 // average knee pos between old and new pos
5910 p->jointPos(leftknee) = (p->jointPos(leftfoot) + change2) / 2 + (p->jointPos(leftknee)) / 2;
5912 // do same as above for right leg
5913 point = DoRotation(p->jointPos(rightfoot), 0, p->yaw, 0) * p->scale + p->coords;
5914 heightright = terrain.getHeight(point.x, point.z) + .04;
5915 point.y = heightright;
5916 change = p->jointPos(rightankle) - p->jointPos(rightfoot);
5917 change2 = p->jointPos(rightknee) - p->jointPos(rightfoot);
5918 p->jointPos(rightfoot) = DoRotation((point - p->coords) / p->scale, 0, -p->yaw, 0) * interp + p->jointPos(rightfoot) * (1 - interp);
5919 p->jointPos(rightankle) = p->jointPos(rightfoot) + change;
5920 p->jointPos(rightknee) = (p->jointPos(rightfoot) + change2) / 2 + (p->jointPos(rightknee)) / 2;
5922 // fix up skeleton now that we've moved body parts?
5923 p->skeleton.DoConstraints(&p->coords, &p->scale);
5930 int Person::DrawSkeleton()
5932 int oldplayerdetail;
5933 if ((frustum.SphereInFrustum(coords.x, coords.y + scale * 3, coords.z, scale * 8) && distsq(&viewer, &coords) < viewdistance * viewdistance) || skeleton.free == 3) {
5934 if (onterrain && (isIdle() || isCrouch() || wasIdle() || wasCrouch()) && !skeleton.free) {
5944 glAlphaFunc(GL_GREATER, 0.0001);
5946 float terrainheight;
5950 if (!isnormal(tilt))
5952 if (!isnormal(tilt2))
5954 oldplayerdetail = playerdetail;
5956 if (distsq(&viewer, &coords) < viewdistance * viewdistance / 32 && detail == 2) {
5959 if (distsq(&viewer, &coords) < viewdistance * viewdistance / 128 && detail == 1) {
5962 if (distsq(&viewer, &coords) < viewdistance * viewdistance / 256 && (detail != 1 && detail != 2)) {
5967 if (playerdetail != oldplayerdetail) {
5969 normalsupdatedelay = 0;
5971 static float updatedelaychange;
5972 static float morphness;
5973 static float framemult;
5975 skeleton.FindForwards();
5976 if (howactive == typesittingwall) {
5977 skeleton.specialforward[1] = 0;
5978 skeleton.specialforward[1].z = 1;
5984 static int weaponattachmuscle;
5985 static int weaponrotatemuscle;
5986 static XYZ weaponpoint;
5987 static int start, endthing;
5988 if ((dead != 2 || skeleton.free != 2) && updatedelay <= 0) {
5989 if (!isSleeping() && !isSitting()) {
5990 // TODO: give these meaningful names
5991 const bool cond1 = (isIdle() || isCrouch() || isLanding() || isLandhard()
5992 || animTarget == drawrightanim || animTarget == drawleftanim || animTarget == crouchdrawrightanim);
5993 const bool cond2 = (wasIdle() || wasCrouch() || wasLanding() || wasLandhard()
5994 || animCurrent == drawrightanim || animCurrent == drawleftanim || animCurrent == crouchdrawrightanim);
5996 if (onterrain && (cond1 && cond2) && !skeleton.free) {
5998 if (creature == wolftype)
6002 if (onterrain && (cond1 && !cond2) && !skeleton.free) {
6003 IKHelper(this, target);
6004 if (creature == wolftype)
6005 IKHelper(this, target);
6008 if (onterrain && (!cond1 && cond2) && !skeleton.free) {
6009 IKHelper(this, 1 - target);
6010 if (creature == wolftype)
6011 IKHelper(this, 1 - target);
6015 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()))
6018 targetheadyaw = -targetyaw;
6019 targetheadpitch = 0;
6020 if (animation[animTarget].attack == 3)
6021 targetheadyaw += 180;
6023 for (i = 0; i < skeleton.drawmodel.vertexNum; i++) {
6024 skeleton.drawmodel.vertex[i] = 0;
6025 skeleton.drawmodel.vertex[i].y = 999;
6027 for (i = 0; i < skeleton.drawmodellow.vertexNum; i++) {
6028 skeleton.drawmodellow.vertex[i] = 0;
6029 skeleton.drawmodellow.vertex[i].y = 999;
6031 for (i = 0; i < skeleton.drawmodelclothes.vertexNum; i++) {
6032 skeleton.drawmodelclothes.vertex[i] = 0;
6033 skeleton.drawmodelclothes.vertex[i].y = 999;
6035 for (i = 0; i < skeleton.num_muscles; i++) {
6036 // convenience renames
6037 const int p1 = skeleton.muscles[i].parent1->label;
6038 const int p2 = skeleton.muscles[i].parent2->label;
6040 if ((skeleton.muscles[i].numvertices > 0 && playerdetail) || (skeleton.muscles[i].numverticeslow > 0 && !playerdetail)) {
6045 if (p1 == righthand || p2 == righthand) {
6046 morphness = righthandmorphness;
6047 start = righthandmorphstart;
6048 endthing = righthandmorphend;
6050 if (p1 == lefthand || p2 == lefthand) {
6051 morphness = lefthandmorphness;
6052 start = lefthandmorphstart;
6053 endthing = lefthandmorphend;
6055 if (p1 == head || p2 == head) {
6056 morphness = headmorphness;
6057 start = headmorphstart;
6058 endthing = headmorphend;
6060 if ((p1 == neck && p2 == abdomen) || (p2 == neck && p1 == abdomen)) {
6061 morphness = chestmorphness;
6062 start = chestmorphstart;
6063 endthing = chestmorphend;
6065 if ((p1 == groin && p2 == abdomen) || (p2 == groin && p1 == abdomen)) {
6066 morphness = tailmorphness;
6067 start = tailmorphstart;
6068 endthing = tailmorphend;
6071 skeleton.FindRotationMuscle(i, animTarget);
6072 mid = (skeleton.muscles[i].parent1->position + skeleton.muscles[i].parent2->position) / 2;
6073 glMatrixMode(GL_MODELVIEW);
6077 glRotatef(tilt2, 1, 0, 0);
6079 glRotatef(tilt, 0, 0, 1);
6082 glTranslatef(mid.x, mid.y, mid.z);
6084 skeleton.muscles[i].lastrotate1 = skeleton.muscles[i].rotate1;
6085 glRotatef(-skeleton.muscles[i].lastrotate1 + 90, 0, 1, 0);
6087 skeleton.muscles[i].lastrotate2 = skeleton.muscles[i].rotate2;
6088 glRotatef(-skeleton.muscles[i].lastrotate2 + 90, 0, 0, 1);
6090 skeleton.muscles[i].lastrotate3 = skeleton.muscles[i].rotate3;
6091 glRotatef(-skeleton.muscles[i].lastrotate3, 0, 1, 0);
6093 if (playerdetail || skeleton.free == 3) {
6094 for (j = 0; j < skeleton.muscles[i].numvertices; j++) {
6095 XYZ &v0 = skeleton.model[start].vertex[skeleton.muscles[i].vertices[j]];
6096 XYZ &v1 = skeleton.model[endthing].vertex[skeleton.muscles[i].vertices[j]];
6097 glMatrixMode(GL_MODELVIEW);
6099 if (p1 == abdomen || p2 == abdomen)
6100 glTranslatef((v0.x * (1 - morphness) + v1.x * morphness) * proportionbody.x,
6101 (v0.y * (1 - morphness) + v1.y * morphness) * proportionbody.y,
6102 (v0.z * (1 - morphness) + v1.z * morphness) * proportionbody.z);
6103 if (p1 == lefthand || p1 == righthand || p1 == leftwrist || p1 == rightwrist || p1 == leftelbow || p1 == rightelbow || p2 == leftelbow || p2 == rightelbow)
6104 glTranslatef((v0.x * (1 - morphness) + v1.x * morphness) * proportionarms.x,
6105 (v0.y * (1 - morphness) + v1.y * morphness) * proportionarms.y,
6106 (v0.z * (1 - morphness) + v1.z * morphness) * proportionarms.z);
6107 if (p1 == leftfoot || p1 == rightfoot || p1 == leftankle || p1 == rightankle || p1 == leftknee || p1 == rightknee || p2 == leftknee || p2 == rightknee)
6108 glTranslatef((v0.x * (1 - morphness) + v1.x * morphness) * proportionlegs.x,
6109 (v0.y * (1 - morphness) + v1.y * morphness) * proportionlegs.y,
6110 (v0.z * (1 - morphness) + v1.z * morphness) * proportionlegs.z);
6111 if (p1 == head || p2 == head)
6112 glTranslatef((v0.x * (1 - morphness) + v1.x * morphness) * proportionhead.x,
6113 (v0.y * (1 - morphness) + v1.y * morphness) * proportionhead.y,
6114 (v0.z * (1 - morphness) + v1.z * morphness) * proportionhead.z);
6115 glGetFloatv(GL_MODELVIEW_MATRIX, M);
6116 //if(!isnormal(M[12])||!isnormal(M[13])||!isnormal(M[14]))test=0;
6117 //if(!isnormal(scale))test=1;
6118 skeleton.drawmodel.vertex[skeleton.muscles[i].vertices[j]].x = M[12] * scale;
6119 skeleton.drawmodel.vertex[skeleton.muscles[i].vertices[j]].y = M[13] * scale;
6120 skeleton.drawmodel.vertex[skeleton.muscles[i].vertices[j]].z = M[14] * scale;
6125 if (!playerdetail || skeleton.free == 3) {
6126 for (j = 0; j < skeleton.muscles[i].numverticeslow; j++) {
6127 XYZ &v0 = skeleton.modellow.vertex[skeleton.muscles[i].verticeslow[j]];
6128 glMatrixMode(GL_MODELVIEW);
6130 if (p1 == abdomen || p2 == abdomen)
6131 glTranslatef(v0.x * proportionbody.x,
6132 v0.y * proportionbody.y,
6133 v0.z * proportionbody.z);
6134 if (p1 == lefthand || p1 == righthand || p1 == leftwrist || p1 == rightwrist || p1 == leftelbow || p1 == rightelbow || p2 == leftelbow || p2 == rightelbow)
6135 glTranslatef(v0.x * proportionarms.x,
6136 v0.y * proportionarms.y,
6137 v0.z * proportionarms.z);
6138 if (p1 == leftfoot || p1 == rightfoot || p1 == leftankle || p1 == rightankle || p1 == leftknee || p1 == rightknee || p2 == leftknee || p2 == rightknee)
6139 glTranslatef(v0.x * proportionlegs.x,
6140 v0.y * proportionlegs.y,
6141 v0.z * proportionlegs.z);
6142 if (p1 == head || p2 == head)
6143 glTranslatef(v0.x * proportionhead.x,
6144 v0.y * proportionhead.y,
6145 v0.z * proportionhead.z);
6147 glGetFloatv(GL_MODELVIEW_MATRIX, M);
6148 skeleton.drawmodellow.vertex[skeleton.muscles[i].verticeslow[j]].x = M[12] * scale;
6149 skeleton.drawmodellow.vertex[skeleton.muscles[i].verticeslow[j]].y = M[13] * scale;
6150 skeleton.drawmodellow.vertex[skeleton.muscles[i].verticeslow[j]].z = M[14] * scale;
6156 if (skeleton.clothes && skeleton.muscles[i].numverticesclothes > 0) {
6157 mid = (skeleton.muscles[i].parent1->position + skeleton.muscles[i].parent2->position) / 2;
6159 glMatrixMode(GL_MODELVIEW);
6163 glRotatef(tilt2, 1, 0, 0);
6165 glRotatef(tilt, 0, 0, 1);
6166 glTranslatef(mid.x, mid.y, mid.z);
6167 skeleton.muscles[i].lastrotate1 = skeleton.muscles[i].rotate1;
6168 glRotatef(-skeleton.muscles[i].lastrotate1 + 90, 0, 1, 0);
6170 skeleton.muscles[i].lastrotate2 = skeleton.muscles[i].rotate2;
6171 glRotatef(-skeleton.muscles[i].lastrotate2 + 90, 0, 0, 1);
6173 skeleton.muscles[i].lastrotate3 = skeleton.muscles[i].rotate3;
6174 glRotatef(-skeleton.muscles[i].lastrotate3, 0, 1, 0);
6176 for (j = 0; j < skeleton.muscles[i].numverticesclothes; j++) {
6177 XYZ &v0 = skeleton.modelclothes.vertex[skeleton.muscles[i].verticesclothes[j]];
6178 glMatrixMode(GL_MODELVIEW);
6180 if (p1 == abdomen || p2 == abdomen)
6181 glTranslatef(v0.x * proportionbody.x,
6182 v0.y * proportionbody.y,
6183 v0.z * proportionbody.z);
6184 if (p1 == lefthand || p1 == righthand || p1 == leftwrist || p1 == rightwrist || p1 == leftelbow || p1 == rightelbow || p2 == leftelbow || p2 == rightelbow)
6185 glTranslatef(v0.x * proportionarms.x,
6186 v0.y * proportionarms.y,
6187 v0.z * proportionarms.z);
6188 if (p1 == leftfoot || p1 == rightfoot || p1 == leftankle || p1 == rightankle || p1 == leftknee || p1 == rightknee || p2 == leftknee || p2 == rightknee)
6189 glTranslatef(v0.x * proportionlegs.x,
6190 v0.y * proportionlegs.y,
6191 v0.z * proportionlegs.z);
6192 if (p1 == head || p2 == head)
6193 glTranslatef(v0.x * proportionhead.x,
6194 v0.y * proportionhead.y,
6195 v0.z * proportionhead.z);
6196 glGetFloatv(GL_MODELVIEW_MATRIX, M);
6197 skeleton.drawmodelclothes.vertex[skeleton.muscles[i].verticesclothes[j]].x = M[12] * scale;
6198 skeleton.drawmodelclothes.vertex[skeleton.muscles[i].verticesclothes[j]].y = M[13] * scale;
6199 skeleton.drawmodelclothes.vertex[skeleton.muscles[i].verticesclothes[j]].z = M[14] * scale;
6204 updatedelay = 1 + (float)(Random() % 100) / 1000;
6206 if (skeleton.free != 2 && (skeleton.free == 1 || skeleton.free == 3 || id == 0 || (normalsupdatedelay <= 0) || animTarget == getupfromfrontanim || animTarget == getupfrombackanim || animCurrent == getupfromfrontanim || animCurrent == getupfrombackanim)) {
6207 normalsupdatedelay = 1;
6208 if (playerdetail || skeleton.free == 3)
6209 skeleton.drawmodel.CalculateNormals(0);
6210 if (!playerdetail || skeleton.free == 3)
6211 skeleton.drawmodellow.CalculateNormals(0);
6212 if (skeleton.clothes)
6213 skeleton.drawmodelclothes.CalculateNormals(0);
6215 if (playerdetail || skeleton.free == 3)
6216 skeleton.drawmodel.UpdateVertexArrayNoTexNoNorm();
6217 if (!playerdetail || skeleton.free == 3)
6218 skeleton.drawmodellow.UpdateVertexArrayNoTexNoNorm();
6219 if (skeleton.clothes) {
6220 skeleton.drawmodelclothes.UpdateVertexArrayNoTexNoNorm();
6225 updatedelaychange = -framemult * 4 * (45 - findDistance(&viewer, &coords) * 1);
6226 if (updatedelaychange > -realmultiplier * 30)
6227 updatedelaychange = -realmultiplier * 30;
6228 if (updatedelaychange > -framemult * 4)
6229 updatedelaychange = -framemult * 4;
6230 if (skeleton.free == 1)
6231 updatedelaychange *= 6;
6233 updatedelaychange *= 8;
6234 updatedelay += updatedelaychange;
6236 glMatrixMode(GL_MODELVIEW);
6239 glTranslatef(coords.x, coords.y - .02, coords.z);
6241 glTranslatef(coords.x, coords.y - .02, coords.z);
6243 glTranslatef(offset.x * scale, offset.y * scale, offset.z * scale);
6245 glRotatef(yaw, 0, 1, 0);
6248 glColor4f(.4, 1, .4, 1);
6249 glDisable(GL_LIGHTING);
6250 glDisable(GL_TEXTURE_2D);
6253 for (i = 0; i < skeleton.drawmodel.vertexNum; i++) {
6254 XYZ &v0 = skeleton.drawmodel.vertex[i];
6255 glVertex3f(v0.x, v0.y, v0.z);
6261 for (i = 0; i < skeleton.drawmodel.TriangleNum; i++) {
6262 XYZ &v0 = skeleton.drawmodel.vertex[skeleton.drawmodel.Triangles[i].vertex[0]];
6263 XYZ &v1 = skeleton.drawmodel.vertex[skeleton.drawmodel.Triangles[i].vertex[1]];
6264 XYZ &v2 = skeleton.drawmodel.vertex[skeleton.drawmodel.Triangles[i].vertex[2]];
6265 glVertex3f(v0.x, v0.y, v0.z);
6266 glVertex3f(v1.x, v1.y, v1.z);
6267 glVertex3f(v1.x, v1.y, v1.z);
6268 glVertex3f(v2.x, v2.y, v2.z);
6269 glVertex3f(v2.x, v2.y, v2.z);
6270 glVertex3f(v0.x, v0.y, v0.z);
6276 terrainlight = terrain.getLighting(coords.x, coords.z);
6277 distance = distsq(&viewer, &coords);
6278 distance = (viewdistance * viewdistance - (distance - (viewdistance * viewdistance * fadestart)) * (1 / (1 - fadestart))) / viewdistance / viewdistance;
6282 terrainheight = (coords.y - terrain.getHeight(coords.x, coords.z)) / 3 + 1;
6283 if (terrainheight < 1)
6285 if (terrainheight > 1.7)
6286 terrainheight = 1.7;
6289 glColor4f((1 - (1 - terrainlight.x) / terrainheight) - burnt, (1 - (1 - terrainlight.y) / terrainheight) - burnt, (1 - (1 - terrainlight.z) / terrainheight) - burnt, distance);
6290 glDisable(GL_BLEND);
6291 glAlphaFunc(GL_GREATER, 0.0001);
6292 glEnable(GL_TEXTURE_2D);
6294 glDisable(GL_TEXTURE_2D);
6295 glColor4f(.7, .35, 0, .5);
6297 glEnable(GL_LIGHTING);
6300 if (tutoriallevel && id != 0) {
6301 //glDisable(GL_TEXTURE_2D);
6302 glColor4f(.7, .7, .7, 0.6);
6304 glEnable(GL_LIGHTING);
6306 if (canattack && cananger)
6307 if (animation[animTarget].attack == normalattack || animation[animTarget].attack == reversed) {
6308 glDisable(GL_TEXTURE_2D);
6309 glColor4f(1, 0, 0, 0.8);
6311 glMatrixMode(GL_TEXTURE);
6313 glTranslatef(0, -smoketex, 0);
6314 glTranslatef(-smoketex, 0, 0);
6318 if ((tutoriallevel && id != 0))
6319 skeleton.drawmodel.drawdifftex(Sprite::cloudimpacttexture);
6321 skeleton.drawmodel.draw();
6324 if (!playerdetail) {
6325 if ((tutoriallevel && id != 0))
6326 skeleton.drawmodellow.drawdifftex(Sprite::cloudimpacttexture);
6328 skeleton.drawmodellow.drawdifftex(skeleton.drawmodel.textureptr);
6331 if (!(animation[animTarget].attack == normalattack || animation[animTarget].attack == reversed))
6332 if (tutoriallevel && id != 0) {
6334 glMatrixMode(GL_MODELVIEW);
6335 glEnable(GL_TEXTURE_2D);
6336 glColor4f(.7, .7, .7, 0.6);
6338 glEnable(GL_LIGHTING);
6340 if (canattack && cananger)
6341 if (animation[animTarget].attack == normalattack || animation[animTarget].attack == reversed) {
6342 glDisable(GL_TEXTURE_2D);
6343 glColor4f(1, 0, 0, 0.8);
6345 glMatrixMode(GL_TEXTURE);
6347 glTranslatef(0, -smoketex * .6, 0);
6348 glTranslatef(smoketex * .6, 0, 0);
6351 if ((tutoriallevel && id != 0))
6352 skeleton.drawmodel.drawdifftex(Sprite::cloudimpacttexture);
6354 skeleton.drawmodel.draw();
6357 if (!playerdetail) {
6358 if ((tutoriallevel && id != 0))
6359 skeleton.drawmodellow.drawdifftex(Sprite::cloudimpacttexture);
6361 skeleton.drawmodellow.drawdifftex(skeleton.drawmodel.textureptr);
6366 if (tutoriallevel && id != 0) {
6368 glMatrixMode(GL_MODELVIEW);
6369 glEnable(GL_TEXTURE_2D);
6371 if (skeleton.clothes) {
6375 skeleton.drawmodelclothes.draw();
6377 skeleton.drawmodelclothes.drawimmediate();
6383 if (num_weapons > 0) {
6384 for (k = 0; k < num_weapons; k++) {
6386 if (weaponactive == k) {
6387 if (weapons[i].getType() != staff) {
6388 for (j = 0; j < skeleton.num_muscles; j++) {
6389 if ((skeleton.muscles[j].parent1->label == righthand || skeleton.muscles[j].parent2->label == righthand) && skeleton.muscles[j].numvertices > 0) {
6390 weaponattachmuscle = j;
6393 for (j = 0; j < skeleton.num_muscles; j++) {
6394 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) {
6395 weaponrotatemuscle = j;
6398 weaponpoint = (skeleton.muscles[weaponattachmuscle].parent1->position + skeleton.muscles[weaponattachmuscle].parent2->position) / 2;
6399 if (creature == wolftype)
6400 weaponpoint = (jointPos(rightwrist) * .7 + jointPos(righthand) * .3);
6402 if (weapons[i].getType() == staff) {
6403 for (j = 0; j < skeleton.num_muscles; j++) {
6404 if ((skeleton.muscles[j].parent1->label == righthand || skeleton.muscles[j].parent2->label == righthand) && skeleton.muscles[j].numvertices > 0) {
6405 weaponattachmuscle = j;
6408 for (j = 0; j < skeleton.num_muscles; j++) {
6409 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) {
6410 weaponrotatemuscle = j;
6413 //weaponpoint=jointPos(rightwrist);
6414 weaponpoint = (skeleton.muscles[weaponattachmuscle].parent1->position + skeleton.muscles[weaponattachmuscle].parent2->position) / 2;
6415 //weaponpoint+=skeleton.specialforward[1]*.1+(jointPos(rightwrist)-jointPos(rightelbow));
6416 XYZ tempnormthing, vec1, vec2;
6417 vec1 = (jointPos(rightwrist) - jointPos(rightelbow));
6418 vec2 = (jointPos(rightwrist) - jointPos(rightshoulder));
6419 CrossProduct(&vec1, &vec2, &tempnormthing);
6420 Normalise(&tempnormthing);
6421 if (animTarget != staffhitanim && animCurrent != staffhitanim && animTarget != staffgroundsmashanim && animCurrent != staffgroundsmashanim && animTarget != staffspinhitanim && animCurrent != staffspinhitanim)
6422 weaponpoint += tempnormthing * .1 - skeleton.specialforward[1] * .3 + (jointPos(rightwrist) - jointPos(rightelbow));
6425 if (weaponactive != k && weaponstuck != k) {
6426 if (weapons[i].getType() == knife)
6427 weaponpoint = jointPos(abdomen) + (jointPos(righthip) - jointPos(lefthip)) * .1 + (jointPos(rightshoulder) - jointPos(leftshoulder)) * .35;
6428 if (weapons[i].getType() == sword)
6429 weaponpoint = jointPos(abdomen) + (jointPos(lefthip) - jointPos(righthip)) * .09 + (jointPos(leftshoulder) - jointPos(rightshoulder)) * .33;
6430 if (weapons[i].getType() == staff)
6431 weaponpoint = jointPos(abdomen) + (jointPos(lefthip) - jointPos(righthip)) * .09 + (jointPos(leftshoulder) - jointPos(rightshoulder)) * .33;
6432 for (j = 0; j < skeleton.num_muscles; j++) {
6433 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) {
6434 weaponrotatemuscle = j;
6438 if (weaponstuck == k) {
6439 if (weaponstuckwhere == 0)
6440 weaponpoint = jointPos(abdomen) * .5 + jointPos(neck) * .5 - skeleton.forward * .8;
6442 weaponpoint = jointPos(abdomen) * .5 + jointPos(neck) * .5 + skeleton.forward * .8;
6443 for (j = 0; j < skeleton.num_muscles; j++) {
6444 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) {
6445 weaponrotatemuscle = j;
6449 if (skeleton.free) {
6450 weapons[i].position = weaponpoint * scale + coords;
6451 weapons[i].bigrotation = 0;
6452 weapons[i].bigtilt = 0;
6453 weapons[i].bigtilt2 = 0;
6455 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;
6456 weapons[i].bigrotation = yaw;
6457 weapons[i].bigtilt = tilt;
6458 weapons[i].bigtilt2 = tilt2;
6460 weapons[i].rotation1 = skeleton.muscles[weaponrotatemuscle].lastrotate1;
6461 weapons[i].rotation2 = skeleton.muscles[weaponrotatemuscle].lastrotate2;
6462 weapons[i].rotation3 = skeleton.muscles[weaponrotatemuscle].lastrotate3;
6463 if (weaponactive == k) {
6464 if (weapons[i].getType() == knife) {
6465 weapons[i].smallrotation = 180;
6466 weapons[i].smallrotation2 = 0;
6467 if (isCrouch() || wasCrouch()) {
6468 weapons[i].smallrotation2 = 20;
6470 if (animTarget == hurtidleanim) {
6471 weapons[i].smallrotation2 = 50;
6473 if ((animCurrent == crouchstabanim && animTarget == crouchstabanim) || (animCurrent == backhandspringanim && animTarget == backhandspringanim)) {
6474 XYZ temppoint1, temppoint2, tempforward;
6477 temppoint1 = jointPos(righthand);
6478 temppoint2 = animation[animCurrent].weapontarget[frameCurrent] * (1 - target) + animation[animTarget].weapontarget[frameTarget] * (target);
6479 distance = findDistance(&temppoint1, &temppoint2);
6480 weapons[i].rotation2 = asin((temppoint1.y - temppoint2.y) / distance);
6481 weapons[i].rotation2 *= 360 / 6.28;
6484 weapons[i].rotation1 = acos((temppoint1.z - temppoint2.z) / findDistance(&temppoint1, &temppoint2));
6485 weapons[i].rotation1 *= 360 / 6.28;
6486 weapons[i].rotation3 = 0;
6487 weapons[i].smallrotation = -90;
6488 weapons[i].smallrotation2 = 0;
6489 if (temppoint1.x > temppoint2.x)
6490 weapons[i].rotation1 = 360 - weapons[i].rotation1;
6492 if ((animCurrent == knifeslashreversalanim && animTarget == knifeslashreversalanim) || (animCurrent == knifeslashreversedanim && animTarget == knifeslashreversedanim)) {
6493 XYZ temppoint1, temppoint2, tempforward;
6496 temppoint1 = jointPos(righthand);
6497 temppoint2 = animation[animCurrent].weapontarget[frameCurrent] * (1 - target) + animation[animTarget].weapontarget[frameTarget] * (target);
6498 distance = findDistance(&temppoint1, &temppoint2);
6499 weapons[i].rotation2 = asin((temppoint1.y - temppoint2.y) / distance);
6500 weapons[i].rotation2 *= 360 / 6.28;
6503 weapons[i].rotation1 = acos((temppoint1.z - temppoint2.z) / findDistance(&temppoint1, &temppoint2));
6504 weapons[i].rotation1 *= 360 / 6.28;
6505 weapons[i].rotation3 = 0;
6506 weapons[i].smallrotation = 90;
6507 weapons[i].smallrotation2 = 0;
6508 if (temppoint1.x > temppoint2.x)
6509 weapons[i].rotation1 = 360 - weapons[i].rotation1;
6511 if (animTarget == knifethrowanim) {
6512 weapons[i].smallrotation = 90;
6513 //weapons[i].smallrotation2=-90;
6514 weapons[i].smallrotation2 = 0;
6515 weapons[i].rotation1 = 0;
6516 weapons[i].rotation2 = 0;
6517 weapons[i].rotation3 = 0;
6519 if (animTarget == knifesneakattackanim && frameTarget < 5) {
6520 weapons[i].smallrotation = -90;
6521 weapons[i].rotation1 = 0;
6522 weapons[i].rotation2 = 0;
6523 weapons[i].rotation3 = 0;
6526 if (weapons[i].getType() == sword) {
6527 weapons[i].smallrotation = 0;
6528 weapons[i].smallrotation2 = 0;
6529 if (animTarget == knifethrowanim) {
6530 weapons[i].smallrotation = -90;
6531 weapons[i].smallrotation2 = 0;
6532 weapons[i].rotation1 = 0;
6533 weapons[i].rotation2 = 0;
6534 weapons[i].rotation3 = 0;
6536 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)) {
6537 XYZ temppoint1, temppoint2, tempforward;
6540 temppoint1 = animation[animCurrent].position[skeleton.jointlabels[righthand]][frameCurrent] * (1 - target) + animation[animTarget].position[skeleton.jointlabels[righthand]][frameTarget] * (target); //jointPos(righthand);
6541 temppoint2 = animation[animCurrent].weapontarget[frameCurrent] * (1 - target) + animation[animTarget].weapontarget[frameTarget] * (target);
6542 distance = findDistance(&temppoint1, &temppoint2);
6543 weapons[i].rotation2 = asin((temppoint1.y - temppoint2.y) / distance);
6544 weapons[i].rotation2 *= 360 / 6.28;
6547 weapons[i].rotation1 = acos((temppoint1.z - temppoint2.z) / findDistance(&temppoint1, &temppoint2));
6548 weapons[i].rotation1 *= 360 / 6.28;
6549 weapons[i].rotation3 = 0;
6550 weapons[i].smallrotation = 90;
6551 weapons[i].smallrotation2 = 0;
6552 if (temppoint1.x > temppoint2.x)
6553 weapons[i].rotation1 = 360 - weapons[i].rotation1;
6556 if (weapons[i].getType() == staff) {
6557 weapons[i].smallrotation = 100;
6558 weapons[i].smallrotation2 = 0;
6559 if ((animTarget == staffhitanim && animCurrent == staffhitanim) || (animTarget == staffhitreversedanim && animCurrent == staffhitreversedanim) || (animTarget == staffspinhitreversedanim && animCurrent == staffspinhitreversedanim) || (animTarget == staffgroundsmashanim && animCurrent == staffgroundsmashanim) || (animTarget == staffspinhitanim && animCurrent == staffspinhitanim)) {
6560 XYZ temppoint1, temppoint2, tempforward;
6563 temppoint1 = animation[animCurrent].position[skeleton.jointlabels[righthand]][frameCurrent] * (1 - target) + animation[animTarget].position[skeleton.jointlabels[righthand]][frameTarget] * (target); //jointPos(righthand);
6564 temppoint2 = animation[animCurrent].weapontarget[frameCurrent] * (1 - target) + animation[animTarget].weapontarget[frameTarget] * (target);
6565 distance = findDistance(&temppoint1, &temppoint2);
6566 weapons[i].rotation2 = asin((temppoint1.y - temppoint2.y) / distance);
6567 weapons[i].rotation2 *= 360 / 6.28;
6570 weapons[i].rotation1 = acos((temppoint1.z - temppoint2.z) / findDistance(&temppoint1, &temppoint2));
6571 weapons[i].rotation1 *= 360 / 6.28;
6572 weapons[i].rotation3 = 0;
6573 weapons[i].smallrotation = 90;
6574 weapons[i].smallrotation2 = 0;
6575 if (temppoint1.x > temppoint2.x)
6576 weapons[i].rotation1 = 360 - weapons[i].rotation1;
6580 if (weaponactive != k && weaponstuck != k) {
6581 if (weapons[i].getType() == knife) {
6582 weapons[i].smallrotation = -70;
6583 weapons[i].smallrotation2 = 10;
6585 if (weapons[i].getType() == sword) {
6586 weapons[i].smallrotation = -100;
6587 weapons[i].smallrotation2 = -8;
6589 if (weapons[i].getType() == staff) {
6590 weapons[i].smallrotation = -100;
6591 weapons[i].smallrotation2 = -8;
6594 if (weaponstuck == k) {
6595 if (weaponstuckwhere == 0)
6596 weapons[i].smallrotation = 180;
6598 weapons[i].smallrotation = 0;
6599 weapons[i].smallrotation2 = 10;
6608 if (animation[animTarget].attack || isRun() || animTarget == staggerbackhardanim || isFlip() || animTarget == climbanim || animTarget == sneakanim || animTarget == rollanim || animTarget == walkanim || animTarget == backhandspringanim || isFlip() || isWallJump())
6610 if (animCurrent != animTarget)
6612 //if(id==0)calcrot=1;
6613 if (skeleton.free == 2)
6622 int Person::SphereCheck(XYZ *p1, float radius, XYZ *p, XYZ *move, float *rotate, Model *model)
6625 static float distance;
6626 static float olddistance;
6627 static int intersecting;
6628 static int firstintersecting;
6631 static XYZ start, end;
6632 static float slopethreshold = -.4;
6634 firstintersecting = -1;
6638 if (distsq(p1, &model->boundingspherecenter) > radius * radius + model->boundingsphereradius * model->boundingsphereradius)
6641 *p1 = DoRotation(*p1, 0, -*rotate, 0);
6642 for (i = 0; i < 4; i++) {
6643 for (j = 0; j < model->TriangleNum; j++) {
6644 if (model->facenormals[j].y <= slopethreshold) {
6646 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)));
6647 if (distance < radius) {
6648 point = *p1 - model->facenormals[j] * distance;
6649 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]]))
6652 intersecting = sphere_line_intersection(&model->vertex[model->Triangles[j].vertex[0]],
6653 &model->vertex[model->Triangles[j].vertex[1]],
6656 intersecting = sphere_line_intersection(&model->vertex[model->Triangles[j].vertex[1]],
6657 &model->vertex[model->Triangles[j].vertex[2]],
6660 intersecting = sphere_line_intersection(&model->vertex[model->Triangles[j].vertex[0]],
6661 &model->vertex[model->Triangles[j].vertex[2]],
6664 if (dotproduct(&model->facenormals[j], &end) > 0 && intersecting) {
6668 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)) {
6669 p1->y = point.y + radius;
6670 if ((animTarget == jumpdownanim || isFlip())) {
6671 if (isFlip() && (frameTarget < 5 || animation[animTarget].label[frameTarget] == 7 || animation[animTarget].label[frameTarget] == 4))
6674 if (animTarget == jumpupanim) {
6676 animTarget = getIdle();
6683 pause_sound(whooshsound);
6684 OPENAL_SetVolume(channels[whooshsound], 0);
6687 if ((animTarget == jumpdownanim || isFlip()) && !wasLanding() && !wasLandhard()) {
6690 animTarget = getLanding();
6691 emit_sound_at(landsound, coords, 128.);
6694 envsound[numenvsounds] = coords;
6695 envsoundvol[numenvsounds] = 16;
6696 envsoundlife[numenvsounds] = .4;
6704 if ((distance < olddistance || firstintersecting == -1) && intersecting) {
6705 olddistance = distance;
6706 firstintersecting = j;
6711 for (j = 0; j < model->TriangleNum; j++) {
6712 if (model->facenormals[j].y > slopethreshold) {
6715 start.y -= radius / 4;
6716 XYZ &v0 = model->vertex[model->Triangles[j].vertex[0]];
6717 XYZ &v1 = model->vertex[model->Triangles[j].vertex[1]];
6718 XYZ &v2 = model->vertex[model->Triangles[j].vertex[2]];
6719 distance = abs((model->facenormals[j].x * start.x)
6720 + (model->facenormals[j].y * start.y)
6721 + (model->facenormals[j].z * start.z)
6722 - ((model->facenormals[j].x * v0.x)
6723 + (model->facenormals[j].y * v0.y)
6724 + (model->facenormals[j].z * v0.z)));
6725 if (distance < radius * .5) {
6726 point = start - model->facenormals[j] * distance;
6727 if (PointInTriangle( &point, model->facenormals[j], &v0, &v1, &v2))
6730 intersecting = sphere_line_intersection(v0.x, v0.y, v0.z, v1.x, v1.y, v1.z, p1->x, p1->y, p1->z, radius / 2);
6732 intersecting = sphere_line_intersection(v1.x, v1.y, v1.z, v2.x, v2.y, v2.z, p1->x, p1->y, p1->z, radius / 2);
6734 intersecting = sphere_line_intersection(v0.x, v0.y, v0.z, v2.x, v2.y, v2.z, p1->x, p1->y, p1->z, radius / 2);
6736 if (dotproduct(&model->facenormals[j], &end) > 0 && intersecting) {
6737 if ((animTarget == jumpdownanim || animTarget == jumpupanim || isFlip())) {
6739 velocity -= DoRotation(model->facenormals[j], 0, *rotate, 0) * findLength(&velocity) * abs(normaldotproduct(velocity, DoRotation(model->facenormals[j], 0, *rotate, 0))); //(distance-radius*.5)/multiplier;
6740 if (findLengthfast(&start) < findLengthfast(&velocity))
6743 *p1 += model->facenormals[j] * (distance - radius * .5);
6746 if ((distance < olddistance || firstintersecting == -1) && intersecting) {
6747 olddistance = distance;
6748 firstintersecting = j;
6755 *p = DoRotation(*p, 0, *rotate, 0);
6758 *p1 = DoRotation(*p1, 0, *rotate, 0);
6760 return firstintersecting;