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 modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 2 of the License, or
9 (at your option) any later version.
11 Lugaru 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. See the
14 GNU General Public License for more details.
16 You should have received a copy of the GNU General Public License
17 along with Lugaru. If not, see <http://www.gnu.org/licenses/>.
20 /**> HEADER FILES <**/
22 #include "openal_wrapper.h"
23 #include "Animation.h"
28 extern float multiplier;
29 extern Terrain terrain;
31 extern int environment;
33 extern FRUSTUM frustum;
35 extern float realmultiplier;
37 extern float slomodelay;
38 extern bool cellophane;
39 extern float texdetail;
40 extern float realtexdetail;
41 extern GLubyte bloodText[512 * 512 * 3];
42 extern GLubyte wolfbloodText[512 * 512 * 3];
43 extern int bloodtoggle;
44 extern Objects objects;
45 extern bool autoslomo;
46 extern float camerashake;
48 extern float viewdistance;
49 extern float blackout;
50 extern int difficulty;
52 extern float fadestart;
54 extern bool winfreeze;
55 extern float flashamount, flashr, flashg, flashb;
56 extern int flashdelay;
57 extern bool showpoints;
58 extern bool immediate;
60 extern bool tilt2weird;
61 extern bool tiltweird;
63 extern bool proportionweird;
64 extern bool vertexweird[6];
65 extern XYZ envsound[30];
66 extern float envsoundvol[30];
67 extern float envsoundlife[30];
68 extern int numenvsounds;
69 extern int tutoriallevel;
70 extern float smoketex;
71 extern int tutorialstage;
72 extern bool reversaltrain;
73 extern bool canattack;
75 extern float damagedealt;
77 extern float hostiletime;
79 extern int indialogue;
81 extern bool gamestarted;
83 std::vector<std::shared_ptr<Person>> Person::players(1, std::shared_ptr<Person>(new Person()));
88 * GameTick/doPlayerCollisions
90 void Person::CheckKick()
93 && (animTarget == rabbitkickanim
95 && victim != this->shared_from_this()
97 && animCurrent == rabbitkickanim)
98 && distsq(&coords, &victim->coords) < 1.2
99 && !victim->skeleton.free))
102 if (animation[victim->animTarget].height != lowheight) {
103 float damagemult = (creature == wolftype ? 2.5 : 1.) * power * power;
104 XYZ relative = velocity;
106 Normalise(&relative);
110 if (tutoriallevel != 1)
111 emit_sound_at(heavyimpactsound, victim->coords);
113 for (int i = 0; i < victim->skeleton.num_joints; i++) {
114 victim->skeleton.joints[i].velocity += relative * 120 * damagemult;
117 victim->DoDamage(100 * damagemult / victim->protectionhigh);
123 animTarget = backflipanim;
125 velocity = facing * -10;
129 resume_stream(whooshsound);
131 award_bonus(id, cannon);
132 } else if (victim->isCrouch()) {
133 animTarget = rabbitkickreversedanim;
134 animCurrent = rabbitkickreversedanim;
135 victim->animCurrent = rabbitkickreversalanim;
136 victim->animTarget = rabbitkickreversalanim;
142 victim->oldcoords = victim->coords;
143 coords = victim->coords;
144 victim->targetyaw = targetyaw;
145 victim->victim = this->shared_from_this();
152 * GameTick/doPlayerCollisions - spread fire between players
153 * GameTick/doDebugKeys - press f to ignite
154 * Person::DoStuff - spread fire from lit campfires and bushes
156 void Person::CatchFire()
158 XYZ flatfacing, flatvelocity;
160 for (int i = 0; i < 10; i++) {
161 howmany = abs(Random() % (skeleton.num_joints));
163 flatvelocity = velocity;
165 flatvelocity = skeleton.joints[howmany].velocity;
167 flatfacing = DoRotation(DoRotation(DoRotation(skeleton.joints[howmany].position, 0, 0, tilt), tilt2, 0, 0), 0, yaw, 0) * scale + coords;
169 flatfacing = skeleton.joints[howmany].position * scale + coords;
170 Sprite::MakeSprite(flamesprite, flatfacing, flatvelocity, 1, 1, 1, 2, 1);
175 emit_sound_at(firestartsound, coords);
177 emit_stream_at(stream_firesound, coords);
185 * idle animation for this creature (depending on status)
187 int Person::getIdle()
189 if (indialogue != -1 && howactive == typeactive && creature == rabbittype)
191 if (hasvictim && (victim != this->shared_from_this())/*||(id==0&&attackkeydown)*/)
192 if (/*(id==0&&attackkeydown)||*/(!victim->dead && victim->aitype != passivetype &&
193 victim->aitype != searchtype && aitype != passivetype && aitype != searchtype &&
194 victim->id < Person::players.size())) {
195 if ((aitype == playercontrolled && stunned <= 0 && weaponactive == -1) || pause) {
196 if (creature == rabbittype)
197 return fightidleanim;
198 if (creature == wolftype)
201 if (aitype == playercontrolled && stunned <= 0 && weaponactive != -1) {
202 if (weapons[weaponids[weaponactive]].getType() == knife)
203 return knifefightidleanim;
204 if (weapons[weaponids[weaponactive]].getType() == sword && victim->weaponactive != -1)
205 return swordfightidlebothanim;
206 if (weapons[weaponids[weaponactive]].getType() == sword)
207 return swordfightidleanim;
208 if (weapons[weaponids[weaponactive]].getType() == staff)
209 return swordfightidleanim;
211 if (aitype != playercontrolled && stunned <= 0 && creature != wolftype && !pause)
212 return fightsidestep;
214 if ((damage > permanentdamage || damage > damagetolerance * .8 || deathbleeding > 0) && creature != wolftype)
216 if (howactive == typesitting) return sitanim;
217 if (howactive == typesittingwall) return sitwallanim;
218 if (howactive == typesleeping) return sleepanim;
219 if (howactive == typedead1) return dead1anim;
220 if (howactive == typedead2) return dead2anim;
221 if (howactive == typedead3) return dead3anim;
222 if (howactive == typedead4) return dead4anim;
223 if (creature == rabbittype) return bounceidleanim;
224 if (creature == wolftype) return wolfidle;
229 * crouch animation for this creature
231 int Person::getCrouch()
233 if (creature == rabbittype)
235 if (creature == wolftype)
236 return wolfcrouchanim;
241 * running animation for this creature (can be upright or all fours)
245 if (creature == rabbittype && (!superruntoggle || weaponactive != -1))
247 if (creature == wolftype && (!superruntoggle))
250 if (creature == rabbittype && (superruntoggle && weaponactive == -1))
251 return rabbitrunninganim;
252 if (creature == wolftype && (superruntoggle))
253 return wolfrunninganim;
259 int Person::getStop()
261 if (creature == rabbittype)
263 if (creature == wolftype)
270 int Person::getLanding()
272 if (creature == rabbittype)
274 if (creature == wolftype)
281 int Person::getLandhard()
283 if (creature == rabbittype)
285 if (creature == wolftype)
286 return wolflandhardanim;
293 * Person::DoAnimations
296 SolidHitBonus(int playerid)
298 if (bonustime < 1.5 && bonus >= solidhit && bonus <= megacombo)
299 award_bonus(playerid, bonus == megacombo ? bonus : bonus + 1);
301 award_bonus(playerid, solidhit);
305 * spawns blood effects
307 void Person::DoBlood(float howmuch, int which)
309 // FIXME: should abstract out inputs
310 static int bleedxint, bleedyint;
312 if (bloodtoggle && tutoriallevel != 1) {
313 if (bleeding <= 0 && spurt) {
315 for (int i = 0; i < 3; i++) {
316 // emit blood particles
318 if (!skeleton.free) {
320 bloodvel = DoRotation(bloodvel, ((float)(Random() % 100)) / 4, yaw + ((float)(Random() % 100)) / 4, 0) * scale;
323 bloodvel -= DoRotation(skeleton.forward * 10 * scale, ((float)(Random() % 100)) / 4, ((float)(Random() % 100)) / 4, 0);
326 bloodvel += DoRotation(jointVel(head), ((float)(Random() % 100)) / 4, yaw + ((float)(Random() % 100)) / 4, 0) * scale;
328 bloodvel += DoRotation(velocity, ((float)(Random() % 100)) / 4, ((float)(Random() % 100)) / 4, 0) * scale;
330 Sprite::MakeSprite(bloodsprite, jointPos(head) * scale + coords, bloodvel, 1, 1, 1, .05, 1);
331 Sprite::MakeSprite(bloodflamesprite, jointPos(head) * scale + coords, bloodvel, 1, 1, 1, .3, 1);
333 if (!skeleton.free) {
334 Sprite::MakeSprite(bloodsprite, DoRotation((jointPos(head) + jointPos(neck)) / 2, 0, yaw, 0)*scale + coords, bloodvel, 1, 1, 1, .05, 1);
335 Sprite::MakeSprite(bloodflamesprite, DoRotation((jointPos(head) + jointPos(neck)) / 2, 0, yaw, 0)*scale + coords, bloodvel, 1, 1, 1, .3, 1);
338 if (Random() % 2 == 0) // 50% chance
339 for (int i = 0; i < 3; i++) {
340 if (Random() % 2 != 0) {
341 // emit teeth particles
344 bloodvel -= DoRotation(skeleton.forward * 10 * scale, ((float)(Random() % 100)) / 4, ((float)(Random() % 100)) / 4, 0);
345 bloodvel += DoRotation(jointVel(head), ((float)(Random() % 100)) / 4, yaw + ((float)(Random() % 100)) / 4, 0) * scale;
348 bloodvel = DoRotation(bloodvel, ((float)(Random() % 100)) / 4, yaw + ((float)(Random() % 100)) / 4, 0) * scale;
349 bloodvel += DoRotation(velocity, ((float)(Random() % 100)) / 4, ((float)(Random() % 100)) / 4, 0) * scale;
353 Sprite::MakeSprite(splintersprite, jointPos(head) * scale + coords, bloodvel, 1, 1, 1, .05, 1);
355 Sprite::MakeSprite(splintersprite, DoRotation((jointPos(head) + jointPos(neck)) / 2, 0, yaw, 0)*scale + coords, bloodvel, 1, 1, 1, .05, 1);
357 Sprite::setLastSpriteSpecial(3); // sets it to teeth
362 // FIXME: manipulating attributes
363 bleeding = howmuch + (float)abs(Random() % 100) / 200 - .25;
366 if (creature == rabbittype)
367 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) {
368 bleedxint = abs(Random() % 512);
369 bleedyint = abs(Random() % 512);
371 if (creature == wolftype)
372 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) {
373 bleedxint = abs(Random() % 512);
374 bleedyint = abs(Random() % 512);
378 bleedy /= realtexdetail;
379 bleedx /= realtexdetail;
380 direction = abs(Random() % 2) * 2 - 1;
389 * spawns big blood effects and ???
390 * modifies character's skin texture
392 void Person::DoBloodBig(float howmuch, int which)
394 static int bleedxint, bleedyint, i, j;
396 if (howmuch && id == 0)
399 if (tutoriallevel != 1 || id == 0)
400 if (aitype != playercontrolled && howmuch > 0) {
404 // FIXME: seems to be spawning sounds by manipulating attributes... MESSY!
405 if (creature == wolftype) {
406 int i = abs(Random() % 2);
408 whichsound = snarlsound;
410 whichsound = snarl2sound;
411 envsound[numenvsounds] = coords;
412 envsoundvol[numenvsounds] = 16;
413 envsoundlife[numenvsounds] = .4;
416 if (creature == rabbittype) {
417 int i = abs(Random() % 2);
419 whichsound = rabbitpainsound;
420 if (i == 1 && howmuch >= 2)
421 whichsound = rabbitpain1sound;
422 envsound[numenvsounds] = coords;
423 envsoundvol[numenvsounds] = 16;
424 envsoundlife[numenvsounds] = .4;
428 if (whichsound != -1)
429 emit_sound_at(whichsound, coords);
432 if (id == 0 && howmuch > 0) {
433 // FIXME: manipulating attributes
441 if (bloodtoggle && decals && tutoriallevel != 1) {
442 if (bleeding <= 0 && spurt) {
444 for (int i = 0; i < 3; i++) {
445 // emit blood particles
446 // FIXME: copypaste from above
448 if (!skeleton.free) {
450 bloodvel = DoRotation(bloodvel, ((float)(Random() % 100)) / 4, yaw + ((float)(Random() % 100)) / 4, 0) * scale;
453 bloodvel -= DoRotation(skeleton.forward * 10 * scale, ((float)(Random() % 100)) / 4, ((float)(Random() % 100)) / 4, 0);
456 bloodvel += DoRotation(jointVel(head), ((float)(Random() % 100)) / 4, yaw + ((float)(Random() % 100)) / 4, 0) * scale;
458 bloodvel += DoRotation(velocity, ((float)(Random() % 100)) / 4, ((float)(Random() % 100)) / 4, 0) * scale;
460 Sprite::MakeSprite(bloodsprite, jointPos(head) * scale + coords, bloodvel, 1, 1, 1, .05, 1);
461 Sprite::MakeSprite(bloodflamesprite, jointPos(head) * scale + coords, bloodvel, 1, 1, 1, .3, 1);
463 if (!skeleton.free) {
464 Sprite::MakeSprite(bloodsprite, DoRotation((jointPos(head) + jointPos(neck)) / 2, 0, yaw, 0)*scale + coords, bloodvel, 1, 1, 1, .05, 1);
465 Sprite::MakeSprite(bloodflamesprite, DoRotation((jointPos(head) + jointPos(neck)) / 2, 0, yaw, 0)*scale + coords, bloodvel, 1, 1, 1, .3, 1);
470 // weird texture manipulation code follows.
471 // looks like this is painting blood onto the character's skin texture
472 // FIXME: surely there's a better way
474 int offsetx = 0, offsety = 0;
476 offsety = Random() % 40;
477 offsetx = abs(Random() % 60);
479 if (which == 190 || which == 185) {
480 offsety = Random() % 40;
481 offsetx = abs(Random() % 100) - 20;
484 offsety = Random() % 10;
485 offsetx = Random() % 10;
488 offsety = Random() % 20;
489 offsetx = Random() % 20;
491 if (which == 220 || which == 215) {
501 if (creature == rabbittype)
502 for (i = 0; i < 512; i++) {
503 for (j = 0; j < 512; j++) {
504 if (bloodText[i * 512 * 3 + j * 3 + 0] <= which + 4 && bloodText[i * 512 * 3 + j * 3 + 0] >= which - 4) {
505 if (i < startx) startx = i;
506 if (j < starty) starty = j;
507 if (i > endx) endx = i;
508 if (j > endy) endy = j;
512 if (creature == wolftype)
513 for (i = 0; i < 512; i++) {
514 for (j = 0; j < 512; j++) {
515 if (wolfbloodText[i * 512 * 3 + j * 3 + 0] <= which + 4 && wolfbloodText[i * 512 * 3 + j * 3 + 0] >= which - 4) {
516 if (i < startx) startx = i;
517 if (j < starty) starty = j;
518 if (i > endx) endx = i;
519 if (j > endy) endy = j;
529 if (startx < 0) startx = 0;
530 if (starty < 0) starty = 0;
531 if (endx > 512 - 1) endx = 512 - 1;
532 if (endy > 512 - 1) endy = 512 - 1;
533 if (endx < startx) endx = startx;
534 if (endy < starty) endy = starty;
536 startx /= realtexdetail;
537 starty /= realtexdetail;
538 endx /= realtexdetail;
539 endy /= realtexdetail;
541 int texdetailint = realtexdetail;
543 if (creature == rabbittype)
544 for (i = startx; i < endx; i++) {
545 for (j = starty; j < endy; j++) {
546 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) {
547 color = Random() % 85 + 170;
548 where = i * skeleton.skinsize * 3 + j * 3;
549 if (skeleton.skinText[where + 0] > color / 2)
550 skeleton.skinText[where + 0] = color / 2;
551 skeleton.skinText[where + 1] = 0;
552 skeleton.skinText[where + 2] = 0;
556 if (creature == wolftype)
557 for (i = startx; i < endx; i++) {
558 for (j = starty; j < endy; j++) {
559 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) {
560 color = Random() % 85 + 170;
561 where = i * skeleton.skinsize * 3 + j * 3;
562 if (skeleton.skinText[where + 0] > color / 2)
563 skeleton.skinText[where + 0] = color / 2;
564 skeleton.skinText[where + 1] = 0;
565 skeleton.skinText[where + 2] = 0;
569 skeleton.drawmodel.textureptr.bind();
574 if (creature == rabbittype)
575 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) {
576 bleedxint = abs(Random() % 512);
577 bleedyint = abs(Random() % 512);
579 if (creature == wolftype)
580 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) {
581 bleedxint = abs(Random() % 512);
582 bleedyint = abs(Random() % 512);
584 bleedy = bleedxint + offsetx;
585 bleedx = bleedyint + offsety;
586 bleedy /= realtexdetail;
587 bleedx /= realtexdetail;
592 if (bleedx > skeleton.skinsize - 1)
593 bleedx = skeleton.skinsize - 1;
594 if (bleedy > skeleton.skinsize - 1)
595 bleedy = skeleton.skinsize - 1;
596 direction = abs(Random() % 2) * 2 - 1;
599 bleeding = howmuch + (float)abs(Random() % 100) / 200 - .25;
600 deathbleeding += bleeding;
601 bloodloss += bleeding * 3;
603 if (tutoriallevel != 1 && aitype != playercontrolled && bloodloss > damagetolerance * 2 / 3 && bloodloss < damagetolerance && creature == rabbittype) {
604 if (abs(Random() % 2) == 0) {
605 aitype = gethelptype;
608 aitype = attacktypecutoff;
616 * similar to DoBloodBig
618 bool Person::DoBloodBigWhere(float howmuch, int which, XYZ where)
622 static XYZ startpoint, endpoint, colpoint, movepoint;
623 static float rotationpoint;
625 static XYZ p1, p2, p3, p0;
629 float coordsx, coordsy;
632 if (bloodtoggle && decals && tutoriallevel != 1) {
635 where = DoRotation(where, 0, -yaw, 0);
643 // ray testing for a tri in the character model
644 whichtri = skeleton.drawmodel.LineCheck(&startpoint, &endpoint, &colpoint, &movepoint, &rotationpoint);
645 if (whichtri != -1) {
646 // low level geometry math
648 p1 = skeleton.drawmodel.vertex[skeleton.drawmodel.Triangles[whichtri].vertex[0]];
649 p2 = skeleton.drawmodel.vertex[skeleton.drawmodel.Triangles[whichtri].vertex[1]];
650 p3 = skeleton.drawmodel.vertex[skeleton.drawmodel.Triangles[whichtri].vertex[2]];
652 CrossProduct(p2-p1,p3-p1,&N);
653 CrossProduct(p0-p1,p3-p1,&temp);
654 s = dotproduct(&temp,&N)/findLength(&N);
655 CrossProduct(p2-p1,p1-p0,&temp);
656 t = dotproduct(&temp,&N)/findLength(&N);
659 bary.x = distsq(&p0, &p1);
660 bary.y = distsq(&p0, &p2);
661 bary.z = distsq(&p0, &p3);
663 total = bary.x + bary.y + bary.z;
672 total = bary.x + bary.y + bary.z;
678 gxx.x = skeleton.drawmodel.Triangles[whichtri].gx[0];
679 gxx.y = skeleton.drawmodel.Triangles[whichtri].gx[1];
680 gxx.z = skeleton.drawmodel.Triangles[whichtri].gx[2];
681 gyy.x = skeleton.drawmodel.Triangles[whichtri].gy[0];
682 gyy.y = skeleton.drawmodel.Triangles[whichtri].gy[1];
683 gyy.z = skeleton.drawmodel.Triangles[whichtri].gy[2];
684 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;
685 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;
687 //coordsx=skeleton.drawmodel.Triangles[whichtri].gx[1];
688 //coordsy=skeleton.drawmodel.Triangles[whichtri].gy[1];
690 if (bleeding <= 0 && spurt) {
692 for (int i = 0; i < 3; i++) {
693 // emit blood particles
694 // FIXME: more copypaste code
696 if (!skeleton.free) {
698 bloodvel = DoRotation(bloodvel, ((float)(Random() % 100)) / 4, yaw + ((float)(Random() % 100)) / 4, 0) * scale;
701 bloodvel -= DoRotation(skeleton.forward * 10 * scale, ((float)(Random() % 100)) / 4, ((float)(Random() % 100)) / 4, 0);
704 bloodvel += DoRotation(jointVel(head), ((float)(Random() % 100)) / 4, yaw + ((float)(Random() % 100)) / 4, 0) * scale;
706 bloodvel += DoRotation(velocity, ((float)(Random() % 100)) / 4, ((float)(Random() % 100)) / 4, 0) * scale;
708 Sprite::MakeSprite(bloodsprite, jointPos(head) * scale + coords, bloodvel, 1, 1, 1, .05, 1);
709 Sprite::MakeSprite(bloodflamesprite, jointPos(head) * scale + coords, bloodvel, 1, 1, 1, .3, 1);
711 if (!skeleton.free) {
712 Sprite::MakeSprite(bloodsprite, DoRotation((jointPos(head) + jointPos(neck)) / 2, 0, yaw, 0)*scale + coords, bloodvel, 1, 1, 1, .05, 1);
713 Sprite::MakeSprite(bloodflamesprite, DoRotation((jointPos(head) + jointPos(neck)) / 2, 0, yaw, 0)*scale + coords, bloodvel, 1, 1, 1, .3, 1);
718 // texture manipulation follows
720 int offsetx = 0, offsety = 0;
721 offsetx = (1 + coordsy) * 512 - 291;
722 offsety = coordsx * 512 - 437;
729 if (creature == rabbittype)
730 for (i = 0; i < 512; i++) {
731 for (j = 0; j < 512; j++) {
732 if (bloodText[i * 512 * 3 + j * 3 + 0] <= which + 4 && bloodText[i * 512 * 3 + j * 3 + 0] >= which - 4) {
733 if (i < startx) startx = i;
734 if (j < starty) starty = j;
735 if (i > endx) endx = i;
736 if (j > endy) endy = j;
740 if (creature == wolftype)
741 for (i = 0; i < 512; i++) {
742 for (j = 0; j < 512; j++) {
743 if (wolfbloodText[i * 512 * 3 + j * 3 + 0] <= which + 4 && wolfbloodText[i * 512 * 3 + j * 3 + 0] >= which - 4) {
744 if (i < startx) startx = i;
745 if (j < starty) starty = j;
746 if (i > endx) endx = i;
747 if (j > endy) endy = j;
756 if (startx < 0) startx = 0;
757 if (starty < 0) starty = 0;
758 if (endx > 512 - 1) endx = 512 - 1;
759 if (endy > 512 - 1) endy = 512 - 1;
760 if (endx < startx) endx = startx;
761 if (endy < starty) endy = starty;
763 startx /= realtexdetail;
764 starty /= realtexdetail;
765 endx /= realtexdetail;
766 endy /= realtexdetail;
768 int texdetailint = realtexdetail;
770 if (creature == rabbittype)
771 for (i = startx; i < endx; i++) {
772 for (j = starty; j < endy; j++) {
773 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) {
774 color = Random() % 85 + 170;
775 where = i * skeleton.skinsize * 3 + j * 3;
776 if (skeleton.skinText[where + 0] > color / 2)
777 skeleton.skinText[where + 0] = color / 2;
778 skeleton.skinText[where + 1] = 0;
779 skeleton.skinText[where + 2] = 0;
780 } 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) {
781 color = Random() % 85 + 170;
782 where = i * skeleton.skinsize * 3 + j * 3;
783 if (skeleton.skinText[where + 0] > color / 2)
784 skeleton.skinText[where + 0] = color / 2;
785 skeleton.skinText[where + 1] = 0;
786 skeleton.skinText[where + 2] = 0;
790 if (creature == wolftype)
791 for (i = startx; i < endx; i++) {
792 for (j = starty; j < endy; j++) {
793 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) {
794 color = Random() % 85 + 170;
795 where = i * skeleton.skinsize * 3 + j * 3;
796 if (skeleton.skinText[where + 0] > color / 2)
797 skeleton.skinText[where + 0] = color / 2;
798 skeleton.skinText[where + 1] = 0;
799 skeleton.skinText[where + 2] = 0;
800 } 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) {
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;
810 skeleton.drawmodel.textureptr.bind();
813 bleedy = (1 + coordsy) * 512;
814 bleedx = coordsx * 512;
815 bleedy /= realtexdetail;
816 bleedx /= realtexdetail;
821 if (bleedx > skeleton.skinsize - 1)
822 bleedx = skeleton.skinsize - 1;
823 if (bleedy > skeleton.skinsize - 1)
824 bleedy = skeleton.skinsize - 1;
825 direction = abs(Random() % 2) * 2 - 1;
830 bleeding = howmuch + (float)abs(Random() % 100) / 200 - .25;
831 deathbleeding += bleeding;
832 bloodloss += bleeding * 3;
834 if (tutoriallevel != 1 && aitype != playercontrolled && bloodloss > damagetolerance * 2 / 3 && bloodloss < damagetolerance && creature == rabbittype) {
835 if (abs(Random() % 2) == 0) {
836 aitype = gethelptype;
839 aitype = attacktypecutoff;
850 * guessing this performs a reversal
852 void Person::Reverse()
854 if (!((victim->aitype == playercontrolled
856 || staggerdelay <= 0)
857 && victim->animTarget != jumpupanim
858 && victim->animTarget != jumpdownanim
859 && (tutoriallevel != 1 || cananger)
863 if (normaldotproduct (victim->facing, victim->coords - coords) > 0
864 && (victim->id != 0 || difficulty >= 2)
865 && (creature != wolftype || victim->creature == wolftype))
868 if (animTarget == sweepanim) {
869 animTarget = sweepreversedanim;
870 animCurrent = sweepreversedanim;
871 victim->animCurrent = sweepreversalanim;
872 victim->animTarget = sweepreversalanim;
874 if (animTarget == spinkickanim) {
875 animTarget = spinkickreversedanim;
876 animCurrent = spinkickreversedanim;
877 victim->animCurrent = spinkickreversalanim;
878 victim->animTarget = spinkickreversalanim;
880 if (animTarget == upunchanim || animTarget == rabbittacklinganim) {
881 if (animTarget == rabbittacklinganim) {
884 victim->frameCurrent = 6;
885 victim->frameTarget = 7;
887 animTarget = upunchreversedanim;
888 animCurrent = upunchreversedanim;
889 victim->animCurrent = upunchreversalanim;
890 victim->animTarget = upunchreversalanim;
892 if (animTarget == staffhitanim && distsq(&victim->coords, &coords) < 2 && ((victim->id == 0 && victim->crouchkeydown) || Random() % 4 == 0)) {
893 if (victim->weaponactive != -1) {
894 victim->throwtogglekeydown = 1;
895 weapons[victim->weaponids[0]].owner = -1;
896 weapons[victim->weaponids[0]].velocity = victim->velocity * .2;
897 if (weapons[victim->weaponids[0]].velocity.x == 0)
898 weapons[victim->weaponids[0]].velocity.x = .1;
899 weapons[victim->weaponids[0]].tipvelocity = weapons[victim->weaponids[0]].velocity;
900 weapons[victim->weaponids[0]].missed = 1;
901 weapons[victim->weaponids[0]].freetime = 0;
902 weapons[victim->weaponids[0]].firstfree = 1;
903 weapons[victim->weaponids[0]].physics = 1;
904 victim->num_weapons--;
905 if (victim->num_weapons) {
906 victim->weaponids[0] = victim->weaponids[victim->num_weapons];
907 if (victim->weaponstuck == victim->num_weapons)
908 victim->weaponstuck = 0;
911 victim->weaponactive = -1;
912 for (unsigned j = 0; j < Person::players.size(); j++) {
913 Person::players[j]->wentforweapon = 0;
917 animTarget = staffhitreversedanim;
918 animCurrent = staffhitreversedanim;
919 victim->animCurrent = staffhitreversalanim;
920 victim->animTarget = staffhitreversalanim;
922 if (animTarget == staffspinhitanim && distsq(&victim->coords, &coords) < 2 && ((victim->id == 0 && victim->crouchkeydown) || Random() % 2 == 0)) {
923 if (victim->weaponactive != -1) {
924 victim->throwtogglekeydown = 1;
925 weapons[victim->weaponids[0]].owner = -1;
926 weapons[victim->weaponids[0]].velocity = victim->velocity * .2;
927 if (weapons[victim->weaponids[0]].velocity.x == 0)
928 weapons[victim->weaponids[0]].velocity.x = .1;
929 weapons[victim->weaponids[0]].tipvelocity = weapons[victim->weaponids[0]].velocity;
930 weapons[victim->weaponids[0]].missed = 1;
931 weapons[victim->weaponids[0]].freetime = 0;
932 weapons[victim->weaponids[0]].firstfree = 1;
933 weapons[victim->weaponids[0]].physics = 1;
934 victim->num_weapons--;
935 if (victim->num_weapons) {
936 victim->weaponids[0] = victim->weaponids[victim->num_weapons];
937 if (victim->weaponstuck == victim->num_weapons)
938 victim->weaponstuck = 0;
941 victim->weaponactive = -1;
942 for (unsigned j = 0; j < Person::players.size(); j++) {
943 Person::players[j]->wentforweapon = 0;
946 animTarget = staffspinhitreversedanim;
947 animCurrent = staffspinhitreversedanim;
948 victim->animCurrent = staffspinhitreversalanim;
949 victim->animTarget = staffspinhitreversalanim;
951 if (animTarget == swordslashanim && distsq(&victim->coords, &coords) < 2 && ((victim->id == 0 && victim->crouchkeydown) || Random() % 4 == 0)) {
952 if (victim->weaponactive != -1) {
953 victim->throwtogglekeydown = 1;
954 weapons[victim->weaponids[0]].owner = -1;
955 weapons[victim->weaponids[0]].velocity = victim->velocity * .2;
956 if (weapons[victim->weaponids[0]].velocity.x == 0)
957 weapons[victim->weaponids[0]].velocity.x = .1;
958 weapons[victim->weaponids[0]].tipvelocity = weapons[victim->weaponids[0]].velocity;
959 weapons[victim->weaponids[0]].missed = 1;
960 weapons[victim->weaponids[0]].freetime = 0;
961 weapons[victim->weaponids[0]].firstfree = 1;
962 weapons[victim->weaponids[0]].physics = 1;
963 victim->num_weapons--;
964 if (victim->num_weapons) {
965 victim->weaponids[0] = victim->weaponids[victim->num_weapons];
966 if (victim->weaponstuck == victim->num_weapons)
967 victim->weaponstuck = 0;
970 victim->weaponactive = -1;
971 for (unsigned j = 0; j < Person::players.size(); j++) {
972 Person::players[j]->wentforweapon = 0;
975 animTarget = swordslashreversedanim;
976 animCurrent = swordslashreversedanim;
977 victim->animCurrent = swordslashreversalanim;
978 victim->animTarget = swordslashreversalanim;
980 if (animTarget == knifeslashstartanim && distsq(&victim->coords, &coords) < 2 && (victim->id == 0 || Random() % 4 == 0)) {
981 if (victim->weaponactive != -1) {
982 victim->throwtogglekeydown = 1;
983 weapons[victim->weaponids[0]].owner = -1;
984 weapons[victim->weaponids[0]].velocity = victim->velocity * .2;
985 if (weapons[victim->weaponids[0]].velocity.x == 0)
986 weapons[victim->weaponids[0]].velocity.x = .1;
987 weapons[victim->weaponids[0]].tipvelocity = weapons[victim->weaponids[0]].velocity;
988 weapons[victim->weaponids[0]].missed = 1;
989 weapons[victim->weaponids[0]].freetime = 0;
990 weapons[victim->weaponids[0]].firstfree = 1;
991 weapons[victim->weaponids[0]].physics = 1;
992 victim->num_weapons--;
993 if (victim->num_weapons) {
994 victim->weaponids[0] = victim->weaponids[victim->num_weapons];
995 if (victim->weaponstuck == victim->num_weapons)
996 victim->weaponstuck = 0;
999 victim->weaponactive = -1;
1000 for (unsigned j = 0; j < Person::players.size(); j++) {
1001 Person::players[j]->wentforweapon = 0;
1004 animTarget = knifeslashreversedanim;
1005 animCurrent = knifeslashreversedanim;
1006 victim->animCurrent = knifeslashreversalanim;
1007 victim->animTarget = knifeslashreversalanim;
1009 if (animTarget != knifeslashstartanim && animTarget != staffhitanim && animTarget != staffspinhitanim && animTarget != winduppunchanim && animTarget != wolfslapanim && animTarget != swordslashanim) {
1010 victim->targettilt2 = targettilt2;
1011 victim->frameCurrent = frameCurrent;
1012 victim->frameTarget = frameTarget;
1013 victim->target = target;
1014 victim->velocity = 0;
1015 victim->oldcoords = victim->coords;
1016 victim->coords = coords;
1017 victim->targetyaw = targetyaw;
1018 victim->yaw = targetyaw;
1019 victim->victim = this->shared_from_this();
1021 if (animTarget == winduppunchanim) {
1022 animTarget = winduppunchblockedanim;
1023 victim->animTarget = blockhighleftanim;
1024 victim->frameTarget = 1;
1025 victim->target = .5;
1026 victim->victim = this->shared_from_this();
1027 victim->targetyaw = targetyaw + 180;
1029 if (animTarget == wolfslapanim) {
1030 animTarget = winduppunchblockedanim;
1031 victim->animTarget = blockhighleftanim;
1032 victim->frameTarget = 1;
1033 victim->target = .5;
1034 victim->victim = this->shared_from_this();
1035 victim->targetyaw = targetyaw + 180;
1037 if ((animTarget == swordslashanim || animTarget == staffhitanim || animTarget == staffspinhitanim) && victim->weaponactive != -1) {
1038 animTarget = swordslashparriedanim;
1039 parriedrecently = .4;
1040 victim->parriedrecently = 0;
1041 victim->animTarget = swordslashparryanim;
1042 victim->frameTarget = 1;
1043 victim->target = .5;
1044 victim->victim = this->shared_from_this();
1045 victim->targetyaw = targetyaw + 180;
1047 if (abs(Random() % 20) == 0 || weapons[victim->weaponids[victim->weaponactive]].getType() == knife) {
1048 if (victim->weaponactive != -1) {
1049 if (weapons[victim->weaponids[0]].getType() == staff || weapons[weaponids[0]].getType() == staff) {
1050 if (weapons[victim->weaponids[0]].getType() == staff)
1051 weapons[victim->weaponids[0]].damage += .2 + float(abs(Random() % 100) - 50) / 250;
1052 if (weapons[weaponids[0]].getType() == staff)
1053 weapons[weaponids[0]].damage += .2 + float(abs(Random() % 100) - 50) / 250;
1054 emit_sound_at(swordstaffsound, victim->coords);
1056 emit_sound_at(metalhitsound, victim->coords);
1060 victim->Puff(righthand);
1062 victim->frameTarget = 0;
1063 victim->animTarget = staggerbackhighanim;
1064 victim->targetyaw = targetyaw + 180;
1066 weapons[victim->weaponids[0]].owner = -1;
1067 aim = DoRotation(facing, 0, 90, 0) * 21;
1069 weapons[victim->weaponids[0]].velocity = aim * -.2;
1070 weapons[victim->weaponids[0]].tipvelocity = aim;
1071 weapons[victim->weaponids[0]].missed = 1;
1072 weapons[victim->weaponids[0]].hitsomething = 0;
1073 weapons[victim->weaponids[0]].freetime = 0;
1074 weapons[victim->weaponids[0]].firstfree = 1;
1075 weapons[victim->weaponids[0]].physics = 1;
1076 victim->num_weapons--;
1077 if (victim->num_weapons) {
1078 victim->weaponids[0] = victim->weaponids[num_weapons];
1079 if (victim->weaponstuck == victim->num_weapons)
1080 victim->weaponstuck = 0;
1082 victim->weaponactive = -1;
1083 for (unsigned i = 0; i < Person::players.size(); i++) {
1084 Person::players[i]->wentforweapon = 0;
1088 if (abs(Random() % 20) == 0) {
1089 if (weaponactive != -1) {
1090 if (weapons[victim->weaponids[0]].getType() == staff || weapons[weaponids[0]].getType() == staff) {
1091 if (weapons[victim->weaponids[0]].getType() == staff)
1092 weapons[victim->weaponids[0]].damage += .2 + float(abs(Random() % 100) - 50) / 250;
1093 if (weapons[weaponids[0]].getType() == staff)
1094 weapons[weaponids[0]].damage += .2 + float(abs(Random() % 100) - 50) / 250;
1096 emit_sound_at(swordstaffsound, coords);
1098 emit_sound_at(metalhitsound, coords);
1106 animTarget = staggerbackhighanim;
1107 targetyaw = targetyaw + 180;
1109 weapons[weaponids[0]].owner = -1;
1110 aim = DoRotation(facing, 0, 90, 0) * 21;
1112 weapons[weaponids[0]].velocity = aim * -.2;
1113 weapons[weaponids[0]].tipvelocity = aim;
1114 weapons[weaponids[0]].hitsomething = 0;
1115 weapons[weaponids[0]].missed = 1;
1116 weapons[weaponids[0]].freetime = 0;
1117 weapons[weaponids[0]].firstfree = 1;
1118 weapons[weaponids[0]].physics = 1;
1121 weaponids[0] = weaponids[num_weapons];
1122 if (weaponstuck == num_weapons)
1126 for (unsigned i = 0; i < Person::players.size(); i++) {
1127 Person::players[i]->wentforweapon = 0;
1134 if (animTarget == knifeslashstartanim || animTarget == swordslashanim || animTarget == staffhitanim || animTarget == staffspinhitanim) {
1135 if ((animTarget != staffhitanim && animTarget != staffspinhitanim) || distsq(&coords, &victim->coords) > .2) {
1136 victim->animTarget = dodgebackanim;
1137 victim->frameTarget = 0;
1141 rotatetarget = coords - victim->coords;
1142 Normalise(&rotatetarget);
1143 victim->targetyaw = -asin(0 - rotatetarget.x);
1144 victim->targetyaw *= 360 / 6.28;
1145 if (rotatetarget.z < 0)
1146 victim->targetyaw = 180 - victim->targetyaw;
1148 victim->targettilt2 = -asin(rotatetarget.y) * 360 / 6.28; //*-70;
1150 victim->lastattack3 = victim->lastattack2;
1151 victim->lastattack2 = victim->lastattack;
1152 victim->lastattack = victim->animTarget;
1154 victim->animTarget = sweepanim;
1155 victim->frameTarget = 0;
1159 rotatetarget = coords - victim->coords;
1160 Normalise(&rotatetarget);
1161 victim->targetyaw = -asin(0 - rotatetarget.x);
1162 victim->targetyaw *= 360 / 6.28;
1163 if (rotatetarget.z < 0)
1164 victim->targetyaw = 180 - victim->targetyaw;
1166 victim->targettilt2 = -asin(rotatetarget.y) * 360 / 6.28; //*-70;
1168 victim->lastattack3 = victim->lastattack2;
1169 victim->lastattack2 = victim->lastattack;
1170 victim->lastattack = victim->animTarget;
1175 victim->velocity = 0;
1177 if (aitype != playercontrolled)
1179 if (aitype != playercontrolled && Random() % 3 == 0 && escapednum < 2 && difficulty == 2)
1181 if (aitype != playercontrolled && Random() % 5 == 0 && escapednum < 2 && difficulty == 1)
1183 if (aitype != playercontrolled && Random() % 10 == 0 && escapednum < 2 && difficulty == 0)
1186 if (victim->id == 0 && animation[victim->animTarget].attack == reversal)
1193 void Person::DoDamage(float howmuch)
1195 // subtract health (temporary?)
1196 if (tutoriallevel != 1)
1197 damage += howmuch / power;
1200 damagedealt += howmuch / power;
1202 damagetaken += howmuch / power;
1205 if (id == 0 && (bonus == solidhit || bonus == twoxcombo || bonus == threexcombo || bonus == fourxcombo || bonus == megacombo))
1208 if (tutoriallevel != 1)
1209 permanentdamage += howmuch / 2 / power;
1210 if (tutoriallevel != 1)
1211 superpermanentdamage += howmuch / 4 / power;
1213 if (permanentdamage > damagetolerance / 2 && permanentdamage - howmuch < damagetolerance / 2 && Random() % 2)
1215 if ((permanentdamage > damagetolerance * .8 && Random() % 2 && !deathbleeding) || spurt)
1219 camerashake += howmuch / 100;
1220 if (id == 0 && ((howmuch > 50 && damage > damagetolerance / 2)))
1221 blackout = damage / damagetolerance;
1226 if (aitype == passivetype && damage < damagetolerance && ((tutoriallevel != 1 || cananger) && hostile))
1227 aitype = attacktypecutoff;
1228 if (tutoriallevel != 1 && aitype != playercontrolled && damage < damagetolerance && damage > damagetolerance * 2 / 3 && creature == rabbittype) {
1229 if (abs(Random() % 2) == 0) {
1230 aitype = gethelptype;
1233 aitype = attacktypecutoff;
1237 if (howmuch > damagetolerance * 50 && skeleton.free != 2) {
1240 for (int i = 0; i < skeleton.num_joints; i++) {
1242 flatvelocity2 = velocity;
1244 flatvelocity2 = skeleton.joints[i].velocity;
1246 flatfacing2 = DoRotation(DoRotation(DoRotation(skeleton.joints[i].position, 0, 0, tilt), tilt2, 0, 0), 0, yaw, 0) * scale + coords;
1248 flatfacing2 = skeleton.joints[i].position * scale + coords;
1249 flatvelocity2.x += (float)(abs(Random() % 100) - 50) / 10;
1250 flatvelocity2.y += (float)(abs(Random() % 100) - 50) / 10;
1251 flatvelocity2.z += (float)(abs(Random() % 100) - 50) / 10;
1252 Sprite::MakeSprite(bloodflamesprite, flatfacing2, flatvelocity2, 1, 1, 1, 3, 1);
1253 Sprite::MakeSprite(bloodsprite, flatfacing2, flatvelocity2, 1, 1, 1, .4, 1);
1254 Sprite::MakeSprite(cloudsprite, flatfacing2, flatvelocity2 * 0, .6, 0, 0, 1, .5);
1257 emit_sound_at(splattersound, coords);
1262 if (!dead && creature == wolftype) {
1263 award_bonus(0, Wolfbonus);
1270 if (tutoriallevel != 1 || id == 0)
1271 if (speechdelay <= 0 && !dead && aitype != playercontrolled) {
1272 int whichsound = -1;
1274 if (creature == wolftype) {
1275 int i = abs(Random() % 2);
1277 whichsound = snarlsound;
1279 whichsound = snarl2sound;
1280 envsound[numenvsounds] = coords;
1281 envsoundvol[numenvsounds] = 16;
1282 envsoundlife[numenvsounds] = .4;
1285 if (creature == rabbittype) {
1286 int i = abs(Random() % 2);
1288 whichsound = rabbitpainsound;
1289 if (i == 1 && damage > damagetolerance)
1290 whichsound = rabbitpain1sound;
1291 envsound[numenvsounds] = coords;
1292 envsoundvol[numenvsounds] = 16;
1293 envsoundlife[numenvsounds] = .4;
1297 if (whichsound != -1) {
1298 emit_sound_at(whichsound, coords);
1305 * calculate/animate head facing direction?
1307 void Person::DoHead()
1309 static XYZ rotatearound;
1311 static float lookspeed = 500;
1313 if (!freeze && !winfreeze) {
1316 targetheadyaw = (float)((int)((0 - yaw - targetheadyaw + 180) * 100) % 36000) / 100;
1317 targetheadpitch = (float)((int)(targetheadpitch * 100) % 36000) / 100;
1319 while (targetheadyaw > 180)targetheadyaw -= 360;
1320 while (targetheadyaw < -180)targetheadyaw += 360;
1322 if (targetheadyaw > 160)
1323 targetheadpitch = targetheadpitch * -1;
1324 if (targetheadyaw < -160)
1325 targetheadpitch = targetheadpitch * -1;
1326 if (targetheadyaw > 160)
1327 targetheadyaw = targetheadyaw - 180;
1328 if (targetheadyaw < -160)
1329 targetheadyaw = targetheadyaw + 180;
1331 if (targetheadpitch > 120)
1332 targetheadpitch = 120;
1333 if (targetheadpitch < -120)
1334 targetheadpitch = -120;
1335 if (targetheadyaw > 120)
1336 targetheadyaw = 120;
1337 if (targetheadyaw < -120)
1338 targetheadyaw = -120;
1341 targetheadpitch = 0;
1343 if (targetheadyaw > 80)
1345 if (targetheadyaw < -80)
1346 targetheadyaw = -80;
1347 if (targetheadpitch > 50)
1348 targetheadpitch = 50;
1349 if (targetheadpitch < -50)
1350 targetheadpitch = -50;
1353 if (abs(headyaw - targetheadyaw) < multiplier * lookspeed)
1354 headyaw = targetheadyaw;
1355 else if (headyaw > targetheadyaw) {
1356 headyaw -= multiplier * lookspeed;
1357 } else if (headyaw < targetheadyaw) {
1358 headyaw += multiplier * lookspeed;
1361 if (abs(headpitch - targetheadpitch) < multiplier * lookspeed / 2)
1362 headpitch = targetheadpitch;
1363 else if (headpitch > targetheadpitch) {
1364 headpitch -= multiplier * lookspeed / 2;
1365 } else if (headpitch < targetheadpitch) {
1366 headpitch += multiplier * lookspeed / 2;
1369 rotatearound = jointPos(neck);
1370 jointPos(head) = rotatearound + DoRotation(jointPos(head) - rotatearound, headpitch, 0, 0);
1374 if (animTarget != bounceidleanim && animTarget != fightidleanim && animTarget != wolfidle && animTarget != knifefightidleanim && animTarget != drawrightanim && animTarget != drawleftanim && animTarget != walkanim) {
1375 facing = DoRotation(facing, headpitch * .4, 0, 0);
1376 facing = DoRotation(facing, 0, headyaw * .4, 0);
1379 if (animTarget == bounceidleanim || animTarget == fightidleanim || animTarget == wolfidle || animTarget == knifefightidleanim || animTarget == drawrightanim || animTarget == drawleftanim) {
1380 facing = DoRotation(facing, headpitch * .8, 0, 0);
1381 facing = DoRotation(facing, 0, headyaw * .8, 0);
1384 if (animTarget == walkanim) {
1385 facing = DoRotation(facing, headpitch * .6, 0, 0);
1386 facing = DoRotation(facing, 0, headyaw * .6, 0);
1389 skeleton.specialforward[0] = facing;
1390 //skeleton.specialforward[0]=DoRotation(facing,0,yaw,0);
1391 for (int i = 0; i < skeleton.num_muscles; i++) {
1392 if (skeleton.muscles[i].visible && (skeleton.muscles[i].parent1->label == head || skeleton.muscles[i].parent2->label == head)) {
1393 skeleton.FindRotationMuscle(i, animTarget);
1400 * ragdolls character?
1402 void Person::RagDoll(bool checkcollision)
1407 if (!skeleton.free) {
1410 if (id == 0 && isFlip())
1417 facing = DoRotation(facing, 0, yaw, 0);
1419 skeleton.freetime = 0;
1421 skeleton.longdead = 0;
1424 skeleton.broken = 0;
1425 skeleton.spinny = 1;
1427 skeleton.freefall = 1;
1429 if (!isnormal(velocity.x)) velocity.x = 0;
1430 if (!isnormal(velocity.y)) velocity.y = 0;
1431 if (!isnormal(velocity.z)) velocity.z = 0;
1432 if (!isnormal(yaw)) yaw = 0;
1433 if (!isnormal(coords.x)) coords = 0;
1434 if (!isnormal(tilt)) tilt = 0;
1435 if (!isnormal(tilt2)) tilt2 = 0;
1437 for (int i = 0; i < skeleton.num_joints; i++) {
1438 skeleton.joints[i].delay = 0;
1439 skeleton.joints[i].locked = 0;
1440 skeleton.joints[i].position = DoRotation(DoRotation(DoRotation(skeleton.joints[i].position, 0, 0, tilt), tilt2, 0, 0), 0, yaw, 0);
1441 if (!isnormal(skeleton.joints[i].position.x)) skeleton.joints[i].position = DoRotation(skeleton.joints[i].position, 0, yaw, 0);
1442 if (!isnormal(skeleton.joints[i].position.x)) skeleton.joints[i].position = coords;
1443 skeleton.joints[i].position.y += .1;
1444 skeleton.joints[i].oldposition = skeleton.joints[i].position;
1445 skeleton.joints[i].realoldposition = skeleton.joints[i].position * scale + coords;
1448 for (int i = 0; i < skeleton.num_joints; i++) {
1449 skeleton.joints[i].velocity = 0;
1450 skeleton.joints[i].velchange = 0;
1452 skeleton.DoConstraints(&coords, &scale);
1453 if (animation[animCurrent].height == lowheight || animation[animTarget].height == lowheight) {
1454 skeleton.DoConstraints(&coords, &scale);
1455 skeleton.DoConstraints(&coords, &scale);
1456 skeleton.DoConstraints(&coords, &scale);
1457 skeleton.DoConstraints(&coords, &scale);
1460 speed = animation[animTarget].speed[frameTarget] * 2;
1461 if (animation[animCurrent].speed[frameCurrent] > animation[animTarget].speed[frameTarget]) {
1462 speed = animation[animCurrent].speed[frameCurrent] * 2;
1465 speed = transspeed * 2;
1469 for (int i = 0; i < skeleton.num_joints; i++) {
1470 if ((animation[animCurrent].attack != reversed || animCurrent == swordslashreversedanim) && animCurrent != rabbitkickanim && !isLanding() && !wasLanding() && animation[animCurrent].height == animation[animTarget].height)
1471 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);
1473 skeleton.joints[i].velocity = velocity / scale + facing * 5;
1474 change.x = (float)(Random() % 100) / 100;
1475 change.y = (float)(Random() % 100) / 100;
1476 change.z = (float)(Random() % 100) / 100;
1477 skeleton.joints[i].velocity += change;
1478 skeleton.joints[abs(Random() % skeleton.num_joints)].velocity -= change;
1480 change.x = (float)(Random() % 100) / 100;
1481 change.y = (float)(Random() % 100) / 100;
1482 change.z = (float)(Random() % 100) / 100;
1483 skeleton.joints[i].velchange += change;
1484 skeleton.joints[abs(Random() % skeleton.num_joints)].velchange -= change;
1487 if (checkcollision) {
1494 for (j = 0; j < skeleton.num_joints; j++) {
1495 average += skeleton.joints[j].position;
1499 coords += average * scale;
1500 for (j = 0; j < skeleton.num_joints; j++) {
1501 skeleton.joints[j].position -= average;
1504 whichpatchx = coords.x / (terrain.size / subdivision * terrain.scale);
1505 whichpatchz = coords.z / (terrain.size / subdivision * terrain.scale);
1506 if (terrain.patchobjectnum[whichpatchx][whichpatchz])
1507 for (l = 0; l < terrain.patchobjectnum[whichpatchx][whichpatchz]; l++) {
1508 i = terrain.patchobjects[whichpatchx][whichpatchz][l];
1511 if (SphereCheck(&lowpoint, 3, &colpoint, &objects.position[i], &objects.yaw[i], &objects.model[i]) != -1) {
1512 coords.x = lowpoint.x;
1513 coords.z = lowpoint.z;
1522 for (int i = 0; i < skeleton.num_joints; i++) {
1523 velocity += skeleton.joints[i].velocity * scale;
1525 velocity /= skeleton.num_joints;
1528 if (Random() % 2 == 0) {
1529 if (weaponactive != -1 && animTarget != rabbitkickanim && num_weapons > 0) {
1530 weapons[weaponids[0]].owner = -1;
1531 weapons[weaponids[0]].hitsomething = 0;
1532 weapons[weaponids[0]].velocity = jointVel(righthand) * scale * -.3;
1533 weapons[weaponids[0]].velocity.x += .01;
1534 weapons[weaponids[0]].tipvelocity = jointVel(righthand) * scale;
1535 weapons[weaponids[0]].missed = 1;
1536 weapons[weaponids[0]].freetime = 0;
1537 weapons[weaponids[0]].firstfree = 1;
1538 weapons[weaponids[0]].physics = 1;
1541 weaponids[0] = weaponids[num_weapons];
1542 if (weaponstuck == num_weapons)
1546 for (unsigned i = 0; i < Person::players.size(); i++) {
1547 Person::players[i]->wentforweapon = 0;
1552 animTarget = bounceidleanim;
1553 animCurrent = bounceidleanim;
1563 void Person::FootLand(int which, float opacity)
1565 static XYZ terrainlight;
1566 static XYZ footvel, footpoint;
1567 if (opacity >= 1 || skiddelay <= 0)
1571 footpoint = DoRotation(jointPos(leftfoot), 0, yaw, 0) * scale + coords;
1573 footpoint = DoRotation(jointPos(rightfoot), 0, yaw, 0) * scale + coords;
1574 //footpoint.y=coords.y;
1575 if (distsq(&footpoint, &viewer))
1576 Sprite::MakeSprite(cloudsprite, footpoint, footvel, 1, 1, 1, .5, .2 * opacity);
1577 } else if (environment == snowyenvironment && onterrain && terrain.getOpacity(coords.x, coords.z) < .2) {
1578 footvel = velocity / 5;
1582 footpoint = DoRotation(jointPos(leftfoot), 0, yaw, 0) * scale + coords;
1584 footpoint = DoRotation(jointPos(rightfoot), 0, yaw, 0) * scale + coords;
1585 footpoint.y = terrain.getHeight(footpoint.x, footpoint.z);
1586 terrainlight = terrain.getLighting(footpoint.x, footpoint.z);
1587 if (distsq(&footpoint, &viewer) < viewdistance * viewdistance / 4)
1588 Sprite::MakeSprite(cloudsprite, footpoint, footvel * .6, terrainlight.x, terrainlight.y, terrainlight.z, .5, .7 * opacity);
1589 if (opacity >= 1 || detail == 2)
1591 if (distsq(&footpoint, &viewer) < viewdistance * viewdistance / 4)
1592 terrain.MakeDecal(footprintdecal, footpoint, .2, 1 * opacity, yaw);
1593 } else if (environment == grassyenvironment && onterrain && terrain.getOpacity(coords.x, coords.z) < .2) {
1594 footvel = velocity / 5;
1598 footpoint = DoRotation(jointPos(leftfoot), 0, yaw, 0) * scale + coords;
1600 footpoint = DoRotation(jointPos(rightfoot), 0, yaw, 0) * scale + coords;
1601 footpoint.y = terrain.getHeight(footpoint.x, footpoint.z);
1602 terrainlight = terrain.getLighting(footpoint.x, footpoint.z);
1603 if (distsq(&footpoint, &viewer) < viewdistance * viewdistance / 4)
1604 Sprite::MakeSprite(cloudsprite, footpoint, footvel * .6, terrainlight.x * 90 / 255, terrainlight.y * 70 / 255, terrainlight.z * 8 / 255, .5, .5 * opacity);
1605 } else if (environment == desertenvironment && onterrain && terrain.getOpacity(coords.x, coords.z) < .2) {
1606 footvel = velocity / 5;
1610 footpoint = DoRotation(jointPos(leftfoot), 0, yaw, 0) * scale + coords;
1612 footpoint = DoRotation(jointPos(rightfoot), 0, yaw, 0) * scale + coords;
1613 footpoint.y = terrain.getHeight(footpoint.x, footpoint.z);
1614 terrainlight = terrain.getLighting(footpoint.x, footpoint.z);
1615 if (distsq(&footpoint, &viewer) < viewdistance * viewdistance / 4)
1616 Sprite::MakeSprite(cloudsprite, footpoint, footvel * .6, terrainlight.x * 190 / 255, terrainlight.y * 170 / 255, terrainlight.z * 108 / 255, .5, .7 * opacity);
1617 if (opacity >= 1 || detail == 2)
1619 if (distsq(&footpoint, &viewer) < viewdistance * viewdistance / 4)
1620 terrain.MakeDecal(footprintdecal, footpoint, .2, .25 * opacity, yaw);
1621 } else if (isLanding() || animTarget == jumpupanim || isLandhard()) {
1622 footvel = velocity / 5;
1626 footpoint = DoRotation(jointPos(leftfoot), 0, yaw, 0) * scale + coords;
1628 footpoint = DoRotation(jointPos(rightfoot), 0, yaw, 0) * scale + coords;
1629 //footpoint.y=coords.y;
1630 if (distsq(&footpoint, &viewer) < viewdistance * viewdistance / 4)
1631 Sprite::MakeSprite(cloudsprite, footpoint, footvel * .6, 1, 1, 1, .5, .2 * opacity);
1636 * make a puff effect at a body part (dust effect?)
1638 void Person::Puff(int whichlabel)
1640 static XYZ footvel, footpoint;
1643 footpoint = DoRotation(jointPos(whichlabel), 0, yaw, 0) * scale + coords;
1644 Sprite::MakeSprite(cloudimpactsprite, footpoint, footvel, 1, 1, 1, .9, .3);
1648 * I think I added this in an attempt to clean up code
1650 void Person::setAnimation(int animation)
1652 animTarget = animation;
1661 void Person::DoAnimations()
1663 if (!skeleton.free) {
1664 static float oldtarget;
1666 if (isIdle() && animCurrent != getIdle())
1667 normalsupdatedelay = 0;
1669 if (animTarget == tempanim || animCurrent == tempanim) {
1670 animation[tempanim] = tempanimation;
1672 if (animTarget == jumpupanim || animTarget == jumpdownanim || isFlip()) {
1678 vel[0] = velocity.x;
1679 vel[1] = velocity.y;
1680 vel[2] = velocity.z;
1683 OPENAL_3D_SetAttributes(channels[whooshsound], gLoc, vel);
1684 OPENAL_SetVolume(channels[whooshsound], 64 * findLength(&velocity) / 5);
1686 if (((velocity.y < -15) || (crouchkeydown && velocity.y < -8)) && abs(velocity.y) * 4 > fast_sqrt(velocity.x * velocity.x * velocity.z * velocity.z))
1688 if (!crouchkeydown && velocity.y >= -15)
1691 if ((animCurrent == jumpupanim || animTarget == jumpdownanim)/*&&velocity.y<40*/ && !isFlip() && (!isLanding() && !isLandhard()) && ((crouchkeydown && !crouchtogglekeydown))) {
1696 targfacing = DoRotation(targfacing, 0, targetyaw, 0);
1698 if (normaldotproduct(targfacing, velocity) >= -.3)
1699 animTarget = flipanim;
1701 animTarget = backflipanim;
1702 crouchtogglekeydown = 1;
1710 if (animation[animTarget].attack != reversed)
1712 if (!crouchkeydown || (isLanding() || isLandhard()) || (wasLanding() || wasLandhard())) {
1713 crouchtogglekeydown = 0;
1714 if (aitype == playercontrolled)
1717 if (!crouchtogglekeydown && animation[animTarget].attack == reversed && aitype == playercontrolled && (escapednum < 2 || reversaltrain))
1720 crouchtogglekeydown = 1;
1724 if (animation[animTarget].attack || animCurrent == getupfrombackanim || animCurrent == getupfromfrontanim) {
1726 normalsupdatedelay = 0;
1730 if (animTarget == rollanim && frameTarget == 3 && onfire) {
1732 emit_sound_at(fireendsound, coords);
1733 pause_sound(stream_firesound);
1737 if (animTarget == rabbittacklinganim && frameTarget == 1) {
1738 if (victim->aitype == attacktypecutoff && victim->stunned <= 0 && victim->surprised <= 0 && victim->id != 0)
1740 if (animTarget == rabbittacklinganim && frameTarget == 1 && !victim->isCrouch() && victim->animTarget != backhandspringanim) {
1741 if (normaldotproduct(victim->facing, facing) > 0)
1742 victim->animTarget = rabbittackledbackanim;
1744 victim->animTarget = rabbittackledfrontanim;
1745 victim->frameTarget = 2;
1748 victim->targetyaw = yaw;
1749 if (victim->aitype == gethelptype)
1750 victim->DoDamage(victim->damagetolerance - victim->damage);
1751 //victim->DoDamage(30);
1752 if (creature == wolftype) {
1754 emit_sound_at(clawslicesound, victim->coords);
1756 victim->DoBloodBig(1 / victim->armorhead, 210);
1758 award_bonus(id, TackleBonus,
1759 victim->aitype == gethelptype ? 50 : 0);
1763 if (!drawtogglekeydown && drawkeydown && (weaponactive == -1 || num_weapons == 1) && (animation[animTarget].label[frameTarget] || (animTarget != animCurrent && animCurrent == rollanim)) && num_weapons > 0 && creature != wolftype) {
1764 if (weapons[weaponids[0]].getType() == knife) {
1765 if (weaponactive == -1)
1767 else if (weaponactive == 0)
1770 if (weaponactive == -1) {
1771 emit_sound_at(knifesheathesound, coords);
1773 if (weaponactive != -1) {
1774 emit_sound_at(knifedrawsound, coords, 128);
1777 drawtogglekeydown = 1;
1780 if (tutoriallevel != 1 || id == 0)
1781 if ((animation[animTarget].label[frameTarget] && (animation[animTarget].label[frameTarget] < 5 || animation[animTarget].label[frameTarget] == 8))/*||(animTarget==rollanim&&frameTarget==animation[rollanim].numframes-1)*/) {
1784 if (terrain.getOpacity(coords.x, coords.z) < .2) {
1785 if (animation[animTarget].label[frameTarget] == 1)
1786 whichsound = footstepsound;
1788 whichsound = footstepsound2;
1789 if (animation[animTarget].label[frameTarget] == 1)
1791 if (animation[animTarget].label[frameTarget] == 2)
1793 if (animation[animTarget].label[frameTarget] == 3 && isRun()) {
1799 if (terrain.getOpacity(coords.x, coords.z) >= .2) {
1800 if (animation[animTarget].label[frameTarget] == 1)
1801 whichsound = footstepsound3;
1803 whichsound = footstepsound4;
1807 if (animation[animTarget].label[frameTarget] == 1)
1808 whichsound = footstepsound3;
1810 whichsound = footstepsound4;
1812 if (animation[animTarget].label[frameTarget] == 4 && (weaponactive == -1 || (animTarget != knifeslashstartanim && animTarget != knifethrowanim && animTarget != crouchstabanim && animTarget != swordgroundstabanim && animTarget != knifefollowanim))) {
1813 if (animation[animTarget].attack != neutral) {
1814 unsigned r = abs(Random() % 3);
1816 whichsound = lowwhooshsound;
1818 whichsound = midwhooshsound;
1820 whichsound = highwhooshsound;
1822 if (animation[animTarget].attack == neutral)
1823 whichsound = movewhooshsound;
1824 } else if (animation[animTarget].label[frameTarget] == 4)
1825 whichsound = knifeswishsound;
1826 if (animation[animTarget].label[frameTarget] == 8 && tutoriallevel != 1)
1827 whichsound = landsound2;
1829 emit_sound_at(whichsound, coords, 256.);
1832 if (whichsound == footstepsound || whichsound == footstepsound2 || whichsound == footstepsound3 || whichsound == footstepsound4) {
1833 envsound[numenvsounds] = coords;
1834 if (animTarget == wolfrunninganim || animTarget == rabbitrunninganim)
1835 envsoundvol[numenvsounds] = 15;
1837 envsoundvol[numenvsounds] = 6;
1838 envsoundlife[numenvsounds] = .4;
1842 if (animation[animTarget].label[frameTarget] == 3) {
1844 emit_sound_at(whichsound, coords, 128.);
1849 if (tutoriallevel != 1 || id == 0)
1850 if (speechdelay <= 0)
1851 if (animTarget != crouchstabanim && animTarget != swordgroundstabanim && animTarget != staffgroundsmashanim)
1852 if ((animation[animTarget].label[frameTarget] && (animation[animTarget].label[frameTarget] < 5 || animation[animTarget].label[frameTarget] == 8))/*||(animTarget==rollanim&&frameTarget==animation[rollanim].numframes-1)*/) {
1853 int whichsound = -1;
1854 if (animation[animTarget].label[frameTarget] == 4 && aitype != playercontrolled) {
1855 if (animation[animTarget].attack != neutral) {
1856 unsigned r = abs(Random() % 4);
1857 if (creature == rabbittype) {
1858 if (r == 0) whichsound = rabbitattacksound;
1859 if (r == 1) whichsound = rabbitattack2sound;
1860 if (r == 2) whichsound = rabbitattack3sound;
1861 if (r == 3) whichsound = rabbitattack4sound;
1863 if (creature == wolftype) {
1864 if (r == 0) whichsound = barksound;
1865 if (r == 1) whichsound = bark2sound;
1866 if (r == 2) whichsound = bark3sound;
1867 if (r == 3) whichsound = barkgrowlsound;
1873 if (whichsound != -1) {
1874 emit_sound_at(whichsound, coords);
1880 if ((!wasLanding() && !wasLandhard()) && animCurrent != getIdle() && (isLanding() || isLandhard())) {
1886 currentoffset = targetoffset;
1887 frameTarget = frameCurrent;
1888 animCurrent = animTarget;
1891 if (animTarget == removeknifeanim && animation[animTarget].label[frameCurrent] == 5) {
1892 for (unsigned i = 0; i < weapons.size(); i++) {
1893 if (weapons[i].owner == -1)
1894 if (distsqflat(&coords, &weapons[i].position) < 4 && weaponactive == -1) {
1895 if (distsq(&coords, &weapons[i].position) >= 1) {
1896 if (weapons[i].getType() != staff) {
1897 emit_sound_at(knifedrawsound, coords, 128.);
1901 weapons[i].owner = id;
1902 if (num_weapons > 0) {
1903 weaponids[num_weapons] = weaponids[0];
1912 if (animTarget == crouchremoveknifeanim && animation[animTarget].label[frameCurrent] == 5) {
1913 for (unsigned i = 0; i < weapons.size(); i++) {
1914 bool willwork = true;
1915 if (weapons[i].owner != -1)
1916 if (Person::players[weapons[i].owner]->weaponstuck != -1)
1917 if (Person::players[weapons[i].owner]->weaponids[Person::players[weapons[i].owner]->weaponstuck] == int(i))
1918 if (Person::players[weapons[i].owner]->num_weapons > 1)
1920 if ((weapons[i].owner == -1) || (hasvictim && (weapons[i].owner == int(victim->id)) && victim->skeleton.free))
1921 if (willwork && distsqflat(&coords, &weapons[i].position) < 3 && weaponactive == -1) {
1922 if (distsq(&coords, &weapons[i].position) < 1 || hasvictim) {
1923 bool fleshstuck = false;
1924 if (weapons[i].owner != -1)
1925 if (victim->weaponstuck != -1) {
1926 if (victim->weaponids[victim->weaponstuck] == int(i)) {
1931 emit_sound_at(fleshstabremovesound, coords, 128.);
1933 if (weapons[i].getType() != staff) {
1934 emit_sound_at(knifedrawsound, coords, 128.);
1938 if (weapons[i].owner != -1) {
1940 victim = Person::players[weapons[i].owner];
1941 if (victim->num_weapons == 1)
1942 victim->num_weapons = 0;
1944 victim->num_weapons = 1;
1946 //victim->weaponactive=-1;
1947 victim->skeleton.longdead = 0;
1948 victim->skeleton.free = 1;
1949 victim->skeleton.broken = 0;
1951 for (int j = 0; j < victim->skeleton.num_joints; j++) {
1952 victim->skeleton.joints[j].velchange = 0;
1953 victim->skeleton.joints[j].locked = 0;
1959 Normalise(&relative);
1960 XYZ footvel, footpoint;
1962 footpoint = weapons[i].position;
1963 if (victim->weaponstuck != -1) {
1964 if (victim->weaponids[victim->weaponstuck] == int(i)) {
1966 Sprite::MakeSprite(cloudimpactsprite, footpoint, footvel, 1, 0, 0, .8, .3);
1967 weapons[i].bloody = 2;
1968 weapons[i].blooddrip = 5;
1969 victim->weaponstuck = -1;
1972 if (victim->num_weapons > 0) {
1973 if (victim->weaponstuck != 0 && victim->weaponstuck != -1)
1974 victim->weaponstuck = 0;
1975 if (victim->weaponids[0] == int(i))
1976 victim->weaponids[0] = victim->weaponids[victim->num_weapons];
1979 victim->jointVel(abdomen) += relative * 6;
1980 victim->jointVel(neck) += relative * 6;
1981 victim->jointVel(rightshoulder) += relative * 6;
1982 victim->jointVel(leftshoulder) += relative * 6;
1984 weapons[i].owner = id;
1985 if (num_weapons > 0) {
1986 weaponids[num_weapons] = weaponids[0];
1995 if (animCurrent == drawleftanim && animation[animTarget].label[frameCurrent] == 5) {
1996 if (weaponactive == -1)
1998 else if (weaponactive == 0) {
2000 if (num_weapons == 2) {
2002 buffer = weaponids[0];
2003 weaponids[0] = weaponids[1];
2004 weaponids[1] = buffer;
2007 if (weaponactive == -1) {
2008 emit_sound_at(knifesheathesound, coords, 128.);
2010 if (weaponactive != -1) {
2011 emit_sound_at(knifedrawsound, coords, 128.);
2016 if ((animCurrent == walljumprightkickanim && animTarget == walljumprightkickanim) || (animCurrent == walljumpleftkickanim && animTarget == walljumpleftkickanim)) {
2017 XYZ rotatetarget = DoRotation(skeleton.forward, 0, yaw, 0);
2018 Normalise(&rotatetarget);
2019 targetyaw = -asin(0 - rotatetarget.x);
2020 targetyaw *= 360 / 6.28;
2021 if (rotatetarget.z < 0)
2022 targetyaw = 180 - targetyaw;
2024 if (animTarget == walljumprightkickanim)
2026 if (animTarget == walljumpleftkickanim)
2032 if ((animTarget == rabbitrunninganim || animTarget == wolfrunninganim) && frameTarget == 3 && (jumpkeydown || attackkeydown || id != 0))
2035 if (distsq(&victim->coords, &/*Person::players[i]->*/coords) < 5 && victim->aitype == gethelptype && (attackkeydown) && !victim->skeleton.free && victim->isRun() && victim->runninghowlong >= 1)
2040 if ((animTarget == rabbitrunninganim || animTarget == wolfrunninganim) && id == 0) {
2041 animTarget = rabbittackleanim;
2043 emit_sound_at(jumpsound, coords);
2051 targetloc = velocity;
2052 Normalise(&targetloc);
2053 targetloc += coords;
2054 for (unsigned i = 0; i < Person::players.size(); i++) {
2056 if (distsq(&targetloc, &Person::players[i]->coords) < closestdist || closestdist == 0) {
2057 closestdist = distsq(&targetloc, &Person::players[i]->coords);
2061 if (closestid != -1)
2062 if (closestdist < 5 && !Person::players[closestid]->dead && animation[Person::players[closestid]->animTarget].height != lowheight && Person::players[closestid]->animTarget != backhandspringanim) {
2064 victim = Person::players[closestid];
2065 coords = victim->coords;
2066 animCurrent = rabbittacklinganim;
2067 animTarget = rabbittacklinganim;
2071 if (coords.z != victim->coords.z || coords.x != victim->coords.x) {
2072 rotatetarget = coords - victim->coords;
2073 Normalise(&rotatetarget);
2074 targetyaw = -asin(0 - rotatetarget.x);
2075 targetyaw *= 360 / 6.28;
2076 if (rotatetarget.z < 0)
2077 targetyaw = 180 - targetyaw;
2079 if (animTarget != rabbitrunninganim) {
2080 emit_sound_at(jumpsound, coords, 128.);
2086 float damagemult = 1 * power;
2087 if (creature == wolftype)
2088 damagemult = 2.5 * power;
2090 damagemult /= victim->damagetolerance / 200;
2092 if ((animation[animTarget].attack == normalattack || animTarget == walljumprightkickanim || animTarget == walljumpleftkickanim) && (!feint) && (victim->skeleton.free != 2 || animTarget == killanim || animTarget == dropkickanim || animTarget == crouchstabanim || animTarget == swordgroundstabanim || animTarget == staffgroundsmashanim)) {
2093 if (animTarget == spinkickanim && animation[animTarget].label[frameCurrent] == 5) {
2094 if (distsq(&coords, &victim->coords) < (scale * 5) * (scale * 5) * 3 && 3 && animation[victim->animTarget].height != lowheight) {
2098 if (Random() % 2 || creature == wolftype) {
2101 if (creature == wolftype)
2104 if (tutoriallevel != 1) {
2105 emit_sound_at(heavyimpactsound, victim->coords, 128.);
2107 if (creature == wolftype) {
2108 emit_sound_at(clawslicesound, victim->coords, 128.);
2110 victim->DoBloodBig(2 / victim->armorhead, 175);
2114 relative = victim->coords - coords;
2116 Normalise(&relative);
2117 relative = DoRotation(relative, 0, -90, 0);
2118 for (int i = 0; i < victim->skeleton.num_joints; i++) {
2119 victim->skeleton.joints[i].velocity += relative * damagemult * 40;
2121 victim->jointVel(head) += relative * damagemult * 200;
2124 victim->DoDamage(damagemult * 100 / victim->protectionhead);
2130 if (animTarget == wolfslapanim && animation[animTarget].label[frameCurrent] == 5) {
2131 if (distsq(&coords, &victim->coords) < (scale * 5) * (scale * 5) * 3 && 3 && animation[victim->animTarget].height != lowheight) {
2135 if (Random() % 2 || creature == wolftype) {
2137 if (creature == wolftype)
2140 emit_sound_at(whooshhitsound, victim->coords);
2141 if (creature == wolftype) {
2142 emit_sound_at(clawslicesound, victim->coords, 128.);
2144 victim->DoBloodBig(2, 175);
2148 relative = victim->coords - coords;
2150 Normalise(&relative);
2152 Normalise(&relative);
2153 relative = DoRotation(relative, 0, 90, 0);
2154 for (int i = 0; i < victim->skeleton.num_joints; i++) {
2155 victim->skeleton.joints[i].velocity += relative * damagemult * 20;
2157 victim->jointVel(head) += relative * damagemult * 100;
2160 victim->DoDamage(damagemult * 50 / victim->protectionhead);
2164 if (animTarget == walljumprightkickanim && animation[animTarget].label[frameCurrent] == 5) {
2165 if (distsq(&coords, &victim->coords) < (scale * 5) * (scale * 5) * 3 && animation[victim->animTarget].height != lowheight) {
2171 if (tutoriallevel != 1) {
2172 emit_sound_at(heavyimpactsound, victim->coords, 160.);
2174 if (creature == wolftype) {
2175 emit_sound_at(clawslicesound, victim->coords, 128.);
2177 victim->DoBloodBig(2 / victim->armorhead, 175);
2183 Normalise(&relative);
2184 relative = DoRotation(relative, 0, -90, 0);
2185 for (int i = 0; i < victim->skeleton.num_joints; i++) {
2186 victim->skeleton.joints[i].velocity += relative * damagemult * 40;
2188 victim->jointVel(head) += relative * damagemult * 200;
2191 victim->DoDamage(damagemult * 150 / victim->protectionhead);
2193 if (victim->damage > victim->damagetolerance)
2194 award_bonus(id, style);
2200 if (animTarget == walljumpleftkickanim && animation[animTarget].label[frameCurrent] == 5) {
2201 if (distsq(&coords, &victim->coords) < (scale * 5) * (scale * 5) * 3 && animation[victim->animTarget].height != lowheight) {
2207 if (tutoriallevel != 1) {
2208 emit_sound_at(heavyimpactsound, victim->coords, 160.);
2210 if (creature == wolftype) {
2211 emit_sound_at(clawslicesound, victim->coords, 128.);
2213 victim->DoBloodBig(2 / victim->armorhead, 175);
2219 Normalise(&relative);
2220 relative = DoRotation(relative, 0, 90, 0);
2221 for (int i = 0; i < victim->skeleton.num_joints; i++) {
2222 victim->skeleton.joints[i].velocity += relative * damagemult * 40;
2224 victim->jointVel(head) += relative * damagemult * 200;
2227 victim->DoDamage(damagemult * 150 / victim->protectionhead);
2229 if (victim->damage > victim->damagetolerance)
2230 award_bonus(id, style);
2236 if (animTarget == blockhighleftstrikeanim && animation[animTarget].label[frameCurrent] == 5) {
2237 if (distsq(&coords, &victim->coords) < (scale * 5) * (scale * 5) * 3 && animation[victim->animTarget].height != lowheight) {
2245 emit_sound_at(whooshhitsound, victim->coords);
2248 relative = victim->coords - coords;
2250 Normalise(&relative);
2251 for (int i = 0; i < victim->skeleton.num_joints; i++) {
2252 victim->skeleton.joints[i].velocity += relative * damagemult * 30;
2254 victim->jointVel(head) += relative * damagemult * 100;
2257 victim->DoDamage(damagemult * 50 / victim->protectionhead);
2261 if (animTarget == killanim && animation[animTarget].label[frameCurrent] == 8) {
2262 if (distsq(&coords, &victim->coords) < (scale * 5) * (scale * 5) * 3 && victim->dead) {
2266 emit_sound_at(whooshhitsound, victim->coords, 128.);
2268 victim->skeleton.longdead = 0;
2269 victim->skeleton.free = 1;
2270 victim->skeleton.broken = 0;
2271 victim->skeleton.spinny = 1;
2273 for (int i = 0; i < victim->skeleton.num_joints; i++) {
2274 victim->skeleton.joints[i].velchange = 0;
2275 victim->skeleton.joints[i].delay = 0;
2276 victim->skeleton.joints[i].locked = 0;
2277 //victim->skeleton.joints[i].velocity=0;
2283 Normalise(&relative);
2284 for (int i = 0; i < victim->skeleton.num_joints; i++) {
2285 victim->skeleton.joints[i].velocity.y = relative.y * 10;
2286 victim->skeleton.joints[i].position.y += relative.y * .3;
2287 victim->skeleton.joints[i].oldposition.y += relative.y * .3;
2288 victim->skeleton.joints[i].realoldposition.y += relative.y * .3;
2290 victim->Puff(abdomen);
2291 victim->jointVel(abdomen).y = relative.y * 400;
2295 if (animTarget == killanim && animation[animTarget].label[frameCurrent] == 5) {
2296 if (distsq(&coords, &victim->coords) < (scale * 5) * (scale * 5) * 9 && victim->dead) {
2300 if (tutoriallevel != 1) {
2301 emit_sound_at(heavyimpactsound, coords, 128.);
2304 relative = victim->coords - coords;
2306 Normalise(&relative);
2307 for (int i = 0; i < victim->skeleton.num_joints; i++) {
2308 victim->skeleton.joints[i].velocity += relative * damagemult * 90;
2310 victim->Puff(abdomen);
2311 if (victim->dead != 2 && victim->permanentdamage > victim->damagetolerance - 250 && autoslomo) {
2315 victim->DoDamage(damagemult * 500 / victim->protectionhigh);
2316 victim->jointVel(abdomen) += relative * damagemult * 300;
2320 if (animTarget == dropkickanim && animation[animTarget].label[frameCurrent] == 7) {
2321 if (distsq(&coords, &victim->coords) < (scale * 5) * (scale * 5) * 9 && victim->skeleton.free) {
2325 if (tutoriallevel != 1) {
2326 emit_sound_at(thudsound, coords);
2329 victim->skeleton.longdead = 0;
2330 victim->skeleton.free = 1;
2331 victim->skeleton.broken = 0;
2332 victim->skeleton.spinny = 1;
2334 for (int i = 0; i < victim->skeleton.num_joints; i++) {
2335 victim->skeleton.joints[i].velchange = 0;
2336 //victim->skeleton.joints[i].delay=0;
2337 victim->skeleton.joints[i].locked = 0;
2340 relative = victim->coords - coords;
2341 Normalise(&relative);
2343 Normalise(&relative);
2344 for (int i = 0; i < victim->skeleton.num_joints; i++) {
2345 victim->skeleton.joints[i].velocity += relative * damagemult * 20;
2350 victim->Puff(abdomen);
2351 victim->DoDamage(damagemult * 20 / victim->protectionhigh);
2352 victim->jointVel(abdomen) += relative * damagemult * 200;
2361 if ((animTarget == crouchstabanim || animTarget == swordgroundstabanim) && animation[animTarget].label[frameCurrent] == 5) {
2364 if (!victim->skeleton.free)
2368 terrain.MakeDecal(blooddecalfast, (weapons[weaponids[weaponactive]].tippoint * .8 + weapons[weaponids[weaponactive]].position * .2), .08, .6, Random() % 360);
2369 emit_sound_at(knifesheathesound, coords, 128.);
2372 if (victim && hasvictim) {
2373 if (distsq(&coords, &victim->coords) < (scale * 5) * (scale * 5) * 3) {
2375 XYZ where, startpoint, endpoint, movepoint, colpoint;
2376 float rotationpoint;
2378 if (weapons[weaponids[weaponactive]].getType() == knife) {
2379 where = (weapons[weaponids[weaponactive]].tippoint * .6 + weapons[weaponids[weaponactive]].position * .4);
2380 where -= victim->coords;
2381 if (!victim->skeleton.free)
2382 where = DoRotation(where, 0, -victim->yaw, 0);
2385 startpoint.y += 100;
2389 if (weapons[weaponids[weaponactive]].getType() == sword) {
2390 where = weapons[weaponids[weaponactive]].position;
2391 where -= victim->coords;
2392 if (!victim->skeleton.free)
2393 where = DoRotation(where, 0, -victim->yaw, 0);
2395 where = weapons[weaponids[weaponactive]].tippoint;
2396 where -= victim->coords;
2397 if (!victim->skeleton.free)
2398 where = DoRotation(where, 0, -victim->yaw, 0);
2401 if (weapons[weaponids[weaponactive]].getType() == staff) {
2402 where = weapons[weaponids[weaponactive]].position;
2403 where -= victim->coords;
2404 if (!victim->skeleton.free)
2405 where = DoRotation(where, 0, -victim->yaw, 0);
2407 where = weapons[weaponids[weaponactive]].tippoint;
2408 where -= victim->coords;
2409 if (!victim->skeleton.free)
2410 where = DoRotation(where, 0, -victim->yaw, 0);
2415 whichtri = victim->skeleton.drawmodel.LineCheck(&startpoint, &endpoint, &colpoint, &movepoint, &rotationpoint);
2417 if (whichtri != -1) {
2418 if (victim->dead != 2) {
2419 victim->DoDamage(abs((victim->damagetolerance - victim->permanentdamage) * 2));
2421 award_bonus(id, FinishedBonus);
2424 weapons[weaponids[weaponactive]].bloody = 2;
2426 victim->skeleton.longdead = 0;
2427 victim->skeleton.free = 1;
2428 victim->skeleton.broken = 0;
2430 for (int i = 0; i < victim->skeleton.num_joints; i++) {
2431 victim->skeleton.joints[i].velchange = 0;
2432 victim->skeleton.joints[i].locked = 0;
2433 //victim->skeleton.joints[i].velocity=0;
2435 emit_sound_at(fleshstabsound, coords, 128);
2438 if (whichtri != -1 || weapons[weaponids[weaponactive]].bloody) {
2439 weapons[weaponids[weaponactive]].blooddrip += 5;
2440 weapons[weaponids[weaponactive]].blooddripdelay = 0;
2442 if (whichtri == -1) {
2444 emit_sound_at(knifesheathesound, coords, 128.);
2450 if ((animTarget == crouchstabanim || animTarget == swordgroundstabanim) && animation[animTarget].label[frameCurrent] == 6) {
2452 emit_sound_at(knifedrawsound, coords, 128);
2455 if (victim && hasvictim) {
2456 XYZ footvel, footpoint;
2458 emit_sound_at(fleshstabremovesound, coords, 128.);
2461 footpoint = (weapons[weaponids[weaponactive]].tippoint * .8 + weapons[weaponids[weaponactive]].position * .2);
2463 if (weapons[weaponids[weaponactive]].getType() == sword) {
2464 XYZ where, startpoint, endpoint, movepoint;
2465 float rotationpoint;
2468 where = weapons[weaponids[weaponactive]].position;
2469 where -= victim->coords;
2470 if (!victim->skeleton.free)
2471 where = DoRotation(where, 0, -victim->yaw, 0);
2473 where = weapons[weaponids[weaponactive]].tippoint;
2474 where -= victim->coords;
2475 if (!victim->skeleton.free)
2476 where = DoRotation(where, 0, -victim->yaw, 0);
2481 whichtri = victim->skeleton.drawmodel.LineCheck(&startpoint, &endpoint, &footpoint, &movepoint, &rotationpoint);
2482 footpoint += victim->coords;
2484 if (whichtri == -1) {
2485 footpoint = (weapons[weaponids[weaponactive]].tippoint * .8 + weapons[weaponids[weaponactive]].position * .2);
2488 if (weapons[weaponids[weaponactive]].getType() == staff) {
2489 XYZ where, startpoint, endpoint, movepoint;
2490 float rotationpoint;
2493 where = weapons[weaponids[weaponactive]].position;
2494 where -= victim->coords;
2495 if (!victim->skeleton.free)
2496 where = DoRotation(where, 0, -victim->yaw, 0);
2498 where = weapons[weaponids[weaponactive]].tippoint;
2499 where -= victim->coords;
2500 if (!victim->skeleton.free)
2501 where = DoRotation(where, 0, -victim->yaw, 0);
2506 whichtri = victim->skeleton.drawmodel.LineCheck(&startpoint, &endpoint, &footpoint, &movepoint, &rotationpoint);
2507 footpoint += victim->coords;
2509 if (whichtri == -1) {
2510 footpoint = (weapons[weaponids[weaponactive]].tippoint * .8 + weapons[weaponids[weaponactive]].position * .2);
2513 hasvictim = victim->DoBloodBigWhere(2, 220, footpoint);
2515 if (distsq(&coords, &victim->coords) < (scale * 5) * (scale * 5) * 3) {
2516 victim->skeleton.longdead = 0;
2517 victim->skeleton.free = 1;
2518 victim->skeleton.broken = 0;
2520 for (int i = 0; i < victim->skeleton.num_joints; i++) {
2521 victim->skeleton.joints[i].velchange = 0;
2522 victim->skeleton.joints[i].locked = 0;
2523 //victim->skeleton.joints[i].velocity=0;
2529 Normalise(&relative);
2530 //victim->Puff(abdomen);
2532 Sprite::MakeSprite(cloudimpactsprite, footpoint, footvel, 1, 0, 0, .8, .3);
2534 if (victim->bloodloss < victim->damagetolerance) {
2535 victim->bloodloss += 1000;
2539 victim->jointVel(abdomen) += relative * damagemult * 20;
2543 if (!hasvictim && onterrain) {
2544 weapons[weaponids[weaponactive]].bloody = 0;
2545 weapons[weaponids[weaponactive]].blooddrip = 0;
2549 if (animTarget == upunchanim && animation[animTarget].label[frameCurrent] == 5) {
2550 if (distsq(&coords, &victim->coords) < (scale * 5) * (scale * 5) * 3) {
2558 if (tutoriallevel != 1) {
2559 emit_sound_at(heavyimpactsound, victim->coords, 128);
2564 relative = victim->coords - coords;
2566 Normalise(&relative);
2567 for (int i = 0; i < victim->skeleton.num_joints; i++) {
2568 victim->skeleton.joints[i].velocity = relative * 30;
2570 victim->jointVel(head) += relative * damagemult * 150;
2572 victim->frameTarget = 0;
2573 victim->animTarget = staggerbackhardanim;
2574 victim->targetyaw = targetyaw + 180;
2576 victim->stunned = 1;
2579 victim->Puff(abdomen);
2580 victim->DoDamage(damagemult * 60 / victim->protectionhigh);
2587 if (animTarget == winduppunchanim && animation[animTarget].label[frameCurrent] == 5) {
2588 if (distsq(&coords, &victim->coords) < (scale * 5) * (scale * 5) * 2) {
2592 if (victim->damage <= victim->damagetolerance - 60 && normaldotproduct(victim->facing, victim->coords - coords) < (scale * 5) * (scale * 5) * 0 && animation[victim->animTarget].height != lowheight) {
2593 if (tutoriallevel != 1) {
2594 emit_sound_at(thudsound, victim->coords);
2596 } else if (victim->damage <= victim->damagetolerance - 60 && normaldotproduct(victim->facing, victim->coords - coords) < (scale * 5) * (scale * 5) * 0 && animation[victim->animTarget].height == lowheight) {
2597 if (tutoriallevel != 1) {
2598 emit_sound_at(whooshhitsound, victim->coords);
2601 if (tutoriallevel != 1) {
2602 emit_sound_at(heavyimpactsound, victim->coords);
2606 if (victim->damage > victim->damagetolerance - 60 || normaldotproduct(victim->facing, victim->coords - coords) > 0 || animation[victim->animTarget].height == lowheight)
2609 relative = victim->coords - coords;
2611 Normalise(&relative);
2613 Normalise(&relative);
2614 for (int i = 0; i < victim->skeleton.num_joints; i++) {
2615 victim->skeleton.joints[i].velocity = relative * 5;
2617 victim->jointVel(abdomen) += relative * damagemult * 400;
2619 victim->frameTarget = 0;
2620 victim->animTarget = staggerbackhardanim;
2621 victim->targetyaw = targetyaw + 180;
2623 victim->stunned = 1;
2625 victim->Puff(abdomen);
2626 victim->DoDamage(damagemult * 60 / victim->protectionhigh);
2632 if (animTarget == blockhighleftanim && animation[animTarget].label[frameCurrent] == 5) {
2633 if (distsq(&coords, &victim->coords) < (scale * 5) * (scale * 5) * 4) {
2634 if (victim->id == 0)
2636 emit_sound_at(landsound2, victim->coords);
2642 if (animTarget == swordslashparryanim && animation[animTarget].label[frameCurrent] == 5) {
2643 if (distsq(&coords, &victim->coords) < (scale * 5) * (scale * 5) * 4) {
2644 if (victim->id == 0)
2647 if (weaponactive != -1) {
2648 if (weapons[victim->weaponids[0]].getType() == staff || weapons[weaponids[0]].getType() == staff) {
2649 if (weapons[victim->weaponids[0]].getType() == staff)
2650 weapons[victim->weaponids[0]].damage += .2 + float(abs(Random() % 100) - 50) / 250;
2651 if (weapons[weaponids[0]].getType() == staff)
2652 weapons[weaponids[0]].damage += .2 + float(abs(Random() % 100) - 50) / 250;
2654 emit_sound_at(swordstaffsound, victim->coords);
2656 emit_sound_at(metalhitsound, victim->coords);
2664 if (animTarget == knifethrowanim && animation[animTarget].label[frameCurrent] == 5) {
2665 if (weaponactive != -1) {
2668 weapons[weaponids[0]].owner = -1;
2669 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);
2671 weapons[weaponids[0]].velocity = aim * 50;
2672 weapons[weaponids[0]].tipvelocity = aim * 50;
2673 weapons[weaponids[0]].missed = 0;
2674 weapons[weaponids[0]].hitsomething = 0;
2675 weapons[weaponids[0]].freetime = 0;
2676 weapons[weaponids[0]].firstfree = 1;
2677 weapons[weaponids[0]].physics = 0;
2680 weaponids[0] = weaponids[num_weapons];
2686 if (animTarget == knifeslashstartanim && animation[animTarget].label[frameCurrent] == 5) {
2688 if (distsq(&coords, &victim->coords) < (scale * 5) * (scale * 5) * 4.5 &&/*animation[victim->animTarget].height!=lowheight&&*/victim->animTarget != dodgebackanim && victim->animTarget != rollanim) {
2690 if (tutoriallevel != 1)
2691 victim->DoBloodBig(1.5 / victim->armorhigh, 225);
2693 award_bonus(id, Slicebonus);
2694 if (tutoriallevel != 1) {
2695 emit_sound_at(knifeslicesound, victim->coords);
2697 //victim->jointVel(abdomen)+=relative*damagemult*200;
2698 if (animation[victim->animTarget].attack && (victim->aitype != playercontrolled || victim->animTarget == knifeslashstartanim) && (victim->creature == rabbittype || victim->deathbleeding <= 0)) {
2699 if (victim->id != 0 || difficulty == 2) {
2700 victim->frameTarget = 0;
2701 victim->animTarget = staggerbackhardanim;
2702 victim->targetyaw = targetyaw + 180;
2706 victim->lowreversaldelay = 0;
2707 victim->highreversaldelay = 0;
2708 if (aitype != playercontrolled)
2709 weaponmissdelay = .6;
2711 if (tutoriallevel != 1)
2712 if (bloodtoggle && !weapons[weaponids[weaponactive]].bloody)
2713 weapons[weaponids[weaponactive]].bloody = 1;
2714 if (tutoriallevel != 1)
2715 weapons[weaponids[weaponactive]].blooddrip += 3;
2717 XYZ footvel, footpoint;
2719 if (skeleton.free) {
2720 footpoint = (victim->jointPos(abdomen) + victim->jointPos(neck)) / 2 * victim->scale + victim->coords;
2722 if (!skeleton.free) {
2723 footpoint = DoRotation((victim->jointPos(abdomen) + victim->jointPos(neck)) / 2, 0, victim->yaw, 0) * victim->scale + victim->coords;
2725 if (tutoriallevel != 1) {
2727 Sprite::MakeSprite(cloudimpactsprite, footpoint, footvel, 1, 0, 0, .6, .3);
2728 footvel = DoRotation(facing, 0, 90, 0) * .8;
2730 Sprite::MakeSprite(bloodsprite, footpoint, DoRotation(footvel * 7, (float)(Random() % 20), (float)(Random() % 20), 0), 1, 1, 1, .05, .9);
2731 Sprite::MakeSprite(bloodsprite, footpoint, DoRotation(footvel * 3, (float)(Random() % 20), (float)(Random() % 20), 0), 1, 1, 1, .05, .9);
2732 Sprite::MakeSprite(bloodflamesprite, footpoint, footvel * 5, 1, 1, 1, .2, 1);
2733 Sprite::MakeSprite(bloodflamesprite, footpoint, footvel * 2, 1, 1, 1, .2, 1);
2735 if (tutoriallevel == 1) {
2736 Sprite::MakeSprite(cloudimpactsprite, footpoint, footvel, 1, 1, 1, .6, .3);
2738 victim->DoDamage(damagemult * 0);
2741 if (animTarget == swordslashanim && animation[animTarget].label[frameCurrent] == 5 && victim->animTarget != rollanim) {
2742 if (distsq(&coords, &victim->coords) < (scale * 5) * (scale * 5) * 6.5 && victim->animTarget != dodgebackanim) {
2743 if (victim->weaponactive == -1 || normaldotproduct(victim->facing, victim->coords - coords) > 0 || (Random() % 2 == 0)) {
2744 award_bonus(id, Slashbonus);
2746 if (tutoriallevel != 1) {
2747 if (normaldotproduct(victim->facing, victim->coords - coords) < 0)
2748 victim->DoBloodBig(2 / victim->armorhigh, 190);
2750 victim->DoBloodBig(2 / victim->armorhigh, 185);
2751 victim->deathbleeding = 1;
2752 emit_sound_at(swordslicesound, victim->coords);
2754 //victim->jointVel(abdomen)+=relative*damagemult*200;
2755 if (tutoriallevel != 1) {
2756 victim->frameTarget = 0;
2757 victim->animTarget = staggerbackhardanim;
2758 victim->targetyaw = targetyaw + 180;
2762 if (tutoriallevel != 1) {
2763 if (bloodtoggle && !weapons[weaponids[weaponactive]].bloody)
2764 weapons[weaponids[weaponactive]].bloody = 1;
2765 weapons[weaponids[weaponactive]].blooddrip += 3;
2767 float bloodlossamount;
2768 bloodlossamount = 200 + abs((float)(Random() % 40)) - 20;
2769 victim->bloodloss += bloodlossamount / victim->armorhigh;
2770 //victim->bloodloss+=100*(6.5-distsq(&coords,&victim->coords));
2771 victim->DoDamage(damagemult * 0);
2773 XYZ footvel, footpoint;
2775 if (skeleton.free) {
2776 footpoint = (victim->jointPos(abdomen) + victim->jointPos(neck)) / 2 * victim->scale + victim->coords;
2778 if (!skeleton.free) {
2779 footpoint = DoRotation((victim->jointPos(abdomen) + victim->jointPos(neck)) / 2, 0, victim->yaw, 0) * victim->scale + victim->coords;
2782 Sprite::MakeSprite(cloudimpactsprite, footpoint, footvel, 1, 0, 0, .9, .3);
2783 footvel = DoRotation(facing, 0, 90, 0) * .8;
2785 Sprite::MakeSprite(bloodsprite, footpoint, DoRotation(footvel * 7, (float)(Random() % 20), (float)(Random() % 20), 0), 1, 1, 1, .05, .9);
2786 Sprite::MakeSprite(bloodsprite, footpoint, DoRotation(footvel * 3, (float)(Random() % 20), (float)(Random() % 20), 0), 1, 1, 1, .05, .9);
2787 Sprite::MakeSprite(bloodflamesprite, footpoint, footvel * 5, 1, 1, 1, .3, 1);
2788 Sprite::MakeSprite(bloodflamesprite, footpoint, footvel * 2, 1, 1, 1, .3, 1);
2791 if (victim->weaponactive != -1) {
2792 if (weapons[victim->weaponids[0]].getType() == staff || weapons[weaponids[0]].getType() == staff) {
2793 if (weapons[victim->weaponids[0]].getType() == staff)
2794 weapons[victim->weaponids[0]].damage += .2 + float(abs(Random() % 100) - 50) / 250;
2795 if (weapons[weaponids[0]].getType() == staff)
2796 weapons[weaponids[0]].damage += .2 + float(abs(Random() % 100) - 50) / 250;
2798 emit_sound_at(swordstaffsound, victim->coords);
2800 emit_sound_at(metalhitsound, victim->coords);
2806 victim->Puff(righthand);
2808 victim->frameTarget = 0;
2809 victim->animTarget = staggerbackhighanim;
2810 victim->targetyaw = targetyaw + 180;
2812 weapons[victim->weaponids[0]].owner = -1;
2813 aim = DoRotation(facing, 0, 90, 0) * 21;
2815 weapons[victim->weaponids[0]].velocity = aim * -.2;
2816 weapons[victim->weaponids[0]].tipvelocity = aim;
2817 weapons[victim->weaponids[0]].missed = 1;
2818 weapons[weaponids[0]].hitsomething = 0;
2819 weapons[victim->weaponids[0]].freetime = 0;
2820 weapons[victim->weaponids[0]].firstfree = 1;
2821 weapons[victim->weaponids[0]].physics = 1;
2822 victim->num_weapons--;
2823 if (victim->num_weapons) {
2824 victim->weaponids[0] = victim->weaponids[num_weapons];
2825 if (victim->weaponstuck == victim->num_weapons)
2826 victim->weaponstuck = 0;
2828 victim->weaponactive = -1;
2829 for (unsigned i = 0; i < Person::players.size(); i++) {
2830 Person::players[i]->wentforweapon = 0;
2837 if (animTarget == staffhitanim && animation[animTarget].label[frameCurrent] == 5 && victim->animTarget != rollanim) {
2838 if (distsq(&coords, &victim->coords) < (scale * 5) * (scale * 5) * 6.5 && victim->animTarget != dodgebackanim && victim->animTarget != sweepanim) {
2839 if (tutoriallevel != 1) {
2840 weapons[weaponids[0]].damage += .4 + float(abs(Random() % 100) - 50) / 250;
2844 if (Random() % 2 || creature == wolftype) {
2847 emit_sound_at(staffheadsound, victim->coords);
2851 relative = victim->coords - coords;
2853 Normalise(&relative);
2854 relative = DoRotation(relative, 0, 90, 0);
2856 Normalise(&relative);
2857 for (int i = 0; i < victim->skeleton.num_joints; i++) {
2858 victim->skeleton.joints[i].velocity += relative * damagemult * 60;
2860 victim->jointVel(head) += relative * damagemult * 230;
2861 victim->jointVel(neck) += relative * damagemult * 230;
2864 if (tutoriallevel != 1) {
2865 victim->DoDamage(damagemult * 120 / victim->protectionhigh);
2867 award_bonus(id, solidhit, 30);
2872 if (animTarget == staffspinhitanim && animation[animTarget].label[frameCurrent] == 5 && victim->animTarget != rollanim) {
2873 if (distsq(&coords, &victim->coords) < (scale * 5) * (scale * 5) * 6.5 && victim->animTarget != dodgebackanim && victim->animTarget != sweepanim) {
2874 if (tutoriallevel != 1) {
2875 weapons[weaponids[0]].damage += .6 + float(abs(Random() % 100) - 50) / 250;
2879 if (Random() % 2 || creature == wolftype) {
2882 emit_sound_at(staffheadsound, victim->coords);
2886 relative = victim->coords - coords;
2888 Normalise(&relative);
2889 relative = DoRotation(relative, 0, -90, 0);
2890 for (int i = 0; i < victim->skeleton.num_joints; i++) {
2891 victim->skeleton.joints[i].velocity += relative * damagemult * 40;
2893 victim->jointVel(head) += relative * damagemult * 220;
2894 victim->jointVel(neck) += relative * damagemult * 220;
2897 if (tutoriallevel != 1) {
2898 victim->DoDamage(damagemult * 350 / victim->protectionhead);
2900 award_bonus(id, solidhit, 60);
2905 if (animTarget == staffgroundsmashanim && animation[animTarget].label[frameCurrent] == 5) {
2906 if (distsq(&coords, &victim->coords) < (scale * 5) * (scale * 5) * 6.5) {
2908 if (tutoriallevel != 1) {
2910 weapons[weaponids[0]].damage += .4 + float(abs(Random() % 100) - 50) / 500;
2913 if (Random() % 2 || creature == wolftype) {
2916 emit_sound_at(staffbodysound, victim->coords);
2918 victim->skeleton.longdead = 0;
2919 victim->skeleton.free = 1;
2920 victim->skeleton.broken = 0;
2922 for (int i = 0; i < victim->skeleton.num_joints; i++) {
2923 victim->skeleton.joints[i].velchange = 0;
2924 victim->skeleton.joints[i].locked = 0;
2925 //victim->skeleton.joints[i].velocity=0;
2931 /*relative=victim->coords-coords;
2933 Normalise(&relative);
2934 relative=DoRotation(relative,0,90,0);*/
2936 Normalise(&relative);
2937 if (!victim->dead) {
2938 for (int i = 0; i < victim->skeleton.num_joints; i++) {
2939 victim->skeleton.joints[i].velocity = relative * damagemult * 40;
2942 victim->jointVel(abdomen) += relative * damagemult * 40;
2945 for (int i = 0; i < victim->skeleton.num_joints; i++) {
2946 victim->skeleton.joints[i].velocity = relative * damagemult * abs(Random() % 20);
2949 //victim->jointVel(abdomen)+=relative*damagemult*20;
2951 victim->Puff(abdomen);
2952 if (tutoriallevel != 1) {
2953 victim->DoDamage(damagemult * 100 / victim->protectionhigh);
2955 if (!victim->dead) {
2956 award_bonus(id, solidhit, 40);
2962 if (animTarget == lowkickanim && animation[animTarget].label[frameCurrent] == 5) {
2963 if (distsq(&coords, &victim->coords) < (scale * 5) * (scale * 5) * 3 && animation[victim->animTarget].height != highheight) {
2968 relative = victim->coords - coords;
2970 Normalise(&relative);
2974 if (animation[victim->animTarget].height == lowheight) {
2980 for (int i = 0; i < victim->skeleton.num_joints; i++) {
2981 victim->skeleton.joints[i].velocity += relative * damagemult * 40;
2983 victim->jointVel(head) += relative * damagemult * 200;
2984 if (tutoriallevel != 1) {
2985 emit_sound_at(heavyimpactsound, victim->coords, 128.);
2988 victim->DoDamage(damagemult * 100 / victim->protectionhead);
2989 if (victim->howactive == typesleeping)
2990 victim->DoDamage(damagemult * 150 / victim->protectionhead);
2991 if (creature == wolftype) {
2992 emit_sound_at(clawslicesound, victim->coords, 128.);
2994 victim->DoBloodBig(2 / victim->armorhead, 175);
2997 if (victim->damage >= victim->damagetolerance)
2999 for (int i = 0; i < victim->skeleton.num_joints; i++) {
3000 victim->skeleton.joints[i].velocity += relative * damagemult * 10;
3002 victim->jointVel(abdomen) += relative * damagemult * 200;
3003 victim->frameTarget = 0;
3004 victim->animTarget = staggerbackhighanim;
3005 victim->targetyaw = targetyaw + 180;
3007 if (tutoriallevel != 1) {
3008 emit_sound_at(landsound2, victim->coords, 128.);
3010 victim->Puff(abdomen);
3011 victim->DoDamage(damagemult * 30 / victim->protectionhigh);
3012 if (creature == wolftype) {
3013 emit_sound_at(clawslicesound, victim->coords, 128.);
3015 victim->DoBloodBig(2 / victim->armorhigh, 170);
3022 if (animTarget == sweepanim && animation[animTarget].label[frameCurrent] == 5) {
3023 if ((victim->animTarget != jumpupanim) &&
3024 (distsq(&coords, &victim->coords) < (scale * 5) * (scale * 5) * 3) &&
3025 (victim != this->shared_from_this())) {
3029 if (tutoriallevel != 1) {
3030 emit_sound_at(landsound2, victim->coords, 128.);
3033 relative = victim->coords - coords;
3035 Normalise(&relative);
3037 if (animation[victim->animTarget].height == middleheight || animation[victim->animCurrent].height == middleheight || victim->damage >= victim->damagetolerance - 40) {
3040 for (int i = 0; i < victim->skeleton.num_joints; i++) {
3041 victim->skeleton.joints[i].velocity += relative * damagemult * 15;
3043 relative = DoRotation(relative, 0, -90, 0);
3045 for (int i = 0; i < victim->skeleton.num_joints; i++) {
3046 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)
3047 victim->skeleton.joints[i].velocity = relative * 80;
3049 victim->Puff(rightankle);
3050 victim->Puff(leftankle);
3051 victim->DoDamage(damagemult * 40 / victim->protectionlow);
3053 if (victim->damage >= victim->damagetolerance)
3055 for (int i = 0; i < victim->skeleton.num_joints; i++) {
3056 victim->skeleton.joints[i].velocity += relative * damagemult * 10;
3058 relative = DoRotation(relative, 0, -90, 0);
3059 for (int i = 0; i < victim->skeleton.num_joints; i++) {
3060 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)
3061 victim->skeleton.joints[i].velocity += relative * damagemult * 80;
3063 victim->jointVel(abdomen) += relative * damagemult * 200;
3064 victim->frameTarget = 0;
3065 victim->animTarget = staggerbackhighanim;
3066 victim->targetyaw = targetyaw + 180;
3068 if (tutoriallevel != 1) {
3069 emit_sound_at(landsound2, victim->coords, 128.);
3071 victim->Puff(abdomen);
3072 victim->DoDamage(damagemult * 30 / victim->protectionlow);
3080 if (animation[animTarget].attack == reversal && (!victim->feint || (victim->lastattack == victim->lastattack2 && victim->lastattack2 == victim->lastattack3 && Random() % 2) || animTarget == knifefollowanim)) {
3081 if (animTarget == spinkickreversalanim && animation[animTarget].label[frameCurrent] == 7) {
3089 if (tutoriallevel != 1) {
3090 emit_sound_at(heavyimpactsound, victim->coords, 128.);
3092 if (creature == wolftype) {
3093 emit_sound_at(clawslicesound, victim->coords, 128);
3095 victim->DoBloodBig(2 / victim->armorhigh, 170);
3099 relative = victim->coords - oldcoords;
3101 Normalise(&relative);
3102 //relative=DoRotation(relative,0,-90,0);
3103 for (int i = 0; i < victim->skeleton.num_joints; i++) {
3104 victim->skeleton.joints[i].velocity += relative * damagemult * 40;
3106 victim->jointVel(abdomen) += relative * damagemult * 200;
3108 victim->Puff(abdomen);
3109 victim->DoDamage(damagemult * 150 / victim->protectionhigh);
3111 award_bonus(id, Reversal);
3114 if ((animTarget == swordslashreversalanim || animTarget == knifeslashreversalanim || animTarget == staffhitreversalanim || animTarget == staffspinhitreversalanim) && animation[animTarget].label[frameCurrent] == 5) {
3115 if (victim->weaponactive != -1 && victim->num_weapons > 0) {
3116 if (weapons[victim->weaponids[victim->weaponactive]].owner == int(victim->id)) {
3117 weapons[victim->weaponids[victim->weaponactive]].owner = id;
3119 if (num_weapons > 0) {
3120 weaponids[num_weapons] = weaponids[victim->weaponactive];
3123 weaponids[0] = victim->weaponids[victim->weaponactive];
3124 victim->num_weapons--;
3125 if (victim->num_weapons > 0) {
3126 victim->weaponids[victim->weaponactive] = victim->weaponids[victim->num_weapons];
3128 victim->weaponactive = -1;
3133 if (animTarget == staffhitreversalanim && animation[animTarget].label[frameCurrent] == 5) {
3141 emit_sound_at(whooshhitsound, victim->coords, 128.);
3144 relative = victim->coords - oldcoords;
3146 Normalise(&relative);
3147 for (int i = 0; i < victim->skeleton.num_joints; i++) {
3148 victim->skeleton.joints[i].velocity += relative * damagemult * 30;
3150 victim->jointVel(abdomen) += relative * damagemult * 200;
3152 victim->DoDamage(damagemult * 70 / victim->protectionhigh);
3155 if (animTarget == staffspinhitreversalanim && animation[animTarget].label[frameCurrent] == 7) {
3164 award_bonus(id, staffreversebonus);
3166 if (tutoriallevel != 1) {
3167 emit_sound_at(heavyimpactsound, victim->coords, 128.);
3170 award_bonus(id, staffreversebonus); // Huh, again?
3173 relative = victim->coords - oldcoords;
3175 Normalise(&relative);
3176 for (int i = 0; i < victim->skeleton.num_joints; i++) {
3177 victim->skeleton.joints[i].velocity += relative * damagemult * 30;
3179 victim->jointVel(abdomen) += relative * damagemult * 200;
3181 victim->DoDamage(damagemult * 70 / victim->protectionhigh);
3184 if (animTarget == upunchreversalanim && animation[animTarget].label[frameCurrent] == 7) {
3190 Normalise(&relative);
3192 for (int i = 0; i < victim->skeleton.num_joints; i++) {
3193 victim->skeleton.joints[i].velocity += relative * damagemult * 70;
3195 victim->jointVel(lefthand) *= .1;
3196 victim->jointVel(leftwrist) *= .2;
3197 victim->jointVel(leftelbow) *= .5;
3198 victim->jointVel(leftshoulder) *= .7;
3199 victim->jointVel(righthand) *= .1;
3200 victim->jointVel(rightwrist) *= .2;
3201 victim->jointVel(rightelbow) *= .5;
3202 victim->jointVel(rightshoulder) *= .7;
3204 victim->Puff(abdomen);
3205 victim->DoDamage(damagemult * 90 / victim->protectionhigh);
3207 award_bonus(id, Reversal);
3211 if (weaponactive != -1 || creature == wolftype)
3213 if (creature == rabbittype && weaponactive != -1)
3214 if (weapons[weaponids[0]].getType() == staff)
3217 if (weaponactive != -1) {
3218 victim->DoBloodBig(2 / victim->armorhigh, 225);
3219 emit_sound_at(knifeslicesound, victim->coords);
3220 if (bloodtoggle && !weapons[weaponids[weaponactive]].bloody)
3221 weapons[weaponids[weaponactive]].bloody = 1;
3222 weapons[weaponids[weaponactive]].blooddrip += 3;
3224 if (weaponactive == -1 && creature == wolftype) {
3226 emit_sound_at(clawslicesound, victim->coords, 128.);
3228 victim->DoBloodBig(2 / victim->armorhigh, 175);
3235 if (animTarget == swordslashreversalanim && animation[animTarget].label[frameCurrent] == 7) {
3241 Normalise(&relative);
3243 for (int i = 0; i < victim->skeleton.num_joints; i++) {
3244 victim->skeleton.joints[i].velocity += relative * damagemult * 70;
3246 victim->jointVel(lefthand) *= .1 - 1;
3247 victim->jointVel(leftwrist) *= .2 - 1;
3248 victim->jointVel(leftelbow) *= .5 - 1;
3249 victim->jointVel(leftshoulder) *= .7 - 1;
3250 victim->jointVel(righthand) *= .1 - 1;
3251 victim->jointVel(rightwrist) *= .2 - 1;
3252 victim->jointVel(rightelbow) *= .5 - 1;
3253 victim->jointVel(rightshoulder) *= .7 - 1;
3255 award_bonus(id, swordreversebonus);
3258 if (hasvictim && animTarget == knifeslashreversalanim && animation[animTarget].label[frameCurrent] == 7) {
3266 if (tutoriallevel != 1) {
3267 emit_sound_at(heavyimpactsound, victim->coords, 128.);
3271 relative = victim->coords - oldcoords;
3273 Normalise(&relative);
3274 relative = DoRotation(relative, 0, -90, 0);
3275 for (int i = 0; i < victim->skeleton.num_joints; i++) {
3276 victim->skeleton.joints[i].velocity += relative * damagemult * 40;
3278 victim->jointVel(abdomen) += relative * damagemult * 200;
3279 victim->Puff(abdomen);
3280 victim->DoDamage(damagemult * 30 / victim->protectionhigh);
3282 award_bonus(id, Reversal);
3285 if (hasvictim && animTarget == sneakattackanim && animation[animTarget].label[frameCurrent] == 7) {
3288 victim->skeleton.spinny = 0;
3290 relative = facing * -1;
3292 Normalise(&relative);
3293 if (victim->id == 0)
3295 for (int i = 0; i < victim->skeleton.num_joints; i++) {
3296 victim->skeleton.joints[i].velocity += relative * damagemult * 40;
3298 victim->damage = victim->damagetolerance;
3299 victim->permanentdamage = victim->damagetolerance - 1;
3302 if (weaponactive != -1 || creature == wolftype)
3304 if (creature == rabbittype && weaponactive != -1)
3305 if (weapons[weaponids[0]].getType() == staff)
3308 if (weaponactive != -1) {
3309 victim->DoBloodBig(200, 225);
3310 emit_sound_at(knifeslicesound, victim->coords);
3312 weapons[weaponids[weaponactive]].bloody = 2;
3313 weapons[weaponids[weaponactive]].blooddrip += 5;
3316 if (creature == wolftype && weaponactive == -1) {
3317 emit_sound_at(clawslicesound, victim->coords, 128.);
3319 victim->DoBloodBig(2, 175);
3322 award_bonus(id, spinecrusher);
3325 if (hasvictim && (animTarget == knifefollowanim || animTarget == knifesneakattackanim) && animation[animTarget].label[frameCurrent] == 5) {
3326 if (weaponactive != -1 && victim->bloodloss < victim->damagetolerance) {
3328 if (animTarget == knifefollowanim)
3329 victim->DoBloodBig(200, 210);
3330 if (animTarget == knifesneakattackanim) {
3331 XYZ footvel, footpoint;
3333 footpoint = weapons[weaponids[0]].tippoint;
3335 Sprite::MakeSprite(cloudimpactsprite, footpoint, footvel, 1, 0, 0, .9, .3);
3336 footvel = (weapons[weaponids[0]].tippoint - weapons[weaponids[0]].position);
3337 Sprite::MakeSprite(bloodsprite, footpoint, DoRotation(footvel * 7, (float)(Random() % 20), (float)(Random() % 20), 0), 1, 1, 1, .05, .9);
3338 Sprite::MakeSprite(bloodsprite, footpoint, DoRotation(footvel * 3, (float)(Random() % 20), (float)(Random() % 20), 0), 1, 1, 1, .05, .9);
3339 Sprite::MakeSprite(bloodflamesprite, footpoint, footvel * 5, 1, 1, 1, .3, 1);
3340 Sprite::MakeSprite(bloodflamesprite, footpoint, footvel * 2, 1, 1, 1, .3, 1);
3341 victim->DoBloodBig(200, 195);
3342 award_bonus(id, tracheotomy);
3344 if (animTarget == knifefollowanim) {
3345 award_bonus(id, Stabbonus);
3346 XYZ footvel, footpoint;
3348 footpoint = weapons[weaponids[0]].tippoint;
3350 Sprite::MakeSprite(cloudimpactsprite, footpoint, footvel, 1, 0, 0, .9, .3);
3351 footvel = (weapons[weaponids[0]].tippoint - weapons[weaponids[0]].position) * -1;
3352 Sprite::MakeSprite(bloodsprite, footpoint, DoRotation(footvel * 7, (float)(Random() % 20), (float)(Random() % 20), 0), 1, 1, 1, .05, .9);
3353 Sprite::MakeSprite(bloodsprite, footpoint, DoRotation(footvel * 3, (float)(Random() % 20), (float)(Random() % 20), 0), 1, 1, 1, .05, .9);
3354 Sprite::MakeSprite(bloodflamesprite, footpoint, footvel * 5, 1, 1, 1, .2, 1);
3355 Sprite::MakeSprite(bloodflamesprite, footpoint, footvel * 2, 1, 1, 1, .2, 1);
3358 victim->bloodloss += 10000;
3359 victim->velocity = 0;
3360 emit_sound_at(fleshstabsound, victim->coords);
3362 weapons[weaponids[weaponactive]].bloody = 2;
3363 weapons[weaponids[weaponactive]].blooddrip += 5;
3367 if (hasvictim && (animTarget == knifefollowanim || animTarget == knifesneakattackanim) && animation[animTarget].label[frameCurrent] == 6) {
3369 victim->velocity = 0;
3370 for (int i = 0; i < victim->skeleton.num_joints; i++) {
3371 victim->skeleton.joints[i].velocity = 0;
3373 if (animTarget == knifefollowanim) {
3375 for (int i = 0; i < victim->skeleton.num_joints; i++) {
3376 victim->skeleton.joints[i].velocity = 0;
3379 if (weaponactive != -1 && animation[victim->animTarget].attack != reversal) {
3380 emit_sound_at(fleshstabremovesound, victim->coords);
3382 weapons[weaponids[weaponactive]].bloody = 2;
3383 weapons[weaponids[weaponactive]].blooddrip += 5;
3385 XYZ footvel, footpoint;
3387 footpoint = weapons[weaponids[0]].tippoint;
3389 Sprite::MakeSprite(cloudimpactsprite, footpoint, footvel, 1, 0, 0, .9, .3);
3390 footvel = (weapons[weaponids[0]].tippoint - weapons[weaponids[0]].position) * -1;
3391 Sprite::MakeSprite(bloodsprite, footpoint, DoRotation(footvel * 7, (float)(Random() % 20), (float)(Random() % 20), 0), 1, 1, 1, .05, .9);
3392 Sprite::MakeSprite(bloodsprite, footpoint, DoRotation(footvel * 3, (float)(Random() % 20), (float)(Random() % 20), 0), 1, 1, 1, .05, .9);
3393 Sprite::MakeSprite(bloodflamesprite, footpoint, footvel * 5, 1, 1, 1, .3, 1);
3394 Sprite::MakeSprite(bloodflamesprite, footpoint, footvel * 2, 1, 1, 1, .3, 1);
3398 if (hasvictim && (animTarget == swordsneakattackanim) && animation[animTarget].label[frameCurrent] == 5) {
3399 if (weaponactive != -1 && victim->bloodloss < victim->damagetolerance) {
3400 award_bonus(id, backstab);
3404 XYZ footvel, footpoint;
3406 footpoint = (weapons[weaponids[0]].tippoint + weapons[weaponids[0]].position) / 2;
3408 Sprite::MakeSprite(cloudimpactsprite, footpoint, footvel, 1, 0, 0, .9, .3);
3409 footvel = (weapons[weaponids[0]].tippoint - weapons[weaponids[0]].position);
3410 Sprite::MakeSprite(bloodsprite, footpoint, DoRotation(footvel * 7, (float)(Random() % 20), (float)(Random() % 20), 0), 1, 1, 1, .05, .9);
3411 Sprite::MakeSprite(bloodsprite, footpoint, DoRotation(footvel * 3, (float)(Random() % 20), (float)(Random() % 20), 0), 1, 1, 1, .05, .9);
3412 Sprite::MakeSprite(bloodflamesprite, footpoint, DoRotation(footvel * 5, (float)(Random() % 20), (float)(Random() % 20), 0), 1, 1, 1, .3, 1);
3413 Sprite::MakeSprite(bloodflamesprite, footpoint, DoRotation(footvel * 3, (float)(Random() % 20), (float)(Random() % 20), 0), 1, 1, 1, .3, 1);
3414 victim->DoBloodBig(200, 180);
3415 victim->DoBloodBig(200, 215);
3416 victim->bloodloss += 10000;
3417 victim->velocity = 0;
3418 emit_sound_at(fleshstabsound, victim->coords);
3420 weapons[weaponids[weaponactive]].bloody = 2;
3421 weapons[weaponids[weaponactive]].blooddrip += 5;
3425 if (hasvictim && animTarget == swordsneakattackanim && animation[animTarget].label[frameCurrent] == 6) {
3427 victim->velocity = 0;
3428 for (int i = 0; i < victim->skeleton.num_joints; i++) {
3429 victim->skeleton.joints[i].velocity = 0;
3431 if (weaponactive != -1) {
3432 emit_sound_at(fleshstabremovesound, victim->coords);
3434 weapons[weaponids[weaponactive]].bloody = 2;
3435 weapons[weaponids[weaponactive]].blooddrip += 5;
3437 XYZ footvel, footpoint;
3439 footpoint = weapons[weaponids[0]].tippoint;
3441 Sprite::MakeSprite(cloudimpactsprite, footpoint, footvel, 1, 0, 0, .9, .3);
3442 footvel = (weapons[weaponids[0]].tippoint - weapons[weaponids[0]].position) * -1;
3443 Sprite::MakeSprite(bloodsprite, footpoint, DoRotation(footvel * 7, (float)(Random() % 20), (float)(Random() % 20), 0), 1, 1, 1, .05, .9);
3444 Sprite::MakeSprite(bloodsprite, footpoint, DoRotation(footvel * 3, (float)(Random() % 20), (float)(Random() % 20), 0), 1, 1, 1, .05, .9);
3445 Sprite::MakeSprite(bloodflamesprite, footpoint, footvel * 5, 1, 1, 1, .3, 1);
3446 Sprite::MakeSprite(bloodflamesprite, footpoint, footvel * 2, 1, 1, 1, .3, 1);
3450 if (animTarget == sweepreversalanim && animation[animTarget].label[frameCurrent] == 7) {
3458 if (weaponactive == -1) {
3459 if (tutoriallevel != 1) {
3460 emit_sound_at(heavyimpactsound, victim->coords, 128.);
3465 if (weaponactive != -1 || creature == wolftype)
3467 if (creature == rabbittype && weaponactive != -1)
3468 if (weapons[weaponids[0]].getType() == staff)
3471 if (weaponactive != -1) {
3472 victim->DoBloodBig(2 / victim->armorhead, 225);
3473 emit_sound_at(knifeslicesound, victim->coords);
3474 if (bloodtoggle && !weapons[weaponids[weaponactive]].bloody)
3475 weapons[weaponids[weaponactive]].bloody = 1;
3476 weapons[weaponids[weaponactive]].blooddrip += 3;
3478 if (weaponactive == -1 && creature == wolftype) {
3479 emit_sound_at(clawslicesound, victim->coords, 128.);
3481 victim->DoBloodBig(2 / victim->armorhead, 175);
3485 award_bonus(id, Reversal);
3490 relative = facing * -1;
3492 Normalise(&relative);
3493 relative = DoRotation(relative, 0, 90, 0);
3495 Normalise(&relative);
3496 for (int i = 0; i < victim->skeleton.num_joints; i++) {
3497 victim->skeleton.joints[i].velocity += relative * damagemult * 20;
3499 victim->jointVel(head) += relative * damagemult * 200;
3500 if (victim->damage < victim->damagetolerance - 100)
3501 victim->velocity = relative * 200;
3502 victim->DoDamage(damagemult * 100 / victim->protectionhead);
3503 victim->velocity = 0;
3506 if (animTarget == sweepreversalanim && ((animation[animTarget].label[frameCurrent] == 9 && victim->damage < victim->damagetolerance) || (animation[animTarget].label[frameCurrent] == 7 && victim->damage > victim->damagetolerance))) {
3510 relative = facing * -1;
3512 Normalise(&relative);
3513 relative = DoRotation(relative, 0, 90, 0);
3515 Normalise(&relative);
3516 for (int i = 0; i < victim->skeleton.num_joints; i++) {
3517 victim->skeleton.joints[i].velocity += relative * damagemult * 20;
3519 victim->jointVel(head) += relative * damagemult * 200;
3522 if (hasvictim && (animTarget == spinkickreversalanim || animTarget == sweepreversalanim || animTarget == rabbitkickreversalanim || animTarget == upunchreversalanim || animTarget == jumpreversalanim || animTarget == swordslashreversalanim || animTarget == knifeslashreversalanim || animTarget == rabbittacklereversal || animTarget == wolftacklereversal || animTarget == staffhitreversalanim || animTarget == staffspinhitreversalanim))
3523 if (victim->damage > victim->damagetolerance && bonus != reverseko) {
3524 award_bonus(id, reverseko);
3530 if (frameTarget > animation[animCurrent].numframes - 1) {
3533 animTarget = getIdle();
3537 if (animCurrent == rabbittackleanim || animCurrent == rabbittacklinganim) {
3538 animTarget = rollanim;
3540 emit_sound_at(movewhooshsound, coords, 128.);
3542 if (animCurrent == staggerbackhighanim) {
3543 animTarget = getIdle();
3545 if (animCurrent == staggerbackhardanim) {
3546 animTarget = getIdle();
3548 if (animCurrent == removeknifeanim) {
3549 animTarget = getIdle();
3551 if (animCurrent == crouchremoveknifeanim) {
3552 animTarget = getCrouch();
3554 if (animCurrent == backhandspringanim) {
3555 animTarget = getIdle();
3557 if (animCurrent == dodgebackanim) {
3558 animTarget = getIdle();
3560 if (animCurrent == drawleftanim) {
3561 animTarget = getIdle();
3563 if (animCurrent == drawrightanim || animCurrent == crouchdrawrightanim) {
3564 animTarget = getIdle();
3565 if (animCurrent == crouchdrawrightanim) {
3566 animTarget = getCrouch();
3568 if (weaponactive == -1)
3570 else if (weaponactive == 0) {
3572 if (num_weapons == 2) {
3574 buffer = weaponids[0];
3575 weaponids[0] = weaponids[1];
3576 weaponids[1] = buffer;
3580 if (weaponactive == -1) {
3581 emit_sound_at(knifesheathesound, coords, 128.);
3583 if (weaponactive != -1) {
3584 emit_sound_at(knifedrawsound, coords, 128.);
3587 if (animCurrent == rollanim) {
3588 animTarget = getCrouch();
3593 if (animTarget == walljumprightkickanim) {
3596 if (animTarget == walljumpleftkickanim) {
3599 animTarget = jumpdownanim;
3601 if (animCurrent == climbanim) {
3602 animTarget = getCrouch();
3604 coords += facing * .1;
3605 if (!isnormal(coords.x))
3616 if (animTarget == rabbitkickreversalanim) {
3617 animTarget = getCrouch();
3620 if (animTarget == jumpreversalanim) {
3621 animTarget = getCrouch();
3624 if (animTarget == walljumprightanim || animTarget == walljumpbackanim || animTarget == walljumpfrontanim) {
3625 if (attackkeydown && animTarget != walljumpfrontanim) {
3627 float closestdist = -1;
3629 if (Person::players.size() > 1)
3630 for (unsigned i = 0; i < Person::players.size(); i++) {
3631 if (id != i && Person::players[i]->coords.y < coords.y && !Person::players[i]->skeleton.free) {
3632 distance = distsq(&Person::players[i]->coords, &coords);
3633 if (closestdist == -1 || distance < closestdist) {
3634 closestdist = distance;
3639 if (closestdist > 0 && closest >= 0 && closestdist < 16) {
3640 victim = Person::players[closest];
3641 animTarget = walljumprightkickanim;
3643 XYZ rotatetarget = victim->coords - coords;
3644 Normalise(&rotatetarget);
3645 yaw = -asin(0 - rotatetarget.x);
3647 if (rotatetarget.z < 0)
3649 targettilt2 = -asin(rotatetarget.y) * 360 / 6.28;
3650 velocity = (victim->coords - coords) * 4;
3655 if (animTarget == walljumpbackanim) {
3656 animTarget = backflipanim;
3658 velocity = facing * -8;
3661 resume_stream(whooshsound);
3663 if (animTarget == walljumprightanim) {
3664 animTarget = rightflipanim;
3668 velocity = DoRotation(facing, 0, 30, 0) * -8;
3671 if (animTarget == walljumpfrontanim) {
3672 animTarget = frontflipanim;
3676 velocity = facing * 8;
3680 resume_stream(whooshsound);
3682 if (animTarget == walljumpleftanim) {
3683 if (attackkeydown) {
3685 float closestdist = -1;
3687 if (Person::players.size() > 1)
3688 for (unsigned i = 0; i < Person::players.size(); i++) {
3689 if (id != i && Person::players[i]->coords.y < coords.y && !Person::players[i]->skeleton.free) {
3690 distance = distsq(&Person::players[i]->coords, &coords);
3691 if (closestdist == -1 || distance < closestdist) {
3692 closestdist = distance;
3697 if (closestdist > 0 && closest >= 0 && closestdist < 16) {
3698 victim = Person::players[closest];
3699 animTarget = walljumpleftkickanim;
3701 XYZ rotatetarget = victim->coords - coords;
3702 Normalise(&rotatetarget);
3703 yaw = -asin(0 - rotatetarget.x);
3705 if (rotatetarget.z < 0)
3707 targettilt2 = -asin(rotatetarget.y) * 360 / 6.28;
3708 velocity = (victim->coords - coords) * 4;
3713 if (animTarget != walljumpleftkickanim) {
3714 animTarget = leftflipanim;
3718 velocity = DoRotation(facing, 0, -30, 0) * -8;
3722 resume_stream(whooshsound);
3724 if (animTarget == sneakattackanim) {
3725 animCurrent = getCrouch();
3726 animTarget = getCrouch();
3733 transspeed = 1000000;
3734 targetheadyaw += 180;
3735 coords -= facing * .7;
3737 coords.y = terrain.getHeight(coords.x, coords.z);
3741 if (animTarget == knifesneakattackanim || animTarget == swordsneakattackanim) {
3742 animTarget = getIdle();
3745 coords.y = terrain.getHeight(coords.x, coords.z);
3749 if (animCurrent == knifefollowanim) {
3750 animTarget = getIdle();
3753 if (animation[animTarget].attack == reversal && animCurrent != sneakattackanim && animCurrent != knifesneakattackanim && animCurrent != swordsneakattackanim && animCurrent != knifefollowanim) {
3754 float ycoords = oldcoords.y;
3755 animTarget = getStop();
3760 transspeed = 1000000;
3761 targetheadyaw += 180;
3762 if (!isnormal(coords.x))
3764 if (animCurrent == spinkickreversalanim || animCurrent == swordslashreversalanim)
3765 oldcoords = coords + facing * .5;
3766 else if (animCurrent == sweepreversalanim)
3767 oldcoords = coords + facing * 1.1;
3768 else if (animCurrent == upunchreversalanim) {
3769 oldcoords = coords + facing * 1.5;
3772 targetheadyaw += 180;
3775 } else if (animCurrent == knifeslashreversalanim) {
3776 oldcoords = coords + facing * .5;
3779 targetheadyaw += 90;
3782 } else if (animCurrent == staffspinhitreversalanim) {
3785 targetheadyaw += 180;
3790 oldcoords.y = terrain.getHeight(oldcoords.x, oldcoords.z);
3792 oldcoords.y = ycoords;
3793 currentoffset = coords - oldcoords;
3799 if (animCurrent == knifesneakattackedanim || animCurrent == swordsneakattackedanim) {
3804 if (animation[animTarget].attack == reversed) {
3806 if (animTarget == sweepreversedanim)
3808 animTarget = backhandspringanim;
3810 emit_sound_at(landsound, coords, 128);
3812 if (animCurrent == upunchreversedanim || animCurrent == swordslashreversedanim) {
3813 animTarget = rollanim;
3816 coords += (DoRotation(jointPos(leftfoot), 0, yaw, 0) + DoRotation(jointPos(rightfoot), 0, yaw, 0)) / 2 * scale;
3817 coords.y = oldcoords.y;
3819 if (animCurrent == knifeslashreversedanim) {
3820 animTarget = rollanim;
3825 coords += (DoRotation(jointPos(leftfoot), 0, yaw, 0) + DoRotation(jointPos(rightfoot), 0, yaw, 0)) / 2 * scale;
3826 coords.y = oldcoords.y;
3830 animTarget = jumpdownanim;
3833 animTarget = getIdle();
3835 animTarget = getIdle();
3836 if (animCurrent == spinkickanim || animCurrent == getupfrombackanim || animCurrent == getupfromfrontanim || animCurrent == lowkickanim) {
3837 animTarget = getIdle();
3839 coords += (DoRotation(jointPos(leftfoot), 0, yaw, 0) + DoRotation(jointPos(rightfoot), 0, yaw, 0)) / 2 * scale;
3840 coords.y = oldcoords.y;
3841 //coords+=DoRotation(animation[animCurrent].offset,0,yaw,0)*scale;
3842 targetoffset.y = coords.y;
3844 targetoffset.y = terrain.getHeight(coords.x, coords.z);
3845 currentoffset = DoRotation(animation[animCurrent].offset * -1, 0, yaw, 0) * scale;
3846 currentoffset.y -= (coords.y - targetoffset.y);
3847 coords.y = targetoffset.y;
3849 normalsupdatedelay = 0;
3851 if (animCurrent == upunchanim) {
3852 animTarget = getStop();
3853 normalsupdatedelay = 0;
3856 if (animCurrent == rabbitkickanim && animTarget != backflipanim) {
3860 if (num_weapons > 0)
3861 if (weapons[0].getType() == staff)
3867 rabbitkickragdoll = 1;
3869 if (animCurrent == rabbitkickreversedanim) {
3875 skeleton.spinny = 0;
3876 SolidHitBonus(!id); // FIXME: tricky id
3880 animTarget = rollanim;
3883 pause_sound(whooshsound);
3887 if (animCurrent == rabbittackledbackanim || animCurrent == rabbittackledfrontanim) {
3891 skeleton.spinny = 0;
3893 if (animCurrent == jumpreversedanim) {
3899 skeleton.spinny = 0;
3900 SolidHitBonus(!id); // FIXME: tricky id
3904 animTarget = rollanim;
3905 coords += facing * 2;
3907 pause_sound(whooshsound);
3912 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) {
3913 animTarget = getupfromfrontanim;
3915 } else if (animation[animCurrent].attack == normalattack) {
3916 animTarget = getIdle();
3919 if (animCurrent == blockhighleftanim && aitype != playercontrolled) {
3920 animTarget = blockhighleftstrikeanim;
3922 if (animCurrent == knifeslashstartanim || animCurrent == knifethrowanim || animCurrent == swordslashanim || animCurrent == staffhitanim || animCurrent == staffgroundsmashanim || animCurrent == staffspinhitanim) {
3923 animTarget = getIdle();
3926 if (animCurrent == spinkickanim && victim->skeleton.free) {
3927 if (creature == rabbittype)
3928 animTarget = fightidleanim;
3933 if (isIdle() && !wasIdle())
3934 normalsupdatedelay = 0;
3936 if (animCurrent == jumpupanim && velocity.y < 0 && !isFlip()) {
3937 animTarget = jumpdownanim;
3940 if (!skeleton.free) {
3942 if (!transspeed && animation[animTarget].attack != 2 && animation[animTarget].attack != 3) {
3943 if (!isRun() || !wasRun()) {
3944 if (animation[animTarget].speed[frameTarget] > animation[animCurrent].speed[frameCurrent])
3945 target += multiplier * animation[animTarget].speed[frameTarget] * speed * 2;
3946 if (animation[animTarget].speed[frameTarget] <= animation[animCurrent].speed[frameCurrent])
3947 target += multiplier * animation[animCurrent].speed[frameCurrent] * speed * 2;
3949 if (isRun() && wasRun()) {
3951 tempspeed = velspeed;
3952 if (tempspeed < 10 * speedmult)
3953 tempspeed = 10 * speedmult;
3954 target += multiplier * animation[animTarget].speed[frameCurrent] * speed * 1.7 * tempspeed / (speed * 45 * scale);
3956 } else if (transspeed)
3957 target += multiplier * transspeed * speed * 2;
3959 if (!isRun() || !wasRun()) {
3960 if (animation[animTarget].speed[frameTarget] > animation[animCurrent].speed[frameCurrent])
3961 target += multiplier * animation[animTarget].speed[frameTarget] * 2;
3962 if (animation[animTarget].speed[frameTarget] <= animation[animCurrent].speed[frameCurrent])
3963 target += multiplier * animation[animCurrent].speed[frameCurrent] * 2;
3967 if (animCurrent != animTarget)
3968 target = (target + oldtarget) / 2;
3971 frameCurrent = frameTarget;
3975 rot = targetrot * target;
3976 yaw += rot - oldrot;
3982 if (animCurrent != oldanimCurrent || animTarget != oldanimTarget || ((frameCurrent != oldframeCurrent || frameTarget != oldframeTarget) && !calcrot)) {
3984 for (int i = 0; i < skeleton.num_joints; i++) {
3985 skeleton.joints[i].position = animation[animCurrent].position[i][frameCurrent];
3988 skeleton.FindForwards();
3990 for (int i = 0; i < skeleton.num_muscles; i++) {
3991 if (skeleton.muscles[i].visible) {
3992 skeleton.FindRotationMuscle(i, animTarget);
3995 for (int i = 0; i < skeleton.num_muscles; i++) {
3996 if (skeleton.muscles[i].visible) {
3997 if (isnormal((float)((int)(skeleton.muscles[i].rotate1 * 100) % 36000) / 100))
3998 skeleton.muscles[i].oldrotate1 = (float)((int)(skeleton.muscles[i].rotate1 * 100) % 36000) / 100;
3999 if (isnormal((float)((int)(skeleton.muscles[i].rotate2 * 100) % 36000) / 100))
4000 skeleton.muscles[i].oldrotate2 = (float)((int)(skeleton.muscles[i].rotate2 * 100) % 36000) / 100;
4001 if (isnormal((float)((int)(skeleton.muscles[i].rotate3 * 100) % 36000) / 100))
4002 skeleton.muscles[i].oldrotate3 = (float)((int)(skeleton.muscles[i].rotate3 * 100) % 36000) / 100;
4007 for (int i = 0; i < skeleton.num_joints; i++) {
4008 skeleton.joints[i].position = animation[animTarget].position[i][frameTarget];
4011 skeleton.FindForwards();
4013 for (int i = 0; i < skeleton.num_muscles; i++) {
4014 if (skeleton.muscles[i].visible) {
4015 skeleton.FindRotationMuscle(i, animTarget);
4018 for (int i = 0; i < skeleton.num_muscles; i++) {
4019 if (skeleton.muscles[i].visible) {
4020 if (isnormal((float)((int)(skeleton.muscles[i].rotate1 * 100) % 36000) / 100))
4021 skeleton.muscles[i].newrotate1 = (float)((int)(skeleton.muscles[i].rotate1 * 100) % 36000) / 100;
4022 if (isnormal((float)((int)(skeleton.muscles[i].rotate2 * 100) % 36000) / 100))
4023 skeleton.muscles[i].newrotate2 = (float)((int)(skeleton.muscles[i].rotate2 * 100) % 36000) / 100;
4024 if (isnormal((float)((int)(skeleton.muscles[i].rotate3 * 100) % 36000) / 100))
4025 skeleton.muscles[i].newrotate3 = (float)((int)(skeleton.muscles[i].rotate3 * 100) % 36000) / 100;
4026 if (skeleton.muscles[i].newrotate3 > skeleton.muscles[i].oldrotate3 + 180) skeleton.muscles[i].newrotate3 -= 360;
4027 if (skeleton.muscles[i].newrotate3 < skeleton.muscles[i].oldrotate3 - 180) skeleton.muscles[i].newrotate3 += 360;
4028 if (skeleton.muscles[i].newrotate2 > skeleton.muscles[i].oldrotate2 + 180) skeleton.muscles[i].newrotate2 -= 360;
4029 if (skeleton.muscles[i].newrotate2 < skeleton.muscles[i].oldrotate2 - 180) skeleton.muscles[i].newrotate2 += 360;
4030 if (skeleton.muscles[i].newrotate1 > skeleton.muscles[i].oldrotate1 + 180) skeleton.muscles[i].newrotate1 -= 360;
4031 if (skeleton.muscles[i].newrotate1 < skeleton.muscles[i].oldrotate1 - 180) skeleton.muscles[i].newrotate1 += 360;
4035 if (frameCurrent >= animation[animCurrent].numframes)
4036 frameCurrent = animation[animCurrent].numframes - 1;
4038 oldanimCurrent = animCurrent;
4039 oldanimTarget = animTarget;
4040 oldframeTarget = frameTarget;
4041 oldframeCurrent = frameCurrent;
4043 for (int i = 0; i < skeleton.num_joints; i++) {
4044 skeleton.joints[i].velocity = (animation[animCurrent].position[i][frameCurrent] * (1 - target) + animation[animTarget].position[i][frameTarget] * (target) - skeleton.joints[i].position) / multiplier;
4045 skeleton.joints[i].position = animation[animCurrent].position[i][frameCurrent] * (1 - target) + animation[animTarget].position[i][frameTarget] * (target);
4047 offset = currentoffset * (1 - target) + targetoffset * target;
4048 for (int i = 0; i < skeleton.num_muscles; i++) {
4049 if (skeleton.muscles[i].visible) {
4050 skeleton.muscles[i].rotate1 = skeleton.muscles[i].oldrotate1 * (1 - target) + skeleton.muscles[i].newrotate1 * (target);
4051 skeleton.muscles[i].rotate2 = skeleton.muscles[i].oldrotate2 * (1 - target) + skeleton.muscles[i].newrotate2 * (target);
4052 skeleton.muscles[i].rotate3 = skeleton.muscles[i].oldrotate3 * (1 - target) + skeleton.muscles[i].newrotate3 * (target);
4057 if (isLanding() && landhard) {
4060 animTarget = getLandhard();
4073 void Person::DoStuff()
4075 static XYZ terrainnormal;
4076 static XYZ flatfacing;
4077 static XYZ flatvelocity;
4078 static float flatvelspeed;
4082 static int bloodsize;
4083 static int startx, starty, endx, endy;
4084 static GLubyte color;
4085 static XYZ bloodvel;
4087 onfiredelay -= multiplier;
4088 if (onfiredelay < 0 && onfire) {
4089 if (Random() % 2 == 0) {
4095 crouchkeydowntime += multiplier;
4097 crouchkeydowntime = 0;
4098 jumpkeydowntime += multiplier;
4099 if (!jumpkeydown && skeleton.free)
4100 jumpkeydowntime = 0;
4102 if (hostile || damage > 0 || bloodloss > 0)
4105 if (isIdle() || isRun())
4108 if (num_weapons == 1 && weaponactive != -1)
4112 blooddimamount -= multiplier * .3;
4113 speechdelay -= multiplier;
4114 texupdatedelay -= multiplier;
4115 interestdelay -= multiplier;
4116 flamedelay -= multiplier;
4117 parriedrecently -= multiplier;
4119 victim = this->shared_from_this();
4124 speed = 1.1 * speedmult;
4126 speed = 1.0 * speedmult;
4128 rabbitkickragdoll = 0;
4132 if (id != 0 && (creature == rabbittype || difficulty != 2))
4134 if (id != 0 && creature == wolftype && difficulty == 2) {
4136 if (aitype != passivetype) {
4138 if (aitype == attacktypecutoff && (Person::players[0]->isIdle() || Person::players[0]->isCrouch() || Person::players[0]->skeleton.free || Person::players[0]->animTarget == getupfrombackanim || Person::players[0]->animTarget == getupfromfrontanim || Person::players[0]->animTarget == sneakanim) && distsq(&coords, &Person::players[0]->coords) < 16) {
4144 if (animTarget == wolfrunninganim && !superruntoggle) {
4145 animTarget = getRun();
4149 if (weaponactive == -1 && num_weapons > 0) {
4150 if (weapons[weaponids[0]].getType() == staff) {
4156 burnt += multiplier;
4160 OPENAL_SetVolume(channels[stream_firesound], 256 + 256 * findLength(&velocity) / 3);
4162 if (animTarget == jumpupanim || animTarget == jumpdownanim || isFlip()) {
4168 vel[0] = velocity.x;
4169 vel[1] = velocity.y;
4170 vel[2] = velocity.z;
4173 OPENAL_3D_SetAttributes(channels[whooshsound], gLoc, vel);
4174 OPENAL_SetVolume(channels[whooshsound], 64 * findLength(&velocity) / 5);
4178 while (flamedelay < 0 && onfire) {
4180 howmany = abs(Random() % (skeleton.num_joints));
4182 flatvelocity = (coords - oldcoords) / multiplier / 2; //velocity/2;
4184 flatvelocity = skeleton.joints[howmany].velocity * scale / 2;
4186 flatfacing = DoRotation(DoRotation(DoRotation(skeleton.joints[howmany].position, 0, 0, tilt), tilt2, 0, 0), 0, yaw, 0) * scale + coords;
4188 flatfacing = skeleton.joints[howmany].position * scale + coords;
4189 Sprite::MakeSprite(flamesprite, flatfacing, flatvelocity, 1, 1, 1, .6 + (float)abs(Random() % 100) / 200 - .25, 1);
4192 while (flamedelay < 0 && !onfire && tutoriallevel == 1 && id != 0) {
4194 howmany = abs(Random() % (skeleton.num_joints));
4196 flatvelocity = (coords - oldcoords) / multiplier / 2; //velocity/2;
4198 flatvelocity = skeleton.joints[howmany].velocity * scale / 2;
4200 flatfacing = DoRotation(DoRotation(DoRotation(skeleton.joints[howmany].position, 0, 0, tilt), tilt2, 0, 0), 0, yaw, 0) * scale + coords;
4202 flatfacing = skeleton.joints[howmany].position * scale + coords;
4203 Sprite::MakeSprite(breathsprite, flatfacing, flatvelocity, 1, 1, 1, .6 + (float)abs(Random() % 100) / 200 - .25, .3);
4207 bleeding -= multiplier * .3;
4208 if (bloodtoggle == 2) {
4209 skeleton.drawmodel.textureptr.bind();
4210 if ((bleeding <= 0) && (detail != 2))
4215 if (neckspurtamount > 0) {
4216 neckspurtamount -= multiplier;
4217 neckspurtdelay -= multiplier * 3;
4218 neckspurtparticledelay -= multiplier * 3;
4219 if (neckspurtparticledelay < 0 && neckspurtdelay > 2) {
4222 if (!skeleton.free) {
4223 bloodvel.z = 5 * neckspurtamount;
4224 bloodvel = DoRotation(bloodvel, ((float)(Random() % 100)) / 40, yaw + ((float)(Random() % 100)) / 40, 0) * scale;
4226 if (skeleton.free) {
4227 bloodvel -= DoRotation(skeleton.forward * 10 * scale, ((float)(Random() % 100)) / 40, ((float)(Random() % 100)) / 40, 0);
4230 bloodvel += DoRotation(jointVel(head), ((float)(Random() % 100)) / 40, yaw + ((float)(Random() % 100)) / 40, 0) * scale;
4232 bloodvel += DoRotation(velocity, ((float)(Random() % 100)) / 40, ((float)(Random() % 100)) / 40, 0) * scale;
4234 Sprite::MakeSprite(bloodsprite, (jointPos(neck) + (jointPos(neck) - jointPos(head)) / 5)*scale + coords, bloodvel, 1, 1, 1, .05, .9);
4236 Sprite::MakeSprite(bloodsprite, DoRotation(jointPos(neck) + (jointPos(neck) - jointPos(head)) / 5, 0, yaw, 0)*scale + coords, bloodvel, 1, 1, 1, .05, .9);
4237 neckspurtparticledelay = .05;
4239 if (neckspurtdelay < 0) {
4244 if (deathbleeding > 0 && dead != 2) {
4245 if (deathbleeding < 5)
4246 bleeddelay -= deathbleeding * multiplier / 4;
4248 bleeddelay -= 5 * multiplier / 4;
4249 if (bleeddelay < 0 && bloodtoggle) {
4255 bloodvel += DoRotation(jointVel(abdomen), ((float)(Random() % 100)) / 4, yaw + ((float)(Random() % 100)) / 4, 0) * scale;
4257 bloodvel += DoRotation(velocity, ((float)(Random() % 100)) / 4, ((float)(Random() % 100)) / 4, 0) * scale;
4259 Sprite::MakeSprite(bloodsprite, jointPos(abdomen) * scale + coords, bloodvel, 1, 1, 1, .05, 1);
4261 Sprite::MakeSprite(bloodsprite, DoRotation((jointPos(abdomen) + jointPos(abdomen)) / 2, 0, yaw, 0)*scale + coords, bloodvel, 1, 1, 1, .05, 1);
4264 bloodloss += deathbleeding * multiplier * 80;
4265 deathbleeding -= multiplier * 1.6;
4266 if (deathbleeding < 0)
4268 if (bloodloss > damagetolerance && animation[animTarget].attack == neutral) {
4269 if (weaponactive != -1) {
4270 weapons[weaponids[0]].owner = -1;
4271 weapons[weaponids[0]].velocity = velocity * scale * -.3;
4272 weapons[weaponids[0]].velocity.x += .01;
4273 weapons[weaponids[0]].tipvelocity = velocity * scale;
4274 weapons[weaponids[0]].missed = 1;
4275 weapons[weaponids[0]].hitsomething = 0;
4276 weapons[weaponids[0]].freetime = 0;
4277 weapons[weaponids[0]].firstfree = 1;
4278 weapons[weaponids[0]].physics = 1;
4281 weaponids[0] = weaponids[num_weapons];
4282 if (weaponstuck == num_weapons)
4286 for (unsigned i = 0; i < Person::players.size(); i++) {
4287 Person::players[i]->wentforweapon = 0;
4299 if (!dead && creature == wolftype) {
4300 award_bonus(0, Wolfbonus);
4303 if (animTarget == knifefollowedanim && !skeleton.free) {
4304 for (int i = 0; i < skeleton.num_joints; i++) {
4305 skeleton.joints[i].velocity = 0;
4306 skeleton.joints[i].velocity.y = -2;
4309 if (id != 0 && unconscioustime > .1) {
4317 if (texupdatedelay < 0 && bleeding > 0 && bloodtoggle == 2 && distsq(&viewer, &coords) < 9) {
4318 texupdatedelay = .12;
4320 bloodsize = 5 - realtexdetail;
4324 startx = bleedy; //abs(Random()%(skeleton.skinsize-bloodsize-1));
4325 starty = bleedx; //abs(Random()%(skeleton.skinsize-bloodsize-1));
4326 endx = startx + bloodsize;
4327 endy = starty + bloodsize;
4337 if (endx > skeleton.skinsize - 1) {
4338 endx = skeleton.skinsize - 1;
4341 if (endy > skeleton.skinsize - 1) {
4342 endy = skeleton.skinsize - 1;
4350 for (i = startx; i < endx; i++) {
4351 for (j = starty; j < endy; j++) {
4352 if (Random() % 2 == 0) {
4353 color = Random() % 85 + 170;
4354 if (skeleton.skinText[i * skeleton.skinsize * 3 + j * 3 + 0] > color / 2)
4355 skeleton.skinText[i * skeleton.skinsize * 3 + j * 3 + 0] = color / 2;
4356 skeleton.skinText[i * skeleton.skinsize * 3 + j * 3 + 1] = 0;
4357 skeleton.skinText[i * skeleton.skinsize * 3 + j * 3 + 2] = 0;
4362 skeleton.drawmodel.textureptr.bind();
4366 if (!skeleton.free) {
4367 bleedy -= 4 / realtexdetail;
4369 bleedx += (abs(Random() % 3) - 1) * 2 / realtexdetail;
4371 bleedx += (abs(Random() % 3) - 1) * 4 / realtexdetail;
4373 if (skeleton.free) {
4374 bleedx += 4 * direction / realtexdetail;
4376 bleedy += (abs(Random() % 3) - 1) * 2 / realtexdetail;
4378 bleedy += (abs(Random() % 3) - 1) * 4 / realtexdetail;
4382 if (abs(righthandmorphness - targetrighthandmorphness) < multiplier * 4) {
4383 righthandmorphness = targetrighthandmorphness;
4384 righthandmorphstart = righthandmorphend;
4385 } else if (righthandmorphness > targetrighthandmorphness) {
4386 righthandmorphness -= multiplier * 4;
4387 } else if (righthandmorphness < targetrighthandmorphness) {
4388 righthandmorphness += multiplier * 4;
4391 if (abs(lefthandmorphness - targetlefthandmorphness) < multiplier * 4) {
4392 lefthandmorphness = targetlefthandmorphness;
4393 lefthandmorphstart = lefthandmorphend;
4394 } else if (lefthandmorphness > targetlefthandmorphness) {
4395 lefthandmorphness -= multiplier * 4;
4396 } else if (lefthandmorphness < targetlefthandmorphness) {
4397 lefthandmorphness += multiplier * 4;
4400 if (creature == rabbittype || targettailmorphness == 5 || targettailmorphness == 0) {
4401 if (abs(tailmorphness - targettailmorphness) < multiplier * 10) {
4402 tailmorphness = targettailmorphness;
4403 tailmorphstart = tailmorphend;
4404 } else if (tailmorphness > targettailmorphness) {
4405 tailmorphness -= multiplier * 10;
4406 } else if (tailmorphness < targettailmorphness) {
4407 tailmorphness += multiplier * 10;
4411 if (creature == wolftype) {
4412 if (abs(tailmorphness - targettailmorphness) < multiplier * 4) {
4413 tailmorphness = targettailmorphness;
4414 tailmorphstart = tailmorphend;
4415 } else if (tailmorphness > targettailmorphness) {
4416 tailmorphness -= multiplier * 2;
4417 } else if (tailmorphness < targettailmorphness) {
4418 tailmorphness += multiplier * 2;
4422 if (headmorphend == 3 || headmorphstart == 3) {
4423 if (abs(headmorphness - targetheadmorphness) < multiplier * 7) {
4424 headmorphness = targetheadmorphness;
4425 headmorphstart = headmorphend;
4426 } else if (headmorphness > targetheadmorphness) {
4427 headmorphness -= multiplier * 7;
4428 } else if (headmorphness < targetheadmorphness) {
4429 headmorphness += multiplier * 7;
4431 } else if (headmorphend == 5 || headmorphstart == 5) {
4432 if (abs(headmorphness - targetheadmorphness) < multiplier * 10) {
4433 headmorphness = targetheadmorphness;
4434 headmorphstart = headmorphend;
4435 } else if (headmorphness > targetheadmorphness) {
4436 headmorphness -= multiplier * 10;
4437 } else if (headmorphness < targetheadmorphness) {
4438 headmorphness += multiplier * 10;
4441 if (abs(headmorphness - targetheadmorphness) < multiplier * 4) {
4442 headmorphness = targetheadmorphness;
4443 headmorphstart = headmorphend;
4444 } else if (headmorphness > targetheadmorphness) {
4445 headmorphness -= multiplier * 4;
4446 } else if (headmorphness < targetheadmorphness) {
4447 headmorphness += multiplier * 4;
4451 if (abs(chestmorphness - targetchestmorphness) < multiplier) {
4452 chestmorphness = targetchestmorphness;
4453 chestmorphstart = chestmorphend;
4454 } else if (chestmorphness > targetchestmorphness) {
4455 chestmorphness -= multiplier;
4456 } else if (chestmorphness < targetchestmorphness) {
4457 chestmorphness += multiplier;
4460 if (dead != 2 && howactive <= typesleeping) {
4461 if (chestmorphstart == 0 && chestmorphend == 0) {
4463 targetchestmorphness = 1;
4466 if (chestmorphstart != 0 && chestmorphend != 0) {
4468 targetchestmorphness = 1;
4470 if (environment == snowyenvironment) {
4474 footvel = DoRotation(skeleton.specialforward[0], 0, yaw, 0) * -1;
4476 footvel = skeleton.specialforward[0] * -1;
4478 footpoint = DoRotation((jointPos(head) + jointPos(neck)) / 2, 0, yaw, 0) * scale + coords;
4480 footpoint = ((jointPos(head) + jointPos(neck)) / 2) * scale + coords;
4481 if (animTarget == sleepanim)
4482 footvel = DoRotation(footvel, 0, 90, 0);
4483 Sprite::MakeSprite(breathsprite, footpoint + footvel * .2, footvel * .4, 1, 1, 1, .4, .3);
4487 if (!dead && howactive < typesleeping) {
4488 blinkdelay -= multiplier * 2;
4489 if (headmorphstart == 0 && headmorphend == 0 && blinkdelay <= 0) {
4491 targetheadmorphness = 1;
4493 blinkdelay = (float)(abs(Random() % 40)) / 5;
4495 if (headmorphstart == 3 && headmorphend == 3) {
4497 targetheadmorphness = 1;
4502 twitchdelay -= multiplier * 1.5;
4503 if (animTarget != hurtidleanim) {
4504 if (headmorphstart == 0 && headmorphend == 0 && twitchdelay <= 0) {
4506 targetheadmorphness = 1;
4508 twitchdelay = (float)(abs(Random() % 40)) / 5;
4510 if (headmorphstart == 5 && headmorphend == 5) {
4512 targetheadmorphness = 1;
4516 if ((isIdle() || isCrouch()) && animTarget != hurtidleanim) {
4517 twitchdelay3 -= multiplier * 1;
4518 if (Random() % 2 == 0) {
4519 if (righthandmorphstart == 0 && righthandmorphend == 0 && twitchdelay3 <= 0) {
4520 righthandmorphness = 0;
4521 targetrighthandmorphness = 1;
4522 righthandmorphend = 1;
4523 if (Random() % 2 == 0)twitchdelay3 = (float)(abs(Random() % 40)) / 5;
4525 if (righthandmorphstart == 1 && righthandmorphend == 1) {
4526 righthandmorphness = 0;
4527 targetrighthandmorphness = 1;
4528 righthandmorphend = 0;
4531 if (Random() % 2 == 0) {
4532 if (lefthandmorphstart == 0 && lefthandmorphend == 0 && twitchdelay3 <= 0) {
4533 lefthandmorphness = 0;
4534 targetlefthandmorphness = 1;
4535 lefthandmorphend = 1;
4536 twitchdelay3 = (float)(abs(Random() % 40)) / 5;
4538 if (lefthandmorphstart == 1 && lefthandmorphend == 1) {
4539 lefthandmorphness = 0;
4540 targetlefthandmorphness = 1;
4541 lefthandmorphend = 0;
4547 if (creature == rabbittype) {
4548 if (howactive < typesleeping)
4549 twitchdelay2 -= multiplier * 1.5;
4551 twitchdelay2 -= multiplier * 0.5;
4552 if (howactive <= typesleeping) {
4553 if (tailmorphstart == 0 && tailmorphend == 0 && twitchdelay2 <= 0) {
4555 targettailmorphness = 1;
4557 twitchdelay2 = (float)(abs(Random() % 40)) / 5;
4559 if (tailmorphstart == 1 && tailmorphend == 1) {
4561 targettailmorphness = 1;
4564 if (tailmorphstart == 2 && tailmorphend == 2) {
4566 targettailmorphness = 1;
4573 if (creature == wolftype) {
4574 twitchdelay2 -= multiplier * 1.5;
4575 if (tailmorphend != 0)
4576 if ((isRun() || animTarget == jumpupanim || animTarget == jumpdownanim || animTarget == backflipanim) && !skeleton.free) {
4578 targettailmorphness = 1;
4582 if (tailmorphend != 5)
4583 if (animTarget == flipanim || animTarget == frontflipanim || animTarget == rollanim || skeleton.free) {
4585 targettailmorphness = 1;
4589 if (twitchdelay2 <= 0) {
4590 if (((tailmorphstart == 0 && tailmorphend == 0) || (tailmorphstart == 5 && tailmorphend == 5))) {
4592 targettailmorphness = 1;
4595 if (tailmorphstart == 1 && tailmorphend == 1) {
4597 targettailmorphness = 1;
4600 if (tailmorphstart == 2 && tailmorphend == 2) {
4602 targettailmorphness = 1;
4605 if (tailmorphstart == 3 && tailmorphend == 3) {
4607 targettailmorphness = 1;
4610 if (tailmorphstart == 4 && tailmorphend == 4) {
4612 targettailmorphness = 1;
4619 unconscioustime = 0;
4621 if (dead == 1 || howactive == typesleeping) {
4622 unconscioustime += multiplier;
4623 //If unconscious, close eyes and mouth
4624 if (righthandmorphend != 0)
4625 righthandmorphness = 0;
4626 righthandmorphend = 0;
4627 targetrighthandmorphness = 1;
4629 if (lefthandmorphend != 0)
4630 lefthandmorphness = 0;
4631 lefthandmorphend = 0;
4632 targetlefthandmorphness = 1;
4634 if (headmorphend != 3 && headmorphend != 5)
4637 targetheadmorphness = 1;
4641 if (howactive > typesleeping) {
4644 if (bloodtoggle && !bled) {
4645 terrain.MakeDecal(blooddecalslow, headpoint, .8, .5, 0);
4647 if (bloodtoggle && !bled)
4648 for (l = 0; l < terrain.patchobjectnum[whichpatchx][whichpatchz]; l++) {
4649 j = terrain.patchobjects[whichpatchx][whichpatchz][l];
4650 XYZ point = DoRotation(headpoint - objects.position[j], 0, -objects.yaw[j], 0);
4654 objects.model[j].MakeDecal(blooddecalslow, &point, &size, &opacity, &yaw);
4659 if (dead == 2 || howactive > typesleeping) {
4660 //If dead, open mouth and hands
4661 if (righthandmorphend != 0)
4662 righthandmorphness = 0;
4663 righthandmorphend = 0;
4664 targetrighthandmorphness = 1;
4666 if (lefthandmorphend != 0)
4667 lefthandmorphness = 0;
4668 lefthandmorphend = 0;
4669 targetlefthandmorphness = 1;
4671 if (headmorphend != 2)
4674 targetheadmorphness = 1;
4677 if (stunned > 0 && !dead && headmorphend != 2) {
4678 if (headmorphend != 4)
4681 targetheadmorphness = 1;
4684 if (damage > damagetolerance && !dead) {
4687 unconscioustime = 0;
4689 if (creature == wolftype) {
4690 award_bonus(0, Wolfbonus);
4695 if (weaponactive != -1) {
4696 weapons[weaponids[0]].owner = -1;
4697 weapons[weaponids[0]].velocity = velocity * scale * -.3;
4698 weapons[weaponids[0]].velocity.x += .01;
4699 weapons[weaponids[0]].tipvelocity = velocity * scale;
4700 weapons[weaponids[0]].missed = 1;
4701 weapons[weaponids[0]].hitsomething = 0;
4702 weapons[weaponids[0]].freetime = 0;
4703 weapons[weaponids[0]].firstfree = 1;
4704 weapons[weaponids[0]].physics = 1;
4707 weaponids[0] = weaponids[num_weapons];
4708 if (weaponstuck == num_weapons)
4712 for (unsigned i = 0; i < Person::players.size(); i++) {
4713 Person::players[i]->wentforweapon = 0;
4719 if ((id == 0 || distsq(&coords, &viewer) < 50) && autoslomo) {
4728 damage -= multiplier * 13;
4730 permanentdamage -= multiplier * 4;
4731 if (isIdle() || isCrouch()) {
4733 permanentdamage -= multiplier * 4;
4737 if (permanentdamage < 0)
4738 permanentdamage = 0;
4739 if (superpermanentdamage < 0)
4740 superpermanentdamage = 0;
4741 if (permanentdamage < superpermanentdamage) {
4742 permanentdamage = superpermanentdamage;
4744 if (damage < permanentdamage) {
4745 damage = permanentdamage;
4747 if (dead == 1 && damage < damagetolerance) {
4751 for (int i = 0; i < skeleton.num_joints; i++) {
4752 skeleton.joints[i].velocity = 0;
4755 if (permanentdamage > damagetolerance && dead != 2) {
4758 if (weaponactive != -1) {
4759 weapons[weaponids[0]].owner = -1;
4760 weapons[weaponids[0]].velocity = velocity * scale * -.3;
4761 weapons[weaponids[0]].velocity.x += .01;
4762 weapons[weaponids[0]].tipvelocity = velocity * scale;
4763 weapons[weaponids[0]].missed = 1;
4764 weapons[weaponids[0]].hitsomething = 0;
4765 weapons[weaponids[0]].freetime = 0;
4766 weapons[weaponids[0]].firstfree = 1;
4767 weapons[weaponids[0]].physics = 1;
4770 weaponids[0] = weaponids[num_weapons];
4771 if (weaponstuck == num_weapons)
4775 for (unsigned i = 0; i < Person::players.size(); i++) {
4776 Person::players[i]->wentforweapon = 0;
4782 if (!dead && creature == wolftype) {
4783 award_bonus(0, Wolfbonus);
4786 if (unconscioustime < .1 && (bonus != spinecrusher || bonustime > 1) && (bonus != FinishedBonus || bonustime > 1) && bloodloss < damagetolerance)
4787 award_bonus(id, touchofdeath);
4788 if (id != 0 && unconscioustime > .1) {
4796 emit_sound_at(breaksound, coords);
4799 if (skeleton.free == 1) {
4801 pause_sound(whooshsound);
4804 //If knocked over, open hands and close mouth
4805 if (righthandmorphend != 0)
4806 righthandmorphness = 0;
4807 righthandmorphend = 0;
4808 targetrighthandmorphness = 1;
4810 if (lefthandmorphend != 0)
4811 lefthandmorphness = 0;
4812 lefthandmorphend = 0;
4813 targetlefthandmorphness = 1;
4815 if (headmorphend != 3 && headmorphend != 5 && headmorphstart != 3 && headmorphstart != 5) {
4816 if (headmorphend != 0)
4819 targetheadmorphness = 1;
4823 skeleton.DoGravity(&scale);
4825 damageamount = skeleton.DoConstraints(&coords, &scale) * 5;
4826 if (damage > damagetolerance - damageamount && !dead && (bonus != spinecrusher || bonustime > 1) && (bonus != style || bonustime > 1) && (bonus != cannon || bonustime > 1))
4827 award_bonus(id, deepimpact);
4828 DoDamage(damageamount / ((protectionhigh + protectionhead + protectionlow) / 3));
4832 for (j = 0; j < skeleton.num_joints; j++) {
4833 average += skeleton.joints[j].position;
4837 coords += average * scale;
4838 for (j = 0; j < skeleton.num_joints; j++) {
4839 skeleton.joints[j].position -= average;
4841 average /= multiplier;
4843 //velocity=jointVel(groin)*scale;
4845 for (int i = 0; i < skeleton.num_joints; i++) {
4846 velocity += skeleton.joints[i].velocity * scale;
4848 velocity /= skeleton.num_joints;
4850 if (!isnormal(velocity.x) && velocity.x) {
4854 if (findLength(&average) < 10 && dead && skeleton.free) {
4855 skeleton.longdead += (2000 - findLength(&average)) * multiplier + multiplier;
4856 if (skeleton.longdead > 2000) {
4857 if (skeleton.longdead > 6000) {
4859 pause_sound(whooshsound);
4864 if (dead == 2 && bloodloss < damagetolerance) {
4866 headpoint = (jointPos(head) + jointPos(neck)) / 2 * scale + coords;
4868 if (bloodtoggle && !bled) {
4869 terrain.MakeDecal(blooddecal, headpoint, .2 * 1.2, .5, 0);
4871 if (bloodtoggle && !bled)
4872 for (l = 0; l < terrain.patchobjectnum[whichpatchx][whichpatchz]; l++) {
4873 j = terrain.patchobjects[whichpatchx][whichpatchz][l];
4874 XYZ point = DoRotation(headpoint - objects.position[j], 0, -objects.yaw[j], 0);
4875 float size = .2 * 1.2;
4878 objects.model[j].MakeDecal(blooddecal, &point, &size, &opacity, &yaw);
4882 if (dead == 2 && bloodloss >= damagetolerance) {
4884 headpoint = (jointPos(abdomen) + jointPos(neck)) / 2 * scale + coords;
4887 if (bloodtoggle && !bled) {
4888 terrain.MakeDecal(blooddecalslow, headpoint, .8, .5, 0);
4890 if (bloodtoggle && !bled)
4891 for (l = 0; l < terrain.patchobjectnum[whichpatchx][whichpatchz]; l++) {
4892 j = terrain.patchobjects[whichpatchx][whichpatchz][l];
4893 XYZ point = DoRotation(headpoint - objects.position[j], 0, -objects.yaw[j], 0);
4897 objects.model[j].MakeDecal(blooddecalslow, &point, &size, &opacity, &yaw);
4904 if (!dead && crouchkeydown && skeleton.freetime > .5 && id == 0 && skeleton.free) {
4905 bool canrecover = 1;
4906 XYZ startpoint, endpoint, colpoint, colviewer, coltarget;
4907 startpoint = coords;
4910 if (terrain.lineTerrain(startpoint, endpoint, &colpoint) != -1)
4912 if (velocity.y < -30)
4914 for (i = 0; i < objects.numobjects; i++) {
4915 if (objects.type[i] != treeleavestype && objects.type[i] != bushtype && objects.type[i] != firetype) {
4916 colviewer = startpoint;
4917 coltarget = endpoint;
4918 if (objects.model[i].LineCheck(&colviewer, &coltarget, &colpoint, &objects.position[i], &objects.yaw[i]) != -1)
4927 terrainnormal = jointPos(groin) - jointPos(abdomen);
4928 if (joint(groin).locked && joint(abdomen).locked) {
4929 terrainnormal = jointPos(groin) - jointPos(abdomen);
4930 middle = (jointPos(groin) + jointPos(abdomen)) / 2;
4932 if (joint(abdomen).locked && joint(neck).locked) {
4933 terrainnormal = jointPos(abdomen) - jointPos(neck);
4934 middle = (jointPos(neck) + jointPos(abdomen)) / 2;
4936 if (joint(groin).locked && joint(neck).locked) {
4937 terrainnormal = jointPos(groin) - jointPos(neck);
4938 middle = (jointPos(groin) + jointPos(neck)) / 2;
4940 Normalise(&terrainnormal);
4942 targetyaw = -asin(0 - terrainnormal.x);
4943 targetyaw *= 360 / 6.28;
4944 if (terrainnormal.z < 0)
4945 targetyaw = 180 - targetyaw;
4949 animTarget = flipanim;
4950 crouchtogglekeydown = 1;
4955 animCurrent = tempanim;
4959 for (int i = 0; i < skeleton.num_joints; i++) {
4960 tempanimation.position[i][0] = skeleton.joints[i].position;
4961 tempanimation.position[i][0] = DoRotation(tempanimation.position[i][0], 0, -yaw, 0);
4966 if (findLength(&average) < 10 && !dead && skeleton.free) {
4967 skeleton.longdead += (2000 - findLength(&average)) * multiplier + multiplier;
4968 if (skeleton.longdead > (damage + 500) * 1.5) {
4970 pause_sound(whooshsound);
4976 terrainnormal = jointPos(groin) - jointPos(abdomen);
4977 if (joint(groin).locked && joint(abdomen).locked) {
4978 terrainnormal = jointPos(groin) - jointPos(abdomen);
4979 middle = (jointPos(groin) + jointPos(abdomen)) / 2;
4981 if (joint(abdomen).locked && joint(neck).locked) {
4982 terrainnormal = jointPos(abdomen) - jointPos(neck);
4983 middle = (jointPos(neck) + jointPos(abdomen)) / 2;
4985 if (joint(groin).locked && joint(neck).locked) {
4986 terrainnormal = jointPos(groin) - jointPos(neck);
4987 middle = (jointPos(groin) + jointPos(neck)) / 2;
4989 Normalise(&terrainnormal);
4991 targetyaw = -asin(0 - terrainnormal.x);
4992 targetyaw *= 360 / 6.28;
4993 if (terrainnormal.z < 0)
4994 targetyaw = 180 - targetyaw;
4997 targettilt2 = asin(terrainnormal.y) * 180 / 3.14 * -1;
5000 if (skeleton.forward.y < 0) {
5001 animTarget = getupfrombackanim;
5005 if (skeleton.forward.y > -.3) {
5006 animTarget = getupfromfrontanim;
5014 if ((Random() % 8 == 0 && id != 0 && creature == rabbittype) || (Random() % 2 == 0 && id != 0 && creature == wolftype) || (id == 0 && crouchkeydown && (forwardkeydown || backkeydown || leftkeydown || rightkeydown))) {
5015 animTarget = rollanim;
5016 targetyaw = lookyaw;
5033 if ( !leftkeydown && !rightkeydown)
5040 if (abs(targettilt2) > 50)
5042 animCurrent = tempanim;
5045 tilt2 = targettilt2;
5047 if (middle.y > 0 && animTarget != rollanim)
5048 targetoffset.y = middle.y + 1;
5050 for (int i = 0; i < skeleton.num_joints; i++) {
5051 tempanimation.position[i][0] = skeleton.joints[i].position;
5052 tempanimation.position[i][0] = DoRotation(tempanimation.position[i][0], 0, -yaw, 0);
5059 if (num_weapons > 0)
5060 if (weapons[0].getType() == staff)
5062 if (!skeleton.freefall && freefall && ((jumpkeydown && jumpkeydowntime < .2) || (hasstaff && rabbitkickragdoll)) && !dead) {
5063 if (velocity.y > -30) {
5065 tempvelocity = velocity;
5066 Normalise(&tempvelocity);
5067 targetyaw = -asin(0 - tempvelocity.x);
5068 targetyaw *= 360 / 6.28;
5070 targetyaw = 180 - targetyaw;
5074 if (dotproduct(&skeleton.forward, &tempvelocity) < 0) {
5075 animTarget = rollanim;
5078 animTarget = backhandspringanim;
5084 emit_sound_at(movewhooshsound, coords, 128.);
5086 animCurrent = animTarget;
5087 frameCurrent = frameTarget - 1;
5099 if (skeleton.freefall == 0)
5104 if (aitype != passivetype || skeleton.free == 1)
5105 if (findLengthfast(&velocity) > .1)
5106 for (i = 0; i < objects.numobjects; i++) {
5107 if (objects.type[i] == firetype)
5108 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) {
5110 if (!objects.onfire[i]) {
5111 emit_sound_at(firestartsound, objects.position[i]);
5113 objects.onfire[i] = 1;
5116 if (objects.onfire[i]) {
5121 if (objects.type[i] == bushtype)
5122 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) {
5124 if (!objects.onfire[i]) {
5125 emit_sound_at(firestartsound, objects.position[i]);
5127 objects.onfire[i] = 1;
5131 if (objects.onfire[i]) {
5135 if (objects.messedwith[i] <= 0) {
5139 emit_sound_at(bushrustle, coords, 40 * findLength(&velocity));
5142 envsound[numenvsounds] = coords;
5143 envsoundvol[numenvsounds] = 4 * findLength(&velocity);
5144 envsoundlife[numenvsounds] = .4;
5149 if (environment == grassyenvironment)
5150 howmany = findLength(&velocity) * 4;
5151 if (environment == snowyenvironment)
5152 howmany = findLength(&velocity) * 2;
5154 if (environment != desertenvironment)
5155 for (j = 0; j < howmany; j++) {
5156 tempvel.x = float(abs(Random() % 100) - 50) / 20;
5157 tempvel.y = float(abs(Random() % 100) - 50) / 20;
5158 tempvel.z = float(abs(Random() % 100) - 50) / 20;
5161 pos.x += float(abs(Random() % 100) - 50) / 200;
5162 pos.y += float(abs(Random() % 100) - 50) / 200;
5163 pos.z += float(abs(Random() % 100) - 50) / 200;
5164 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);
5165 Sprite::setLastSpriteSpecial(1);
5167 howmany = findLength(&velocity) * 4;
5169 if (environment == snowyenvironment)
5170 for (j = 0; j < howmany; j++) {
5171 tempvel.x = float(abs(Random() % 100) - 50) / 20;
5172 tempvel.y = float(abs(Random() % 100) - 50) / 20;
5173 tempvel.z = float(abs(Random() % 100) - 50) / 20;
5176 pos.x += float(abs(Random() % 100) - 50) / 200;
5177 pos.y += float(abs(Random() % 100) - 50) / 200;
5178 pos.z += float(abs(Random() % 100) - 50) / 200;
5179 Sprite::MakeSprite(splintersprite, pos, tempvel * .3 + velocity * float(abs(Random() % 100)) / 100 / 2, 1, 1, 1, .1, 1);
5180 Sprite::setLastSpriteSpecial(2);
5183 objects.rotx[i] += velocity.x * multiplier * 6;
5184 objects.roty[i] += velocity.z * multiplier * 6;
5185 objects.messedwith[i] = .5;
5188 if (objects.type[i] == treeleavestype && environment != desertenvironment) {
5189 if (objects.pitch[i] == 0)
5192 tempcoord = coords - objects.position[i];
5193 tempcoord = DoRotation(tempcoord, 0, -objects.yaw[i], 0);
5194 tempcoord = DoRotation(tempcoord, -objects.pitch[i], 0, 0);
5195 tempcoord += objects.position[i];
5197 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]) {
5198 if (objects.messedwith[i] <= 0) {
5202 emit_sound_at(bushrustle, coords, 40 * findLength(&velocity));
5205 envsound[numenvsounds] = coords;
5206 envsoundvol[numenvsounds] = 4 * findLength(&velocity);
5207 envsoundlife[numenvsounds] = .4;
5212 if (environment == grassyenvironment)
5213 howmany = findLength(&velocity) * 4;
5214 if (environment == snowyenvironment)
5215 howmany = findLength(&velocity) * 2;
5217 if (environment != desertenvironment)
5218 for (j = 0; j < howmany; j++) {
5219 tempvel.x = float(abs(Random() % 100) - 50) / 20;
5220 tempvel.y = float(abs(Random() % 100) - 50) / 20;
5221 tempvel.z = float(abs(Random() % 100) - 50) / 20;
5223 pos += velocity * .1;
5225 pos.x += float(abs(Random() % 100) - 50) / 150;
5226 pos.y += float(abs(Random() % 100) - 50) / 150;
5227 pos.z += float(abs(Random() % 100) - 50) / 150;
5228 Sprite::MakeSprite(splintersprite, pos, tempvel * .5 + velocity * float(abs(Random() % 100)) / 100, 165 / 255 + float(abs(Random() % 100) - 50) / 400, 0, 0, .2 + float(abs(Random() % 100) - 50) / 1300, 1);
5229 Sprite::setLastSpriteSpecial(1);
5231 howmany = findLength(&velocity) * 4;
5233 if (environment == snowyenvironment)
5234 for (j = 0; j < howmany; j++) {
5235 tempvel.x = float(abs(Random() % 100) - 50) / 20;
5236 tempvel.y = float(abs(Random() % 100) - 50) / 20;
5237 tempvel.z = float(abs(Random() % 100) - 50) / 20;
5239 pos += velocity * .1;
5241 pos.x += float(abs(Random() % 100) - 50) / 150;
5242 pos.y += float(abs(Random() % 100) - 50) / 150;
5243 pos.z += float(abs(Random() % 100) - 50) / 150;
5244 Sprite::MakeSprite(splintersprite, pos, tempvel * .3 + velocity * float(abs(Random() % 100)) / 100 / 2, 1, 1, 1, .1, 1);
5245 Sprite::setLastSpriteSpecial(2);
5248 objects.messedwith[i] = .5;
5253 if (!skeleton.free) {
5256 if ((stunned > 0 || surprised > 0) && Person::players.size() > 2 && aitype != passivetype)
5259 if (aitype != passivetype && victim->skeleton.free && !victim->dead)
5261 if (tutoriallevel == 1 && id != 0)
5263 if (play && aitype != playercontrolled) {
5264 int whichsound = -1;
5265 i = abs(Random() % 4);
5266 if (speechdelay <= 0) {
5267 if (creature == rabbittype) {
5269 whichsound = rabbitchitter;
5271 whichsound = rabbitchitter2;
5273 if (creature == wolftype) {
5275 whichsound = growlsound;
5277 whichsound = growl2sound;
5282 if (whichsound != -1) {
5283 emit_sound_at(whichsound, coords);
5287 if (animTarget == staggerbackhighanim)
5289 if (animTarget == staggerbackhardanim)
5291 staggerdelay -= multiplier;
5292 if (animTarget != crouchstabanim && animTarget != swordgroundstabanim && animTarget != staffgroundsmashanim)
5294 if (velocity.y < -30 && animTarget == jumpdownanim)
5296 if (animCurrent != getIdle() && wasIdle() && animTarget != getIdle() && isIdle()) {
5297 animTarget = getIdle();
5301 weaponmissdelay -= multiplier;
5302 highreversaldelay -= multiplier;
5303 lowreversaldelay -= multiplier;
5304 lastcollide -= multiplier;
5305 skiddelay -= multiplier;
5306 if (!isnormal(velocity.x) && velocity.x) {
5309 if (!isnormal(targettilt) && targettilt) {
5312 if (!isnormal(targettilt2) && targettilt2) {
5315 if (!isnormal(targetyaw) && targetyaw) {
5319 if (animTarget == bounceidleanim || animTarget == wolfidle || animTarget == walkanim || animTarget == drawrightanim || animTarget == crouchdrawrightanim || animTarget == drawleftanim || animTarget == fightidleanim || animTarget == fightsidestep || animTarget == hanganim || isCrouch() || animTarget == backhandspringanim) {
5320 //open hands and close mouth
5321 if (righthandmorphend != 0 && righthandmorphness == targetrighthandmorphness) {
5322 righthandmorphness = 0;
5323 righthandmorphend = 0;
5324 targetrighthandmorphness = 1;
5327 if (lefthandmorphend != 0 && lefthandmorphness == targetlefthandmorphness) {
5328 lefthandmorphness = 0;
5329 lefthandmorphend = 0;
5330 targetlefthandmorphness = 1;
5333 if (headmorphend != 3 && headmorphend != 5 && headmorphstart != 3 && headmorphstart != 5 && headmorphend != 0 && headmorphness == targetheadmorphness) {
5336 targetheadmorphness = 1;
5340 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) {
5341 //open hands and mouth
5342 if (righthandmorphend != 0 && righthandmorphness == targetrighthandmorphness) {
5343 righthandmorphness = 0;
5344 righthandmorphend = 0;
5345 targetrighthandmorphness = 1;
5348 if (lefthandmorphend != 0 && lefthandmorphness == targetlefthandmorphness) {
5349 lefthandmorphness = 0;
5350 lefthandmorphend = 0;
5351 targetlefthandmorphness = 1;
5354 if (headmorphend != 1 && headmorphness == targetheadmorphness) {
5357 targetheadmorphness = 1;
5361 if (animTarget == jumpupanim || animTarget == crouchstabanim || animTarget == swordgroundstabanim || animTarget == swordfightidlebothanim || animTarget == blockhighleftanim) {
5362 //close hands and mouth
5363 if (righthandmorphend != 1 && righthandmorphness == targetrighthandmorphness) {
5364 righthandmorphness = 0;
5365 righthandmorphend = 1;
5366 targetrighthandmorphness = 1;
5369 if (lefthandmorphend != 1 && lefthandmorphness == targetlefthandmorphness) {
5370 lefthandmorphness = 0;
5371 lefthandmorphend = 1;
5372 targetlefthandmorphness = 1;
5375 if (headmorphend != 0 && headmorphness == targetheadmorphness) {
5378 targetheadmorphness = 1;
5382 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) {
5383 //close hands and yell
5384 if (righthandmorphend != 1 && righthandmorphness == targetrighthandmorphness) {
5385 righthandmorphness = 0;
5386 righthandmorphend = 1;
5387 targetrighthandmorphness = 1;
5390 if (lefthandmorphend != 1 && lefthandmorphness == targetlefthandmorphness) {
5391 lefthandmorphness = 0;
5392 lefthandmorphend = 1;
5393 targetlefthandmorphness = 1;
5396 if (headmorphend != 2 && headmorphness == targetheadmorphness) {
5399 targetheadmorphness = 1;
5406 if ((victim != this->shared_from_this()) && !victim->dead && (victim->aitype != passivetype) &&
5407 (victim->aitype != searchtype) && (aitype != passivetype) &&
5408 (aitype != searchtype) && (victim->id < Person::players.size()) && (aitype != passivetype)) {
5409 behind = (normaldotproduct(facing, coords - victim->coords) > 0);
5413 if (!dead && animTarget != hurtidleanim)
5414 if (behind || animTarget == killanim || animTarget == knifethrowanim || animTarget == knifefollowanim || animTarget == spinkickreversalanim || animTarget == rabbitkickreversedanim || animTarget == jumpreversedanim) {
5415 if (headmorphend != 4 || headmorphness == targetheadmorphness) {
5418 targetheadmorphness = 1;
5422 if (weaponactive != -1) {
5423 if (weapons[weaponids[weaponactive]].getType() != staff) {
5424 righthandmorphstart = 1;
5425 righthandmorphend = 1;
5427 if (weapons[weaponids[weaponactive]].getType() == staff) {
5428 righthandmorphstart = 2;
5429 righthandmorphend = 2;
5431 targetrighthandmorphness = 1;
5434 terrainnormal = terrain.getNormal(coords.x, coords.z);
5436 if (animation[animTarget].attack != reversal) {
5437 if (!isnormal(coords.x))
5445 flatfacing = DoRotation(flatfacing, 0, yaw, 0);
5446 facing = flatfacing;
5447 ReflectVector(&facing, terrainnormal);
5450 if (isRun() || animTarget == sneakanim || animTarget == rollanim || animTarget == walkanim) {
5452 targettilt2 = -facing.y * 20;
5457 if (!isRun() && !animation[animTarget].attack && animTarget != getupfromfrontanim && animTarget != getupfrombackanim && animTarget != sneakanim)
5459 if (animTarget == jumpupanim || animTarget == jumpdownanim || isFlip()) {
5460 flatvelocity = velocity;
5462 flatvelspeed = findLength(&flatvelocity);
5463 targettilt = flatvelspeed * fast_sqrt(abs(velocity.y) * .7) * normaldotproduct(DoRotation(flatfacing, 0, -90, 0), flatvelocity);
5464 targettilt2 = flatvelspeed * fast_sqrt(abs(velocity.y) * .7) * normaldotproduct(flatfacing, flatvelocity);
5469 if (targettilt > 25)
5471 if (targettilt < -25)
5475 if (targettilt2 > 45)
5477 if (targettilt2 < -45)
5479 if (abs(tilt2 - targettilt2) < multiplier * 400)
5480 tilt2 = targettilt2;
5481 else if (tilt2 > targettilt2) {
5482 tilt2 -= multiplier * 400;
5483 } else if (tilt2 < targettilt2) {
5484 tilt2 += multiplier * 400;
5486 if (!animation[animTarget].attack && animTarget != getupfrombackanim && animTarget != getupfromfrontanim) {
5493 if (!isnormal(targettilt) && targettilt) {
5496 if (!isnormal(targettilt2) && targettilt2) {
5501 if (animTarget == rabbittackleanim) {
5502 velocity += facing * multiplier * speed * 700 * scale;
5503 velspeed = findLength(&velocity);
5504 if (velspeed > speed * 65 * scale) {
5505 velocity /= velspeed;
5506 velspeed = speed * 65 * scale;
5507 velocity *= velspeed;
5509 velocity.y += gravity * multiplier * 20;
5510 ReflectVector(&velocity, terrain.getNormal(coords.x, coords.z));
5511 velspeed = findLength(&velocity);
5512 velocity = flatfacing * velspeed;
5514 if (animTarget != rabbitrunninganim && animTarget != wolfrunninganim) {
5515 if (isRun() || animTarget == rabbitkickanim) {
5516 velocity += facing * multiplier * speed * 700 * scale;
5517 velspeed = findLength(&velocity);
5518 if (velspeed > speed * 45 * scale) {
5519 velocity /= velspeed;
5520 velspeed = speed * 45 * scale;
5521 velocity *= velspeed;
5523 velocity.y += gravity * multiplier * 20;
5524 ReflectVector(&velocity, terrain.getNormal(coords.x, coords.z));
5525 velspeed = findLength(&velocity);
5526 if (velspeed < speed * 30 * scale)
5527 velspeed = speed * 30 * scale;
5528 velocity = flatfacing * velspeed;
5530 } else if (isRun()) {
5531 velocity += facing * multiplier * speed * 700 * scale;
5532 velspeed = findLength(&velocity);
5533 if (creature == rabbittype) {
5534 if (velspeed > speed * 55 * scale) {
5535 velocity /= velspeed;
5536 velspeed = speed * 55 * scale;
5537 velocity *= velspeed;
5540 if (creature == wolftype) {
5541 if (velspeed > speed * 75 * scale) {
5542 velocity /= velspeed;
5543 velspeed = speed * 75 * scale;
5544 velocity *= velspeed;
5547 velocity.y += gravity * multiplier * 20;
5548 ReflectVector(&velocity, terrain.getNormal(coords.x, coords.z));
5549 velspeed = findLength(&velocity);
5550 velocity = flatfacing * velspeed;
5553 if (animTarget == rollanim && animation[animTarget].label[frameTarget] != 6) {
5554 velocity += facing * multiplier * speed * 700 * scale;
5555 velspeed = findLength(&velocity);
5556 if (velspeed > speed * 45 * scale) {
5557 velocity /= velspeed;
5558 velspeed = speed * 45 * scale;
5559 velocity *= velspeed;
5561 velocity.y += gravity * multiplier * 20;
5562 ReflectVector(&velocity, terrain.getNormal(coords.x, coords.z));
5563 velspeed = findLength(&velocity);
5564 velocity = flatfacing * velspeed;
5567 if (animTarget == sneakanim || animTarget == walkanim) {
5568 velocity += facing * multiplier * speed * 700 * scale;
5569 velspeed = findLength(&velocity);
5570 if (velspeed > speed * 12 * scale) {
5571 velocity /= velspeed;
5572 velspeed = speed * 12 * scale;
5573 velocity *= velspeed;
5575 velocity.y += gravity * multiplier * 20;
5576 ReflectVector(&velocity, terrain.getNormal(coords.x, coords.z));
5577 velspeed = findLength(&velocity);
5578 velocity = flatfacing * velspeed;
5581 if ((animTarget == fightidleanim || animTarget == knifefightidleanim) && (animCurrent == bounceidleanim || animCurrent == hurtidleanim)) {
5582 velocity += facing * multiplier * speed * 700 * scale;
5583 velspeed = findLength(&velocity);
5584 if (velspeed > speed * 2 * scale) {
5585 velocity /= velspeed;
5586 velspeed = speed * 2 * scale;
5587 velocity *= velspeed;
5589 velocity.y += gravity * multiplier * 20;
5590 ReflectVector(&velocity, terrain.getNormal(coords.x, coords.z));
5591 velspeed = findLength(&velocity);
5592 velocity = flatfacing * velspeed;
5596 if ((animTarget == bounceidleanim || animCurrent == hurtidleanim) && (animCurrent == fightidleanim || animCurrent == knifefightidleanim)) {
5597 velocity -= facing * multiplier * speed * 700 * scale;
5598 velspeed = findLength(&velocity);
5599 if (velspeed > speed * 2 * scale) {
5600 velocity /= velspeed;
5601 velspeed = speed * 2 * scale;
5602 velocity *= velspeed;
5604 velocity.y += gravity * multiplier * 20;
5605 ReflectVector(&velocity, terrain.getNormal(coords.x, coords.z));
5606 velspeed = findLength(&velocity);
5607 velocity = flatfacing * velspeed * -1;
5610 if (animTarget == fightsidestep) {
5611 velocity += DoRotation(facing * multiplier * speed * 700 * scale, 0, -90, 0);
5612 velspeed = findLength(&velocity);
5613 if (velspeed > speed * 12 * scale) {
5614 velocity /= velspeed;
5615 velspeed = speed * 12 * scale;
5616 velocity *= velspeed;
5618 velocity.y += gravity * multiplier * 20;
5619 ReflectVector(&velocity, terrain.getNormal(coords.x, coords.z));
5620 velspeed = findLength(&velocity);
5621 velocity = DoRotation(flatfacing * velspeed, 0, -90, 0);
5624 if (animTarget == staggerbackhighanim) {
5625 coords -= facing * multiplier * speed * 16 * scale;
5628 if (animTarget == staggerbackhardanim && animation[staggerbackhardanim].label[frameTarget] != 6) {
5629 coords -= facing * multiplier * speed * 20 * scale;
5633 if (animTarget == backhandspringanim) {
5634 //coords-=facing*multiplier*50*scale;
5635 velocity += facing * multiplier * speed * 700 * scale * -1;
5636 velspeed = findLength(&velocity);
5637 if (velspeed > speed * 50 * scale) {
5638 velocity /= velspeed;
5639 velspeed = speed * 50 * scale;
5640 velocity *= velspeed;
5642 velocity.y += gravity * multiplier * 20;
5643 ReflectVector(&velocity, terrain.getNormal(coords.x, coords.z));
5644 velspeed = findLength(&velocity);
5645 velocity = flatfacing * velspeed * -1;
5647 if (animTarget == dodgebackanim) {
5648 //coords-=facing*multiplier*50*scale;
5649 velocity += facing * multiplier * speed * 700 * scale * -1;
5650 velspeed = findLength(&velocity);
5651 if (velspeed > speed * 60 * scale) {
5652 velocity /= velspeed;
5653 velspeed = speed * 60 * scale;
5654 velocity *= velspeed;
5656 velocity.y += gravity * multiplier * 20;
5657 ReflectVector(&velocity, terrain.getNormal(coords.x, coords.z));
5658 velspeed = findLength(&velocity);
5659 velocity = flatfacing * velspeed * -1;
5662 if (animTarget == jumpupanim || animTarget == jumpdownanim || isFlip()) {
5663 velspeed = findLength(&velocity);
5667 if (animTarget == jumpupanim || animTarget == jumpdownanim || isFlip()) {
5668 velocity.y += gravity * multiplier;
5671 if (animTarget != climbanim && animTarget != hanganim && !isWallJump())
5672 coords += velocity * multiplier;
5674 if (coords.y < terrain.getHeight(coords.x, coords.z) && (animTarget == jumpdownanim || animTarget == jumpupanim || isFlip())) {
5675 if (isFlip() && animation[animTarget].label[frameTarget] == 7)
5678 if (animTarget == jumpupanim) {
5680 animTarget = getIdle();
5687 pause_sound(whooshsound);
5688 OPENAL_SetVolume(channels[whooshsound], 0);
5691 if (animTarget == jumpdownanim || isFlip()) {
5692 if (isFlip())jumppower = -4;
5693 animTarget = getLanding();
5694 emit_sound_at(landsound, coords, 128.);
5697 envsound[numenvsounds] = coords;
5698 envsoundvol[numenvsounds] = 16;
5699 envsoundlife[numenvsounds] = .4;
5705 if (animTarget != jumpupanim && animTarget != jumpdownanim && !isFlip() && animTarget != climbanim && animTarget != hanganim && !isWallJump())
5706 coords.y += gravity * multiplier * 2;
5707 if (animTarget != jumpupanim && animTarget != jumpdownanim && !isFlip() && coords.y < terrain.getHeight(coords.x, coords.z)) {
5708 coords.y = terrain.getHeight(coords.x, coords.z);
5713 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)) {
5714 velspeed = findLength(&velocity);
5716 if (velspeed < multiplier * 300 * scale) {
5719 velocity -= velocity / velspeed * multiplier * 300 * scale;
5720 if (velspeed > 5 && (isLanding() || isLandhard())) {
5721 skiddingdelay += multiplier;
5722 if (skiddelay <= 0) {
5732 velspeed = findLength(&velocity);
5734 if (velspeed < multiplier * 600 * scale) {
5737 velocity -= velocity / velspeed * multiplier * 600 * scale;
5739 if (velspeed > 5 && (isLanding() || isLandhard())) {
5740 skiddingdelay += multiplier;
5741 if (skiddelay <= 0) {
5750 if (skiddingdelay < 0)
5751 skiddingdelay += multiplier;
5752 if (skiddingdelay > .02 && !forwardkeydown && !backkeydown && !leftkeydown && !rightkeydown && !jumpkeydown && isLanding() && !landhard) {
5754 if (!onterrain || environment == grassyenvironment) {
5755 emit_sound_at(skidsound, coords, 128 * velspeed / 10);
5757 emit_sound_at(snowskidsound, coords, 128 * velspeed / 10);
5761 if (animation[animTarget].attack == normalattack && animTarget != rabbitkickanim && !victim->skeleton.free) {
5762 terrainnormal = victim->coords - coords;
5763 Normalise(&terrainnormal);
5764 targetyaw = -asin(0 - terrainnormal.x);
5765 targetyaw *= 360 / 6.28;
5766 if (terrainnormal.z < 0)
5767 targetyaw = 180 - targetyaw;
5768 targettilt2 = -asin(terrainnormal.y) * 360 / 6.28; //*-70;
5771 if (animation[animTarget].attack == reversal && animTarget != rabbittacklinganim) {
5772 targetyaw = victim->targetyaw;
5774 if (animTarget == rabbittacklinganim) {
5775 coords = victim->coords;
5778 skeleton.oldfree = skeleton.free;
5782 midterrain.x = terrain.size * terrain.scale / 2;
5783 midterrain.z = terrain.size * terrain.scale / 2;
5784 if (distsqflat(&coords, &midterrain) > (terrain.size * terrain.scale / 2 - viewdistance) * (terrain.size * terrain.scale / 2 - viewdistance)) {
5786 tempposit = coords - midterrain;
5788 Normalise(&tempposit);
5789 tempposit *= (terrain.size * terrain.scale / 2 - viewdistance);
5790 coords.x = tempposit.x + midterrain.x;
5791 coords.z = tempposit.z + midterrain.z;
5797 * inverse kinematics helper function
5799 void IKHelper(Person *p, float interp)
5801 XYZ point, newpoint, change, change2;
5802 float heightleft, heightright;
5804 // TODO: implement localToWorld and worldToLocal
5805 // but keep in mind it won't be the same math if player is ragdolled or something
5806 // - localToWorldStanding / worldToLocalStanding (or crouching or...?)
5807 // then comb through code for places where to use it
5809 // point = localToWorld(jointPos(leftfoot))
5810 point = DoRotation(p->jointPos(leftfoot), 0, p->yaw, 0) * p->scale + p->coords;
5811 // adjust height of foot
5812 heightleft = terrain.getHeight(point.x, point.z) + .04;
5813 point.y = heightleft;
5814 change = p->jointPos(leftankle) - p->jointPos(leftfoot);
5815 change2 = p->jointPos(leftknee) - p->jointPos(leftfoot);
5816 // jointPos(leftfoot) = interpolate(worldToLocal(point), jointPos(leftfoot), interp)
5817 p->jointPos(leftfoot) = DoRotation((point - p->coords) / p->scale, 0, -p->yaw, 0) * interp + p->jointPos(leftfoot) * (1 - interp);
5818 // move ankle along with foot
5819 p->jointPos(leftankle) = p->jointPos(leftfoot) + change;
5820 // average knee pos between old and new pos
5821 p->jointPos(leftknee) = (p->jointPos(leftfoot) + change2) / 2 + (p->jointPos(leftknee)) / 2;
5823 // do same as above for right leg
5824 point = DoRotation(p->jointPos(rightfoot), 0, p->yaw, 0) * p->scale + p->coords;
5825 heightright = terrain.getHeight(point.x, point.z) + .04;
5826 point.y = heightright;
5827 change = p->jointPos(rightankle) - p->jointPos(rightfoot);
5828 change2 = p->jointPos(rightknee) - p->jointPos(rightfoot);
5829 p->jointPos(rightfoot) = DoRotation((point - p->coords) / p->scale, 0, -p->yaw, 0) * interp + p->jointPos(rightfoot) * (1 - interp);
5830 p->jointPos(rightankle) = p->jointPos(rightfoot) + change;
5831 p->jointPos(rightknee) = (p->jointPos(rightfoot) + change2) / 2 + (p->jointPos(rightknee)) / 2;
5833 // fix up skeleton now that we've moved body parts?
5834 p->skeleton.DoConstraints(&p->coords, &p->scale);
5841 int Person::DrawSkeleton()
5843 int oldplayerdetail;
5844 if ((frustum.SphereInFrustum(coords.x, coords.y + scale * 3, coords.z, scale * 8) && distsq(&viewer, &coords) < viewdistance * viewdistance) || skeleton.free == 3) {
5845 if (onterrain && (isIdle() || isCrouch() || wasIdle() || wasCrouch()) && !skeleton.free) {
5855 glAlphaFunc(GL_GREATER, 0.0001);
5857 float terrainheight;
5861 if (!isnormal(tilt))
5863 if (!isnormal(tilt2))
5865 oldplayerdetail = playerdetail;
5867 if (distsq(&viewer, &coords) < viewdistance * viewdistance / 32 && detail == 2) {
5870 if (distsq(&viewer, &coords) < viewdistance * viewdistance / 128 && detail == 1) {
5873 if (distsq(&viewer, &coords) < viewdistance * viewdistance / 256 && (detail != 1 && detail != 2)) {
5878 if (playerdetail != oldplayerdetail) {
5880 normalsupdatedelay = 0;
5882 static float updatedelaychange;
5883 static float morphness;
5884 static float framemult;
5886 skeleton.FindForwards();
5887 if (howactive == typesittingwall) {
5888 skeleton.specialforward[1] = 0;
5889 skeleton.specialforward[1].z = 1;
5895 static int weaponattachmuscle;
5896 static int weaponrotatemuscle;
5897 static XYZ weaponpoint;
5898 static int start, endthing;
5899 if ((dead != 2 || skeleton.free != 2) && updatedelay <= 0) {
5900 if (!isSleeping() && !isSitting()) {
5901 // TODO: give these meaningful names
5902 const bool cond1 = (isIdle() || isCrouch() || isLanding() || isLandhard()
5903 || animTarget == drawrightanim || animTarget == drawleftanim || animTarget == crouchdrawrightanim);
5904 const bool cond2 = (wasIdle() || wasCrouch() || wasLanding() || wasLandhard()
5905 || animCurrent == drawrightanim || animCurrent == drawleftanim || animCurrent == crouchdrawrightanim);
5907 if (onterrain && (cond1 && cond2) && !skeleton.free) {
5909 if (creature == wolftype)
5913 if (onterrain && (cond1 && !cond2) && !skeleton.free) {
5914 IKHelper(this, target);
5915 if (creature == wolftype)
5916 IKHelper(this, target);
5919 if (onterrain && (!cond1 && cond2) && !skeleton.free) {
5920 IKHelper(this, 1 - target);
5921 if (creature == wolftype)
5922 IKHelper(this, 1 - target);
5926 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()))
5929 targetheadyaw = -targetyaw;
5930 targetheadpitch = 0;
5931 if (animation[animTarget].attack == 3)
5932 targetheadyaw += 180;
5934 for (i = 0; i < skeleton.drawmodel.vertexNum; i++) {
5935 skeleton.drawmodel.vertex[i] = 0;
5936 skeleton.drawmodel.vertex[i].y = 999;
5938 for (i = 0; i < skeleton.drawmodellow.vertexNum; i++) {
5939 skeleton.drawmodellow.vertex[i] = 0;
5940 skeleton.drawmodellow.vertex[i].y = 999;
5942 for (i = 0; i < skeleton.drawmodelclothes.vertexNum; i++) {
5943 skeleton.drawmodelclothes.vertex[i] = 0;
5944 skeleton.drawmodelclothes.vertex[i].y = 999;
5946 for (int i = 0; i < skeleton.num_muscles; i++) {
5947 // convenience renames
5948 const int p1 = skeleton.muscles[i].parent1->label;
5949 const int p2 = skeleton.muscles[i].parent2->label;
5951 if ((skeleton.muscles[i].numvertices > 0 && playerdetail) || (skeleton.muscles[i].numverticeslow > 0 && !playerdetail)) {
5956 if (p1 == righthand || p2 == righthand) {
5957 morphness = righthandmorphness;
5958 start = righthandmorphstart;
5959 endthing = righthandmorphend;
5961 if (p1 == lefthand || p2 == lefthand) {
5962 morphness = lefthandmorphness;
5963 start = lefthandmorphstart;
5964 endthing = lefthandmorphend;
5966 if (p1 == head || p2 == head) {
5967 morphness = headmorphness;
5968 start = headmorphstart;
5969 endthing = headmorphend;
5971 if ((p1 == neck && p2 == abdomen) || (p2 == neck && p1 == abdomen)) {
5972 morphness = chestmorphness;
5973 start = chestmorphstart;
5974 endthing = chestmorphend;
5976 if ((p1 == groin && p2 == abdomen) || (p2 == groin && p1 == abdomen)) {
5977 morphness = tailmorphness;
5978 start = tailmorphstart;
5979 endthing = tailmorphend;
5982 skeleton.FindRotationMuscle(i, animTarget);
5983 mid = (skeleton.muscles[i].parent1->position + skeleton.muscles[i].parent2->position) / 2;
5984 glMatrixMode(GL_MODELVIEW);
5988 glRotatef(tilt2, 1, 0, 0);
5990 glRotatef(tilt, 0, 0, 1);
5993 glTranslatef(mid.x, mid.y, mid.z);
5995 skeleton.muscles[i].lastrotate1 = skeleton.muscles[i].rotate1;
5996 glRotatef(-skeleton.muscles[i].lastrotate1 + 90, 0, 1, 0);
5998 skeleton.muscles[i].lastrotate2 = skeleton.muscles[i].rotate2;
5999 glRotatef(-skeleton.muscles[i].lastrotate2 + 90, 0, 0, 1);
6001 skeleton.muscles[i].lastrotate3 = skeleton.muscles[i].rotate3;
6002 glRotatef(-skeleton.muscles[i].lastrotate3, 0, 1, 0);
6004 if (playerdetail || skeleton.free == 3) {
6005 for (j = 0; j < skeleton.muscles[i].numvertices; j++) {
6006 XYZ &v0 = skeleton.model[start].vertex[skeleton.muscles[i].vertices[j]];
6007 XYZ &v1 = skeleton.model[endthing].vertex[skeleton.muscles[i].vertices[j]];
6008 glMatrixMode(GL_MODELVIEW);
6010 if (p1 == abdomen || p2 == abdomen)
6011 glTranslatef((v0.x * (1 - morphness) + v1.x * morphness) * proportionbody.x,
6012 (v0.y * (1 - morphness) + v1.y * morphness) * proportionbody.y,
6013 (v0.z * (1 - morphness) + v1.z * morphness) * proportionbody.z);
6014 if (p1 == lefthand || p1 == righthand || p1 == leftwrist || p1 == rightwrist || p1 == leftelbow || p1 == rightelbow || p2 == leftelbow || p2 == rightelbow)
6015 glTranslatef((v0.x * (1 - morphness) + v1.x * morphness) * proportionarms.x,
6016 (v0.y * (1 - morphness) + v1.y * morphness) * proportionarms.y,
6017 (v0.z * (1 - morphness) + v1.z * morphness) * proportionarms.z);
6018 if (p1 == leftfoot || p1 == rightfoot || p1 == leftankle || p1 == rightankle || p1 == leftknee || p1 == rightknee || p2 == leftknee || p2 == rightknee)
6019 glTranslatef((v0.x * (1 - morphness) + v1.x * morphness) * proportionlegs.x,
6020 (v0.y * (1 - morphness) + v1.y * morphness) * proportionlegs.y,
6021 (v0.z * (1 - morphness) + v1.z * morphness) * proportionlegs.z);
6022 if (p1 == head || p2 == head)
6023 glTranslatef((v0.x * (1 - morphness) + v1.x * morphness) * proportionhead.x,
6024 (v0.y * (1 - morphness) + v1.y * morphness) * proportionhead.y,
6025 (v0.z * (1 - morphness) + v1.z * morphness) * proportionhead.z);
6026 glGetFloatv(GL_MODELVIEW_MATRIX, M);
6027 skeleton.drawmodel.vertex[skeleton.muscles[i].vertices[j]].x = M[12] * scale;
6028 skeleton.drawmodel.vertex[skeleton.muscles[i].vertices[j]].y = M[13] * scale;
6029 skeleton.drawmodel.vertex[skeleton.muscles[i].vertices[j]].z = M[14] * scale;
6033 if (!playerdetail || skeleton.free == 3) {
6034 for (j = 0; j < skeleton.muscles[i].numverticeslow; j++) {
6035 XYZ &v0 = skeleton.modellow.vertex[skeleton.muscles[i].verticeslow[j]];
6036 glMatrixMode(GL_MODELVIEW);
6038 if (p1 == abdomen || p2 == abdomen)
6039 glTranslatef(v0.x * proportionbody.x,
6040 v0.y * proportionbody.y,
6041 v0.z * proportionbody.z);
6042 if (p1 == lefthand || p1 == righthand || p1 == leftwrist || p1 == rightwrist || p1 == leftelbow || p1 == rightelbow || p2 == leftelbow || p2 == rightelbow)
6043 glTranslatef(v0.x * proportionarms.x,
6044 v0.y * proportionarms.y,
6045 v0.z * proportionarms.z);
6046 if (p1 == leftfoot || p1 == rightfoot || p1 == leftankle || p1 == rightankle || p1 == leftknee || p1 == rightknee || p2 == leftknee || p2 == rightknee)
6047 glTranslatef(v0.x * proportionlegs.x,
6048 v0.y * proportionlegs.y,
6049 v0.z * proportionlegs.z);
6050 if (p1 == head || p2 == head)
6051 glTranslatef(v0.x * proportionhead.x,
6052 v0.y * proportionhead.y,
6053 v0.z * proportionhead.z);
6055 glGetFloatv(GL_MODELVIEW_MATRIX, M);
6056 skeleton.drawmodellow.vertex[skeleton.muscles[i].verticeslow[j]].x = M[12] * scale;
6057 skeleton.drawmodellow.vertex[skeleton.muscles[i].verticeslow[j]].y = M[13] * scale;
6058 skeleton.drawmodellow.vertex[skeleton.muscles[i].verticeslow[j]].z = M[14] * scale;
6064 if (skeleton.clothes && skeleton.muscles[i].numverticesclothes > 0) {
6065 mid = (skeleton.muscles[i].parent1->position + skeleton.muscles[i].parent2->position) / 2;
6067 glMatrixMode(GL_MODELVIEW);
6071 glRotatef(tilt2, 1, 0, 0);
6073 glRotatef(tilt, 0, 0, 1);
6074 glTranslatef(mid.x, mid.y, mid.z);
6075 skeleton.muscles[i].lastrotate1 = skeleton.muscles[i].rotate1;
6076 glRotatef(-skeleton.muscles[i].lastrotate1 + 90, 0, 1, 0);
6078 skeleton.muscles[i].lastrotate2 = skeleton.muscles[i].rotate2;
6079 glRotatef(-skeleton.muscles[i].lastrotate2 + 90, 0, 0, 1);
6081 skeleton.muscles[i].lastrotate3 = skeleton.muscles[i].rotate3;
6082 glRotatef(-skeleton.muscles[i].lastrotate3, 0, 1, 0);
6084 for (j = 0; j < skeleton.muscles[i].numverticesclothes; j++) {
6085 XYZ &v0 = skeleton.modelclothes.vertex[skeleton.muscles[i].verticesclothes[j]];
6086 glMatrixMode(GL_MODELVIEW);
6088 if (p1 == abdomen || p2 == abdomen)
6089 glTranslatef(v0.x * proportionbody.x,
6090 v0.y * proportionbody.y,
6091 v0.z * proportionbody.z);
6092 if (p1 == lefthand || p1 == righthand || p1 == leftwrist || p1 == rightwrist || p1 == leftelbow || p1 == rightelbow || p2 == leftelbow || p2 == rightelbow)
6093 glTranslatef(v0.x * proportionarms.x,
6094 v0.y * proportionarms.y,
6095 v0.z * proportionarms.z);
6096 if (p1 == leftfoot || p1 == rightfoot || p1 == leftankle || p1 == rightankle || p1 == leftknee || p1 == rightknee || p2 == leftknee || p2 == rightknee)
6097 glTranslatef(v0.x * proportionlegs.x,
6098 v0.y * proportionlegs.y,
6099 v0.z * proportionlegs.z);
6100 if (p1 == head || p2 == head)
6101 glTranslatef(v0.x * proportionhead.x,
6102 v0.y * proportionhead.y,
6103 v0.z * proportionhead.z);
6104 glGetFloatv(GL_MODELVIEW_MATRIX, M);
6105 skeleton.drawmodelclothes.vertex[skeleton.muscles[i].verticesclothes[j]].x = M[12] * scale;
6106 skeleton.drawmodelclothes.vertex[skeleton.muscles[i].verticesclothes[j]].y = M[13] * scale;
6107 skeleton.drawmodelclothes.vertex[skeleton.muscles[i].verticesclothes[j]].z = M[14] * scale;
6112 updatedelay = 1 + (float)(Random() % 100) / 1000;
6114 if (skeleton.free != 2 && (skeleton.free == 1 || skeleton.free == 3 || id == 0 || (normalsupdatedelay <= 0) || animTarget == getupfromfrontanim || animTarget == getupfrombackanim || animCurrent == getupfromfrontanim || animCurrent == getupfrombackanim)) {
6115 normalsupdatedelay = 1;
6116 if (playerdetail || skeleton.free == 3)
6117 skeleton.drawmodel.CalculateNormals(0);
6118 if (!playerdetail || skeleton.free == 3)
6119 skeleton.drawmodellow.CalculateNormals(0);
6120 if (skeleton.clothes)
6121 skeleton.drawmodelclothes.CalculateNormals(0);
6123 if (playerdetail || skeleton.free == 3)
6124 skeleton.drawmodel.UpdateVertexArrayNoTexNoNorm();
6125 if (!playerdetail || skeleton.free == 3)
6126 skeleton.drawmodellow.UpdateVertexArrayNoTexNoNorm();
6127 if (skeleton.clothes) {
6128 skeleton.drawmodelclothes.UpdateVertexArrayNoTexNoNorm();
6133 updatedelaychange = -framemult * 4 * (45 - findDistance(&viewer, &coords) * 1);
6134 if (updatedelaychange > -realmultiplier * 30)
6135 updatedelaychange = -realmultiplier * 30;
6136 if (updatedelaychange > -framemult * 4)
6137 updatedelaychange = -framemult * 4;
6138 if (skeleton.free == 1)
6139 updatedelaychange *= 6;
6141 updatedelaychange *= 8;
6142 updatedelay += updatedelaychange;
6144 glMatrixMode(GL_MODELVIEW);
6147 glTranslatef(coords.x, coords.y - .02, coords.z);
6149 glTranslatef(coords.x, coords.y - .02, coords.z);
6151 glTranslatef(offset.x * scale, offset.y * scale, offset.z * scale);
6153 glRotatef(yaw, 0, 1, 0);
6156 glColor4f(.4, 1, .4, 1);
6157 glDisable(GL_LIGHTING);
6158 glDisable(GL_TEXTURE_2D);
6161 for (i = 0; i < skeleton.drawmodel.vertexNum; i++) {
6162 XYZ &v0 = skeleton.drawmodel.vertex[i];
6163 glVertex3f(v0.x, v0.y, v0.z);
6169 for (i = 0; i < skeleton.drawmodel.TriangleNum; i++) {
6170 XYZ &v0 = skeleton.drawmodel.vertex[skeleton.drawmodel.Triangles[i].vertex[0]];
6171 XYZ &v1 = skeleton.drawmodel.vertex[skeleton.drawmodel.Triangles[i].vertex[1]];
6172 XYZ &v2 = skeleton.drawmodel.vertex[skeleton.drawmodel.Triangles[i].vertex[2]];
6173 glVertex3f(v0.x, v0.y, v0.z);
6174 glVertex3f(v1.x, v1.y, v1.z);
6175 glVertex3f(v1.x, v1.y, v1.z);
6176 glVertex3f(v2.x, v2.y, v2.z);
6177 glVertex3f(v2.x, v2.y, v2.z);
6178 glVertex3f(v0.x, v0.y, v0.z);
6184 terrainlight = terrain.getLighting(coords.x, coords.z);
6185 distance = distsq(&viewer, &coords);
6186 distance = (viewdistance * viewdistance - (distance - (viewdistance * viewdistance * fadestart)) * (1 / (1 - fadestart))) / viewdistance / viewdistance;
6190 terrainheight = (coords.y - terrain.getHeight(coords.x, coords.z)) / 3 + 1;
6191 if (terrainheight < 1)
6193 if (terrainheight > 1.7)
6194 terrainheight = 1.7;
6197 glColor4f((1 - (1 - terrainlight.x) / terrainheight) - burnt, (1 - (1 - terrainlight.y) / terrainheight) - burnt, (1 - (1 - terrainlight.z) / terrainheight) - burnt, distance);
6198 glDisable(GL_BLEND);
6199 glAlphaFunc(GL_GREATER, 0.0001);
6200 glEnable(GL_TEXTURE_2D);
6202 glDisable(GL_TEXTURE_2D);
6203 glColor4f(.7, .35, 0, .5);
6205 glEnable(GL_LIGHTING);
6208 if (tutoriallevel && id != 0) {
6209 glColor4f(.7, .7, .7, 0.6);
6211 glEnable(GL_LIGHTING);
6213 if (canattack && cananger)
6214 if (animation[animTarget].attack == normalattack || animation[animTarget].attack == reversed) {
6215 glDisable(GL_TEXTURE_2D);
6216 glColor4f(1, 0, 0, 0.8);
6218 glMatrixMode(GL_TEXTURE);
6220 glTranslatef(0, -smoketex, 0);
6221 glTranslatef(-smoketex, 0, 0);
6225 if ((tutoriallevel && id != 0))
6226 skeleton.drawmodel.drawdifftex(Sprite::cloudimpacttexture);
6228 skeleton.drawmodel.draw();
6231 if (!playerdetail) {
6232 if ((tutoriallevel && id != 0))
6233 skeleton.drawmodellow.drawdifftex(Sprite::cloudimpacttexture);
6235 skeleton.drawmodellow.drawdifftex(skeleton.drawmodel.textureptr);
6238 if (!(animation[animTarget].attack == normalattack || animation[animTarget].attack == reversed))
6239 if (tutoriallevel && id != 0) {
6241 glMatrixMode(GL_MODELVIEW);
6242 glEnable(GL_TEXTURE_2D);
6243 glColor4f(.7, .7, .7, 0.6);
6245 glEnable(GL_LIGHTING);
6247 if (canattack && cananger)
6248 if (animation[animTarget].attack == normalattack || animation[animTarget].attack == reversed) {
6249 glDisable(GL_TEXTURE_2D);
6250 glColor4f(1, 0, 0, 0.8);
6252 glMatrixMode(GL_TEXTURE);
6254 glTranslatef(0, -smoketex * .6, 0);
6255 glTranslatef(smoketex * .6, 0, 0);
6258 if ((tutoriallevel && id != 0))
6259 skeleton.drawmodel.drawdifftex(Sprite::cloudimpacttexture);
6261 skeleton.drawmodel.draw();
6264 if (!playerdetail) {
6265 if ((tutoriallevel && id != 0))
6266 skeleton.drawmodellow.drawdifftex(Sprite::cloudimpacttexture);
6268 skeleton.drawmodellow.drawdifftex(skeleton.drawmodel.textureptr);
6273 if (tutoriallevel && id != 0) {
6275 glMatrixMode(GL_MODELVIEW);
6276 glEnable(GL_TEXTURE_2D);
6278 if (skeleton.clothes) {
6282 skeleton.drawmodelclothes.draw();
6284 skeleton.drawmodelclothes.drawimmediate();
6290 if (num_weapons > 0) {
6291 for (k = 0; k < num_weapons; k++) {
6293 if (weaponactive == k) {
6294 if (weapons[i].getType() != staff) {
6295 for (j = 0; j < skeleton.num_muscles; j++) {
6296 if ((skeleton.muscles[j].parent1->label == righthand || skeleton.muscles[j].parent2->label == righthand) && skeleton.muscles[j].numvertices > 0) {
6297 weaponattachmuscle = j;
6300 for (j = 0; j < skeleton.num_muscles; j++) {
6301 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) {
6302 weaponrotatemuscle = j;
6305 weaponpoint = (skeleton.muscles[weaponattachmuscle].parent1->position + skeleton.muscles[weaponattachmuscle].parent2->position) / 2;
6306 if (creature == wolftype)
6307 weaponpoint = (jointPos(rightwrist) * .7 + jointPos(righthand) * .3);
6309 if (weapons[i].getType() == staff) {
6310 for (j = 0; j < skeleton.num_muscles; j++) {
6311 if ((skeleton.muscles[j].parent1->label == righthand || skeleton.muscles[j].parent2->label == righthand) && skeleton.muscles[j].numvertices > 0) {
6312 weaponattachmuscle = j;
6315 for (j = 0; j < skeleton.num_muscles; j++) {
6316 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) {
6317 weaponrotatemuscle = j;
6320 //weaponpoint=jointPos(rightwrist);
6321 weaponpoint = (skeleton.muscles[weaponattachmuscle].parent1->position + skeleton.muscles[weaponattachmuscle].parent2->position) / 2;
6322 //weaponpoint+=skeleton.specialforward[1]*.1+(jointPos(rightwrist)-jointPos(rightelbow));
6323 XYZ tempnormthing, vec1, vec2;
6324 vec1 = (jointPos(rightwrist) - jointPos(rightelbow));
6325 vec2 = (jointPos(rightwrist) - jointPos(rightshoulder));
6326 CrossProduct(&vec1, &vec2, &tempnormthing);
6327 Normalise(&tempnormthing);
6328 if (animTarget != staffhitanim && animCurrent != staffhitanim && animTarget != staffgroundsmashanim && animCurrent != staffgroundsmashanim && animTarget != staffspinhitanim && animCurrent != staffspinhitanim)
6329 weaponpoint += tempnormthing * .1 - skeleton.specialforward[1] * .3 + (jointPos(rightwrist) - jointPos(rightelbow));
6332 if (weaponactive != k && weaponstuck != k) {
6333 if (weapons[i].getType() == knife)
6334 weaponpoint = jointPos(abdomen) + (jointPos(righthip) - jointPos(lefthip)) * .1 + (jointPos(rightshoulder) - jointPos(leftshoulder)) * .35;
6335 if (weapons[i].getType() == sword)
6336 weaponpoint = jointPos(abdomen) + (jointPos(lefthip) - jointPos(righthip)) * .09 + (jointPos(leftshoulder) - jointPos(rightshoulder)) * .33;
6337 if (weapons[i].getType() == staff)
6338 weaponpoint = jointPos(abdomen) + (jointPos(lefthip) - jointPos(righthip)) * .09 + (jointPos(leftshoulder) - jointPos(rightshoulder)) * .33;
6339 for (j = 0; j < skeleton.num_muscles; j++) {
6340 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) {
6341 weaponrotatemuscle = j;
6345 if (weaponstuck == k) {
6346 if (weaponstuckwhere == 0)
6347 weaponpoint = jointPos(abdomen) * .5 + jointPos(neck) * .5 - skeleton.forward * .8;
6349 weaponpoint = jointPos(abdomen) * .5 + jointPos(neck) * .5 + skeleton.forward * .8;
6350 for (j = 0; j < skeleton.num_muscles; j++) {
6351 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) {
6352 weaponrotatemuscle = j;
6356 if (skeleton.free) {
6357 weapons[i].position = weaponpoint * scale + coords;
6358 weapons[i].bigrotation = 0;
6359 weapons[i].bigtilt = 0;
6360 weapons[i].bigtilt2 = 0;
6362 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;
6363 weapons[i].bigrotation = yaw;
6364 weapons[i].bigtilt = tilt;
6365 weapons[i].bigtilt2 = tilt2;
6367 weapons[i].rotation1 = skeleton.muscles[weaponrotatemuscle].lastrotate1;
6368 weapons[i].rotation2 = skeleton.muscles[weaponrotatemuscle].lastrotate2;
6369 weapons[i].rotation3 = skeleton.muscles[weaponrotatemuscle].lastrotate3;
6370 if (weaponactive == k) {
6371 if (weapons[i].getType() == knife) {
6372 weapons[i].smallrotation = 180;
6373 weapons[i].smallrotation2 = 0;
6374 if (isCrouch() || wasCrouch()) {
6375 weapons[i].smallrotation2 = 20;
6377 if (animTarget == hurtidleanim) {
6378 weapons[i].smallrotation2 = 50;
6380 if ((animCurrent == crouchstabanim && animTarget == crouchstabanim) || (animCurrent == backhandspringanim && animTarget == backhandspringanim)) {
6381 XYZ temppoint1, temppoint2, tempforward;
6384 temppoint1 = jointPos(righthand);
6385 temppoint2 = animation[animCurrent].weapontarget[frameCurrent] * (1 - target) + animation[animTarget].weapontarget[frameTarget] * (target);
6386 distance = findDistance(&temppoint1, &temppoint2);
6387 weapons[i].rotation2 = asin((temppoint1.y - temppoint2.y) / distance);
6388 weapons[i].rotation2 *= 360 / 6.28;
6391 weapons[i].rotation1 = acos((temppoint1.z - temppoint2.z) / findDistance(&temppoint1, &temppoint2));
6392 weapons[i].rotation1 *= 360 / 6.28;
6393 weapons[i].rotation3 = 0;
6394 weapons[i].smallrotation = -90;
6395 weapons[i].smallrotation2 = 0;
6396 if (temppoint1.x > temppoint2.x)
6397 weapons[i].rotation1 = 360 - weapons[i].rotation1;
6399 if ((animCurrent == knifeslashreversalanim && animTarget == knifeslashreversalanim) || (animCurrent == knifeslashreversedanim && animTarget == knifeslashreversedanim)) {
6400 XYZ temppoint1, temppoint2, tempforward;
6403 temppoint1 = jointPos(righthand);
6404 temppoint2 = animation[animCurrent].weapontarget[frameCurrent] * (1 - target) + animation[animTarget].weapontarget[frameTarget] * (target);
6405 distance = findDistance(&temppoint1, &temppoint2);
6406 weapons[i].rotation2 = asin((temppoint1.y - temppoint2.y) / distance);
6407 weapons[i].rotation2 *= 360 / 6.28;
6410 weapons[i].rotation1 = acos((temppoint1.z - temppoint2.z) / findDistance(&temppoint1, &temppoint2));
6411 weapons[i].rotation1 *= 360 / 6.28;
6412 weapons[i].rotation3 = 0;
6413 weapons[i].smallrotation = 90;
6414 weapons[i].smallrotation2 = 0;
6415 if (temppoint1.x > temppoint2.x)
6416 weapons[i].rotation1 = 360 - weapons[i].rotation1;
6418 if (animTarget == knifethrowanim) {
6419 weapons[i].smallrotation = 90;
6420 //weapons[i].smallrotation2=-90;
6421 weapons[i].smallrotation2 = 0;
6422 weapons[i].rotation1 = 0;
6423 weapons[i].rotation2 = 0;
6424 weapons[i].rotation3 = 0;
6426 if (animTarget == knifesneakattackanim && frameTarget < 5) {
6427 weapons[i].smallrotation = -90;
6428 weapons[i].rotation1 = 0;
6429 weapons[i].rotation2 = 0;
6430 weapons[i].rotation3 = 0;
6433 if (weapons[i].getType() == sword) {
6434 weapons[i].smallrotation = 0;
6435 weapons[i].smallrotation2 = 0;
6436 if (animTarget == knifethrowanim) {
6437 weapons[i].smallrotation = -90;
6438 weapons[i].smallrotation2 = 0;
6439 weapons[i].rotation1 = 0;
6440 weapons[i].rotation2 = 0;
6441 weapons[i].rotation3 = 0;
6443 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)) {
6444 XYZ temppoint1, temppoint2, tempforward;
6447 temppoint1 = animation[animCurrent].position[skeleton.jointlabels[righthand]][frameCurrent] * (1 - target) + animation[animTarget].position[skeleton.jointlabels[righthand]][frameTarget] * (target); //jointPos(righthand);
6448 temppoint2 = animation[animCurrent].weapontarget[frameCurrent] * (1 - target) + animation[animTarget].weapontarget[frameTarget] * (target);
6449 distance = findDistance(&temppoint1, &temppoint2);
6450 weapons[i].rotation2 = asin((temppoint1.y - temppoint2.y) / distance);
6451 weapons[i].rotation2 *= 360 / 6.28;
6454 weapons[i].rotation1 = acos((temppoint1.z - temppoint2.z) / findDistance(&temppoint1, &temppoint2));
6455 weapons[i].rotation1 *= 360 / 6.28;
6456 weapons[i].rotation3 = 0;
6457 weapons[i].smallrotation = 90;
6458 weapons[i].smallrotation2 = 0;
6459 if (temppoint1.x > temppoint2.x)
6460 weapons[i].rotation1 = 360 - weapons[i].rotation1;
6463 if (weapons[i].getType() == staff) {
6464 weapons[i].smallrotation = 100;
6465 weapons[i].smallrotation2 = 0;
6466 if ((animTarget == staffhitanim && animCurrent == staffhitanim) || (animTarget == staffhitreversedanim && animCurrent == staffhitreversedanim) || (animTarget == staffspinhitreversedanim && animCurrent == staffspinhitreversedanim) || (animTarget == staffgroundsmashanim && animCurrent == staffgroundsmashanim) || (animTarget == staffspinhitanim && animCurrent == staffspinhitanim)) {
6467 XYZ temppoint1, temppoint2, tempforward;
6470 temppoint1 = animation[animCurrent].position[skeleton.jointlabels[righthand]][frameCurrent] * (1 - target) + animation[animTarget].position[skeleton.jointlabels[righthand]][frameTarget] * (target); //jointPos(righthand);
6471 temppoint2 = animation[animCurrent].weapontarget[frameCurrent] * (1 - target) + animation[animTarget].weapontarget[frameTarget] * (target);
6472 distance = findDistance(&temppoint1, &temppoint2);
6473 weapons[i].rotation2 = asin((temppoint1.y - temppoint2.y) / distance);
6474 weapons[i].rotation2 *= 360 / 6.28;
6477 weapons[i].rotation1 = acos((temppoint1.z - temppoint2.z) / findDistance(&temppoint1, &temppoint2));
6478 weapons[i].rotation1 *= 360 / 6.28;
6479 weapons[i].rotation3 = 0;
6480 weapons[i].smallrotation = 90;
6481 weapons[i].smallrotation2 = 0;
6482 if (temppoint1.x > temppoint2.x)
6483 weapons[i].rotation1 = 360 - weapons[i].rotation1;
6487 if (weaponactive != k && weaponstuck != k) {
6488 if (weapons[i].getType() == knife) {
6489 weapons[i].smallrotation = -70;
6490 weapons[i].smallrotation2 = 10;
6492 if (weapons[i].getType() == sword) {
6493 weapons[i].smallrotation = -100;
6494 weapons[i].smallrotation2 = -8;
6496 if (weapons[i].getType() == staff) {
6497 weapons[i].smallrotation = -100;
6498 weapons[i].smallrotation2 = -8;
6501 if (weaponstuck == k) {
6502 if (weaponstuckwhere == 0)
6503 weapons[i].smallrotation = 180;
6505 weapons[i].smallrotation = 0;
6506 weapons[i].smallrotation2 = 10;
6515 if (animation[animTarget].attack || isRun() || animTarget == staggerbackhardanim || isFlip() || animTarget == climbanim || animTarget == sneakanim || animTarget == rollanim || animTarget == walkanim || animTarget == backhandspringanim || isFlip() || isWallJump())
6517 if (animCurrent != animTarget)
6519 if (skeleton.free == 2)
6528 int Person::SphereCheck(XYZ *p1, float radius, XYZ *p, XYZ *move, float *rotate, Model *model)
6531 static float distance;
6532 static float olddistance;
6533 static int intersecting;
6534 static int firstintersecting;
6537 static XYZ start, end;
6538 static float slopethreshold = -.4;
6540 firstintersecting = -1;
6544 if (distsq(p1, &model->boundingspherecenter) > radius * radius + model->boundingsphereradius * model->boundingsphereradius)
6547 *p1 = DoRotation(*p1, 0, -*rotate, 0);
6548 for (i = 0; i < 4; i++) {
6549 for (j = 0; j < model->TriangleNum; j++) {
6550 if (model->facenormals[j].y <= slopethreshold) {
6552 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)));
6553 if (distance < radius) {
6554 point = *p1 - model->facenormals[j] * distance;
6555 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]]))
6558 intersecting = sphere_line_intersection(&model->vertex[model->Triangles[j].vertex[0]],
6559 &model->vertex[model->Triangles[j].vertex[1]],
6562 intersecting = sphere_line_intersection(&model->vertex[model->Triangles[j].vertex[1]],
6563 &model->vertex[model->Triangles[j].vertex[2]],
6566 intersecting = sphere_line_intersection(&model->vertex[model->Triangles[j].vertex[0]],
6567 &model->vertex[model->Triangles[j].vertex[2]],
6570 if (dotproduct(&model->facenormals[j], &end) > 0 && intersecting) {
6574 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)) {
6575 p1->y = point.y + radius;
6576 if ((animTarget == jumpdownanim || isFlip())) {
6577 if (isFlip() && (frameTarget < 5 || animation[animTarget].label[frameTarget] == 7 || animation[animTarget].label[frameTarget] == 4))
6580 if (animTarget == jumpupanim) {
6582 animTarget = getIdle();
6589 pause_sound(whooshsound);
6590 OPENAL_SetVolume(channels[whooshsound], 0);
6593 if ((animTarget == jumpdownanim || isFlip()) && !wasLanding() && !wasLandhard()) {
6596 animTarget = getLanding();
6597 emit_sound_at(landsound, coords, 128.);
6600 envsound[numenvsounds] = coords;
6601 envsoundvol[numenvsounds] = 16;
6602 envsoundlife[numenvsounds] = .4;
6610 if ((distance < olddistance || firstintersecting == -1) && intersecting) {
6611 olddistance = distance;
6612 firstintersecting = j;
6617 for (j = 0; j < model->TriangleNum; j++) {
6618 if (model->facenormals[j].y > slopethreshold) {
6621 start.y -= radius / 4;
6622 XYZ &v0 = model->vertex[model->Triangles[j].vertex[0]];
6623 XYZ &v1 = model->vertex[model->Triangles[j].vertex[1]];
6624 XYZ &v2 = model->vertex[model->Triangles[j].vertex[2]];
6625 distance = abs((model->facenormals[j].x * start.x)
6626 + (model->facenormals[j].y * start.y)
6627 + (model->facenormals[j].z * start.z)
6628 - ((model->facenormals[j].x * v0.x)
6629 + (model->facenormals[j].y * v0.y)
6630 + (model->facenormals[j].z * v0.z)));
6631 if (distance < radius * .5) {
6632 point = start - model->facenormals[j] * distance;
6633 if (PointInTriangle( &point, model->facenormals[j], &v0, &v1, &v2))
6636 intersecting = sphere_line_intersection(v0.x, v0.y, v0.z, v1.x, v1.y, v1.z, p1->x, p1->y, p1->z, radius / 2);
6638 intersecting = sphere_line_intersection(v1.x, v1.y, v1.z, v2.x, v2.y, v2.z, p1->x, p1->y, p1->z, radius / 2);
6640 intersecting = sphere_line_intersection(v0.x, v0.y, v0.z, v2.x, v2.y, v2.z, p1->x, p1->y, p1->z, radius / 2);
6642 if (dotproduct(&model->facenormals[j], &end) > 0 && intersecting) {
6643 if ((animTarget == jumpdownanim || animTarget == jumpupanim || isFlip())) {
6645 velocity -= DoRotation(model->facenormals[j], 0, *rotate, 0) * findLength(&velocity) * abs(normaldotproduct(velocity, DoRotation(model->facenormals[j], 0, *rotate, 0))); //(distance-radius*.5)/multiplier;
6646 if (findLengthfast(&start) < findLengthfast(&velocity))
6649 *p1 += model->facenormals[j] * (distance - radius * .5);
6652 if ((distance < olddistance || firstintersecting == -1) && intersecting) {
6653 olddistance = distance;
6654 firstintersecting = j;
6661 *p = DoRotation(*p, 0, *rotate, 0);
6664 *p1 = DoRotation(*p1, 0, *rotate, 0);
6666 return firstintersecting;