2 Copyright (C) 2003, 2010 - Wolfire Games
3 Copyright (C) 2010-2016 - Lugaru contributors (see AUTHORS file)
5 This file is part of Lugaru.
7 Lugaru is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 2 of the License, or
10 (at your option) any later version.
12 Lugaru is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
17 You should have received a copy of the GNU General Public License
18 along with Lugaru. If not, see <http://www.gnu.org/licenses/>.
21 /**> HEADER FILES <**/
23 #include "openal_wrapper.h"
24 #include "Animation.h"
29 extern float multiplier;
30 extern Terrain terrain;
32 extern int environment;
34 extern FRUSTUM frustum;
36 extern float realmultiplier;
38 extern float slomodelay;
39 extern bool cellophane;
40 extern float texdetail;
41 extern float realtexdetail;
42 extern GLubyte bloodText[512 * 512 * 3];
43 extern GLubyte wolfbloodText[512 * 512 * 3];
44 extern int bloodtoggle;
45 extern Objects objects;
46 extern bool autoslomo;
47 extern float camerashake;
49 extern float viewdistance;
50 extern float blackout;
51 extern int difficulty;
53 extern float fadestart;
55 extern bool winfreeze;
56 extern bool showpoints;
57 extern bool immediate;
58 extern int tutoriallevel;
59 extern float smoketex;
60 extern int tutorialstage;
61 extern bool reversaltrain;
62 extern bool canattack;
64 extern float damagedealt;
66 extern float hostiletime;
68 extern int indialogue;
70 extern bool gamestarted;
72 std::vector<std::shared_ptr<Person>> Person::players(1, std::shared_ptr<Person>(new Person()));
85 howactive(typeactive),
87 superruntoggle(false),
88 lastattack(0), lastattack2(0), lastattack3(0),
89 currentoffset(), targetoffset(), offset(),
121 rabbitkickenabled(false),
133 superpermanentdamage(0),
147 bleedx(0), bleedy(0),
151 headyaw(0), headpitch(0),
152 targetheadyaw(0), targetheadpitch(0),
163 normalsupdatedelay(0),
166 forwardkeydown(false),
167 forwardstogglekeydown(false),
172 jumptogglekeydown(false),
173 crouchkeydown(false),
174 crouchtogglekeydown(false),
176 drawtogglekeydown(false),
178 throwtogglekeydown(false),
179 attackkeydown(false),
184 crouchkeydowntime(0),
198 whichdirection(false),
199 whichdirectiondelay(0),
200 avoidsomething(false),
209 lefthandmorphness(0),
210 righthandmorphness(0),
214 targetlefthandmorphness(0),
215 targetrighthandmorphness(0),
216 targetheadmorphness(0),
217 targetchestmorphness(0),
218 targettailmorphness(0),
219 lefthandmorphstart(0), lefthandmorphend(0),
220 righthandmorphstart(0), righthandmorphend(0),
221 headmorphstart(0), headmorphend(0),
222 chestmorphstart(0), chestmorphend(0),
223 tailmorphstart(0), tailmorphend(0),
226 highreversaldelay(0),
229 creature(rabbittype),
276 finalpathfindpoint(0),
277 targetpathfindpoint(0),
278 lastpathfindpoint(0),
279 lastpathfindpoint2(0),
280 lastpathfindpoint3(0),
281 lastpathfindpoint4(0),
297 neckspurtparticledelay(0),
301 rabbitkickragdoll(false),
311 /* Read a person in tfile. Throws an error if it’s not valid */
312 Person::Person(FILE *tfile, int mapvers, unsigned i) : Person()
315 funpackf(tfile, "Bi Bi Bf Bf Bf Bi", &whichskin, &creature, &coords.x, &coords.y, &coords.z, &num_weapons);
317 funpackf(tfile, "Bi", &howactive);
319 howactive = typeactive;
322 funpackf(tfile, "Bf", &scale);
327 funpackf(tfile, "Bb", &immobile);
332 funpackf(tfile, "Bf", &yaw);
337 if (num_weapons < 0 || num_weapons > 5) {
338 throw InvalidPersonException();
340 if (num_weapons > 0 && num_weapons < 5) {
341 for (int j = 0; j < num_weapons; j++) {
342 weaponids[j] = weapons.size();
344 funpackf(tfile, "Bi", &type);
345 weapons.push_back(Weapon(type, id));
348 funpackf(tfile, "Bi", &numwaypoints);
349 for (int j = 0; j < numwaypoints; j++) {
350 funpackf(tfile, "Bf", &waypoints[j].x);
351 funpackf(tfile, "Bf", &waypoints[j].y);
352 funpackf(tfile, "Bf", &waypoints[j].z);
354 funpackf(tfile, "Bi", &waypointtype[j]);
356 waypointtype[j] = wpkeepwalking;
360 funpackf(tfile, "Bi", &waypoint);
361 if (waypoint > (numwaypoints - 1)) {
365 funpackf(tfile, "Bf Bf Bf", &armorhead, &armorhigh, &armorlow);
366 funpackf(tfile, "Bf Bf Bf", &protectionhead, &protectionhigh, &protectionlow);
367 funpackf(tfile, "Bf Bf Bf", &metalhead, &metalhigh, &metallow);
368 funpackf(tfile, "Bf Bf", &power, &speedmult);
370 float headprop, legprop, armprop, bodyprop;
373 funpackf(tfile, "Bf Bf Bf Bf", &headprop, &bodyprop, &armprop, &legprop);
381 if (creature == wolftype) {
382 proportionhead = 1.1 * headprop;
383 proportionbody = 1.1 * bodyprop;
384 proportionarms = 1.1 * armprop;
385 proportionlegs = 1.1 * legprop;
386 } else if (creature == rabbittype) {
387 proportionhead = 1.2 * headprop;
388 proportionbody = 1.05 * bodyprop;
389 proportionarms = 1.00 * armprop;
390 proportionlegs = 1.1 * legprop;
391 proportionlegs.y = 1.05 * legprop;
394 funpackf(tfile, "Bi", &numclothes);
395 for (int k = 0; k < numclothes; k++) {
397 funpackf(tfile, "Bi", &templength);
398 for (int l = 0; l < templength; l++)
399 funpackf(tfile, "Bb", &clothes[k][l]);
400 clothes[k][templength] = '\0';
401 funpackf(tfile, "Bf Bf Bf", &clothestintr[k], &clothestintg[k], &clothestintb[k]);
408 * GameTick/doPlayerCollisions
410 void Person::CheckKick()
413 && (animTarget == rabbitkickanim
415 && victim != this->shared_from_this()
417 && animCurrent == rabbitkickanim)
418 && distsq(&coords, &victim->coords) < 1.2
419 && !victim->skeleton.free))
422 if (animation[victim->animTarget].height != lowheight) {
423 float damagemult = (creature == wolftype ? 2.5 : 1.) * power * power;
424 XYZ relative = velocity;
426 Normalise(&relative);
430 if (tutoriallevel != 1)
431 emit_sound_at(heavyimpactsound, victim->coords);
433 for (int i = 0; i < victim->skeleton.num_joints; i++) {
434 victim->skeleton.joints[i].velocity += relative * 120 * damagemult;
437 victim->DoDamage(100 * damagemult / victim->protectionhigh);
443 animTarget = backflipanim;
445 velocity = facing * -10;
449 resume_stream(whooshsound);
451 award_bonus(id, cannon);
452 } else if (victim->isCrouch()) {
453 animTarget = rabbitkickreversedanim;
454 animCurrent = rabbitkickreversedanim;
455 victim->animCurrent = rabbitkickreversalanim;
456 victim->animTarget = rabbitkickreversalanim;
462 victim->oldcoords = victim->coords;
463 coords = victim->coords;
464 victim->targetyaw = targetyaw;
465 victim->victim = this->shared_from_this();
472 * GameTick/doPlayerCollisions - spread fire between players
473 * GameTick/doDebugKeys - press f to ignite
474 * Person::DoStuff - spread fire from lit campfires and bushes
476 void Person::CatchFire()
478 XYZ flatfacing, flatvelocity;
480 for (int i = 0; i < 10; i++) {
481 howmany = abs(Random() % (skeleton.num_joints));
483 flatvelocity = skeleton.joints[howmany].velocity;
484 flatfacing = skeleton.joints[howmany].position * scale + coords;
486 flatvelocity = velocity;
487 flatfacing = DoRotation(DoRotation(DoRotation(skeleton.joints[howmany].position, 0, 0, tilt), tilt2, 0, 0), 0, yaw, 0) * scale + coords;
489 Sprite::MakeSprite(flamesprite, flatfacing, flatvelocity, 1, 1, 1, 2, 1);
494 emit_sound_at(firestartsound, coords);
496 emit_stream_at(stream_firesound, coords);
504 * idle animation for this creature (depending on status)
506 int Person::getIdle()
508 if (indialogue != -1 && howactive == typeactive && creature == rabbittype)
510 if (hasvictim && (victim != this->shared_from_this())/*||(id==0&&attackkeydown)*/)
511 if (/*(id==0&&attackkeydown)||*/(!victim->dead && victim->aitype != passivetype &&
512 victim->aitype != searchtype && aitype != passivetype && aitype != searchtype &&
513 victim->id < Person::players.size())) {
514 if ((aitype == playercontrolled && stunned <= 0 && weaponactive == -1) || pause) {
515 if (creature == rabbittype)
516 return fightidleanim;
517 if (creature == wolftype)
520 if (aitype == playercontrolled && stunned <= 0 && weaponactive != -1) {
521 if (weapons[weaponids[weaponactive]].getType() == knife)
522 return knifefightidleanim;
523 if (weapons[weaponids[weaponactive]].getType() == sword && victim->weaponactive != -1)
524 return swordfightidlebothanim;
525 if (weapons[weaponids[weaponactive]].getType() == sword)
526 return swordfightidleanim;
527 if (weapons[weaponids[weaponactive]].getType() == staff)
528 return swordfightidleanim;
530 if (aitype != playercontrolled && stunned <= 0 && creature != wolftype && !pause)
531 return fightsidestep;
533 if ((damage > permanentdamage || damage > damagetolerance * .8 || deathbleeding > 0) && creature != wolftype)
535 if (howactive == typesitting) return sitanim;
536 if (howactive == typesittingwall) return sitwallanim;
537 if (howactive == typesleeping) return sleepanim;
538 if (howactive == typedead1) return dead1anim;
539 if (howactive == typedead2) return dead2anim;
540 if (howactive == typedead3) return dead3anim;
541 if (howactive == typedead4) return dead4anim;
542 if (creature == rabbittype) return bounceidleanim;
543 if (creature == wolftype) return wolfidle;
548 * crouch animation for this creature
550 int Person::getCrouch()
552 if (creature == rabbittype)
554 if (creature == wolftype)
555 return wolfcrouchanim;
560 * running animation for this creature (can be upright or all fours)
564 if (creature == rabbittype && (!superruntoggle || weaponactive != -1))
566 if (creature == wolftype && (!superruntoggle))
569 if (creature == rabbittype && (superruntoggle && weaponactive == -1))
570 return rabbitrunninganim;
571 if (creature == wolftype && (superruntoggle))
572 return wolfrunninganim;
578 int Person::getStop()
580 if (creature == rabbittype)
582 if (creature == wolftype)
589 int Person::getLanding()
591 if (creature == rabbittype)
593 if (creature == wolftype)
600 int Person::getLandhard()
602 if (creature == rabbittype)
604 if (creature == wolftype)
605 return wolflandhardanim;
612 * Person::DoAnimations
615 SolidHitBonus(int playerid)
617 if (bonustime < 1.5 && bonus >= solidhit && bonus <= megacombo)
618 award_bonus(playerid, bonus == megacombo ? bonus : bonus + 1);
620 award_bonus(playerid, solidhit);
624 * spawns blood effects
626 void Person::DoBlood(float howmuch, int which)
628 // FIXME: should abstract out inputs
629 static int bleedxint, bleedyint;
631 if (bloodtoggle && tutoriallevel != 1) {
632 if (bleeding <= 0 && spurt) {
634 for (int i = 0; i < 3; i++) {
635 // emit blood particles
638 bloodvel -= DoRotation(skeleton.forward * 10 * scale, ((float)(Random() % 100)) / 4, ((float)(Random() % 100)) / 4, 0);
639 bloodvel += DoRotation(jointVel(head), ((float)(Random() % 100)) / 4, yaw + ((float)(Random() % 100)) / 4, 0) * scale;
640 Sprite::MakeSprite(bloodsprite, jointPos(head) * scale + coords, bloodvel, 1, 1, 1, .05, 1);
641 Sprite::MakeSprite(bloodflamesprite, jointPos(head) * scale + coords, bloodvel, 1, 1, 1, .3, 1);
644 bloodvel = DoRotation(bloodvel, ((float)(Random() % 100)) / 4, yaw + ((float)(Random() % 100)) / 4, 0) * scale;
645 bloodvel += DoRotation(velocity, ((float)(Random() % 100)) / 4, ((float)(Random() % 100)) / 4, 0) * scale;
646 Sprite::MakeSprite(bloodsprite, DoRotation((jointPos(head) + jointPos(neck)) / 2, 0, yaw, 0)*scale + coords, bloodvel, 1, 1, 1, .05, 1);
647 Sprite::MakeSprite(bloodflamesprite, DoRotation((jointPos(head) + jointPos(neck)) / 2, 0, yaw, 0)*scale + coords, bloodvel, 1, 1, 1, .3, 1);
650 if (Random() % 2 == 0) // 50% chance
651 for (int i = 0; i < 3; i++) {
652 if (Random() % 2 != 0) {
653 // emit teeth particles
656 bloodvel -= DoRotation(skeleton.forward * 10 * scale, ((float)(Random() % 100)) / 4, ((float)(Random() % 100)) / 4, 0);
657 bloodvel += DoRotation(jointVel(head), ((float)(Random() % 100)) / 4, yaw + ((float)(Random() % 100)) / 4, 0) * scale;
660 bloodvel = DoRotation(bloodvel, ((float)(Random() % 100)) / 4, yaw + ((float)(Random() % 100)) / 4, 0) * scale;
661 bloodvel += DoRotation(velocity, ((float)(Random() % 100)) / 4, ((float)(Random() % 100)) / 4, 0) * scale;
665 Sprite::MakeSprite(splintersprite, jointPos(head) * scale + coords, bloodvel, 1, 1, 1, .05, 1);
667 Sprite::MakeSprite(splintersprite, DoRotation((jointPos(head) + jointPos(neck)) / 2, 0, yaw, 0)*scale + coords, bloodvel, 1, 1, 1, .05, 1);
669 Sprite::setLastSpriteSpecial(3); // sets it to teeth
674 // FIXME: manipulating attributes
675 bleeding = howmuch + (float)abs(Random() % 100) / 200 - .25;
678 if (creature == rabbittype)
679 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) {
680 bleedxint = abs(Random() % 512);
681 bleedyint = abs(Random() % 512);
683 if (creature == wolftype)
684 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) {
685 bleedxint = abs(Random() % 512);
686 bleedyint = abs(Random() % 512);
690 bleedy /= realtexdetail;
691 bleedx /= realtexdetail;
692 direction = abs(Random() % 2) * 2 - 1;
701 * spawns big blood effects and ???
702 * modifies character's skin texture
704 void Person::DoBloodBig(float howmuch, int which)
706 static int bleedxint, bleedyint, i, j;
708 if (howmuch && id == 0)
711 if (tutoriallevel != 1 || id == 0)
712 if (aitype != playercontrolled && howmuch > 0) {
716 if (creature == wolftype) {
717 int i = abs(Random() % 2);
719 whichsound = snarlsound;
721 whichsound = snarl2sound;
723 if (creature == rabbittype) {
724 int i = abs(Random() % 2);
726 whichsound = rabbitpainsound;
727 if (i == 1 && howmuch >= 2)
728 whichsound = rabbitpain1sound;
731 if (whichsound != -1) {
732 emit_sound_at(whichsound, coords);
737 if (id == 0 && howmuch > 0) {
741 if (bloodtoggle && decals && tutoriallevel != 1) {
742 if (bleeding <= 0 && spurt) {
744 for (int i = 0; i < 3; i++) {
745 // emit blood particles
746 // FIXME: copypaste from above
749 bloodvel -= DoRotation(skeleton.forward * 10 * scale, ((float)(Random() % 100)) / 4, ((float)(Random() % 100)) / 4, 0);
750 bloodvel += DoRotation(jointVel(head), ((float)(Random() % 100)) / 4, yaw + ((float)(Random() % 100)) / 4, 0) * scale;
751 Sprite::MakeSprite(bloodsprite, jointPos(head) * scale + coords, bloodvel, 1, 1, 1, .05, 1);
752 Sprite::MakeSprite(bloodflamesprite, jointPos(head) * scale + coords, bloodvel, 1, 1, 1, .3, 1);
755 bloodvel = DoRotation(bloodvel, ((float)(Random() % 100)) / 4, yaw + ((float)(Random() % 100)) / 4, 0) * scale;
756 bloodvel += DoRotation(velocity, ((float)(Random() % 100)) / 4, ((float)(Random() % 100)) / 4, 0) * scale;
757 Sprite::MakeSprite(bloodsprite, DoRotation((jointPos(head) + jointPos(neck)) / 2, 0, yaw, 0)*scale + coords, bloodvel, 1, 1, 1, .05, 1);
758 Sprite::MakeSprite(bloodflamesprite, DoRotation((jointPos(head) + jointPos(neck)) / 2, 0, yaw, 0)*scale + coords, bloodvel, 1, 1, 1, .3, 1);
763 // weird texture manipulation code follows.
764 // looks like this is painting blood onto the character's skin texture
765 // FIXME: surely there's a better way
767 int offsetx = 0, offsety = 0;
769 offsety = Random() % 40;
770 offsetx = abs(Random() % 60);
772 if (which == 190 || which == 185) {
773 offsety = Random() % 40;
774 offsetx = abs(Random() % 100) - 20;
777 offsety = Random() % 10;
778 offsetx = Random() % 10;
781 offsety = Random() % 20;
782 offsetx = Random() % 20;
784 if (which == 220 || which == 215) {
794 if (creature == rabbittype)
795 for (i = 0; i < 512; i++) {
796 for (j = 0; j < 512; j++) {
797 if (bloodText[i * 512 * 3 + j * 3 + 0] <= which + 4 && bloodText[i * 512 * 3 + j * 3 + 0] >= which - 4) {
798 if (i < startx) startx = i;
799 if (j < starty) starty = j;
800 if (i > endx) endx = i;
801 if (j > endy) endy = j;
805 if (creature == wolftype)
806 for (i = 0; i < 512; i++) {
807 for (j = 0; j < 512; j++) {
808 if (wolfbloodText[i * 512 * 3 + j * 3 + 0] <= which + 4 && wolfbloodText[i * 512 * 3 + j * 3 + 0] >= which - 4) {
809 if (i < startx) startx = i;
810 if (j < starty) starty = j;
811 if (i > endx) endx = i;
812 if (j > endy) endy = j;
822 if (startx < 0) startx = 0;
823 if (starty < 0) starty = 0;
824 if (endx > 512 - 1) endx = 512 - 1;
825 if (endy > 512 - 1) endy = 512 - 1;
826 if (endx < startx) endx = startx;
827 if (endy < starty) endy = starty;
829 startx /= realtexdetail;
830 starty /= realtexdetail;
831 endx /= realtexdetail;
832 endy /= realtexdetail;
834 int texdetailint = realtexdetail;
836 if (creature == rabbittype)
837 for (i = startx; i < endx; i++) {
838 for (j = starty; j < endy; j++) {
839 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) {
840 color = Random() % 85 + 170;
841 where = i * skeleton.skinsize * 3 + j * 3;
842 if (skeleton.skinText[where + 0] > color / 2)
843 skeleton.skinText[where + 0] = color / 2;
844 skeleton.skinText[where + 1] = 0;
845 skeleton.skinText[where + 2] = 0;
849 if (creature == wolftype)
850 for (i = startx; i < endx; i++) {
851 for (j = starty; j < endy; j++) {
852 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) {
853 color = Random() % 85 + 170;
854 where = i * skeleton.skinsize * 3 + j * 3;
855 if (skeleton.skinText[where + 0] > color / 2)
856 skeleton.skinText[where + 0] = color / 2;
857 skeleton.skinText[where + 1] = 0;
858 skeleton.skinText[where + 2] = 0;
862 skeleton.drawmodel.textureptr.bind();
867 if (creature == rabbittype)
868 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) {
869 bleedxint = abs(Random() % 512);
870 bleedyint = abs(Random() % 512);
872 if (creature == wolftype)
873 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) {
874 bleedxint = abs(Random() % 512);
875 bleedyint = abs(Random() % 512);
877 bleedy = bleedxint + offsetx;
878 bleedx = bleedyint + offsety;
879 bleedy /= realtexdetail;
880 bleedx /= realtexdetail;
885 if (bleedx > skeleton.skinsize - 1)
886 bleedx = skeleton.skinsize - 1;
887 if (bleedy > skeleton.skinsize - 1)
888 bleedy = skeleton.skinsize - 1;
889 direction = abs(Random() % 2) * 2 - 1;
892 bleeding = howmuch + (float)abs(Random() % 100) / 200 - .25;
893 deathbleeding += bleeding;
894 bloodloss += bleeding * 3;
896 if (tutoriallevel != 1 && aitype != playercontrolled && bloodloss > damagetolerance * 2 / 3 && bloodloss < damagetolerance && creature == rabbittype) {
897 if (abs(Random() % 2) == 0) {
898 aitype = gethelptype;
901 aitype = attacktypecutoff;
909 * similar to DoBloodBig
911 bool Person::DoBloodBigWhere(float howmuch, int which, XYZ where)
915 static XYZ startpoint, endpoint, colpoint, movepoint;
916 static float rotationpoint;
918 static XYZ p1, p2, p3, p0;
921 float coordsx, coordsy;
924 if (bloodtoggle && decals && tutoriallevel != 1) {
927 where = DoRotation(where, 0, -yaw, 0);
935 // ray testing for a tri in the character model
936 whichtri = skeleton.drawmodel.LineCheck(&startpoint, &endpoint, &colpoint, &movepoint, &rotationpoint);
937 if (whichtri != -1) {
938 // low level geometry math
940 p1 = skeleton.drawmodel.vertex[skeleton.drawmodel.Triangles[whichtri].vertex[0]];
941 p2 = skeleton.drawmodel.vertex[skeleton.drawmodel.Triangles[whichtri].vertex[1]];
942 p3 = skeleton.drawmodel.vertex[skeleton.drawmodel.Triangles[whichtri].vertex[2]];
944 bary.x = distsq(&p0, &p1);
945 bary.y = distsq(&p0, &p2);
946 bary.z = distsq(&p0, &p3);
948 total = bary.x + bary.y + bary.z;
957 total = bary.x + bary.y + bary.z;
963 gxx.x = skeleton.drawmodel.Triangles[whichtri].gx[0];
964 gxx.y = skeleton.drawmodel.Triangles[whichtri].gx[1];
965 gxx.z = skeleton.drawmodel.Triangles[whichtri].gx[2];
966 gyy.x = skeleton.drawmodel.Triangles[whichtri].gy[0];
967 gyy.y = skeleton.drawmodel.Triangles[whichtri].gy[1];
968 gyy.z = skeleton.drawmodel.Triangles[whichtri].gy[2];
969 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;
970 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;
972 if (bleeding <= 0 && spurt) {
974 for (int i = 0; i < 3; i++) {
975 // emit blood particles
976 // FIXME: more copypaste code
979 bloodvel -= DoRotation(skeleton.forward * 10 * scale, ((float)(Random() % 100)) / 4, ((float)(Random() % 100)) / 4, 0);
980 bloodvel += DoRotation(jointVel(head), ((float)(Random() % 100)) / 4, yaw + ((float)(Random() % 100)) / 4, 0) * scale;
981 Sprite::MakeSprite(bloodsprite, jointPos(head) * scale + coords, bloodvel, 1, 1, 1, .05, 1);
982 Sprite::MakeSprite(bloodflamesprite, jointPos(head) * scale + coords, bloodvel, 1, 1, 1, .3, 1);
985 bloodvel = DoRotation(bloodvel, ((float)(Random() % 100)) / 4, yaw + ((float)(Random() % 100)) / 4, 0) * scale;
986 bloodvel += DoRotation(velocity, ((float)(Random() % 100)) / 4, ((float)(Random() % 100)) / 4, 0) * scale;
987 Sprite::MakeSprite(bloodsprite, DoRotation((jointPos(head) + jointPos(neck)) / 2, 0, yaw, 0)*scale + coords, bloodvel, 1, 1, 1, .05, 1);
988 Sprite::MakeSprite(bloodflamesprite, DoRotation((jointPos(head) + jointPos(neck)) / 2, 0, yaw, 0)*scale + coords, bloodvel, 1, 1, 1, .3, 1);
993 // texture manipulation follows
995 int offsetx = 0, offsety = 0;
996 offsetx = (1 + coordsy) * 512 - 291;
997 offsety = coordsx * 512 - 437;
1004 if (creature == rabbittype)
1005 for (i = 0; i < 512; i++) {
1006 for (j = 0; j < 512; j++) {
1007 if (bloodText[i * 512 * 3 + j * 3 + 0] <= which + 4 && bloodText[i * 512 * 3 + j * 3 + 0] >= which - 4) {
1008 if (i < startx) startx = i;
1009 if (j < starty) starty = j;
1010 if (i > endx) endx = i;
1011 if (j > endy) endy = j;
1015 if (creature == wolftype)
1016 for (i = 0; i < 512; i++) {
1017 for (j = 0; j < 512; j++) {
1018 if (wolfbloodText[i * 512 * 3 + j * 3 + 0] <= which + 4 && wolfbloodText[i * 512 * 3 + j * 3 + 0] >= which - 4) {
1019 if (i < startx) startx = i;
1020 if (j < starty) starty = j;
1021 if (i > endx) endx = i;
1022 if (j > endy) endy = j;
1031 if (startx < 0) startx = 0;
1032 if (starty < 0) starty = 0;
1033 if (endx > 512 - 1) endx = 512 - 1;
1034 if (endy > 512 - 1) endy = 512 - 1;
1035 if (endx < startx) endx = startx;
1036 if (endy < starty) endy = starty;
1038 startx /= realtexdetail;
1039 starty /= realtexdetail;
1040 endx /= realtexdetail;
1041 endy /= realtexdetail;
1043 int texdetailint = realtexdetail;
1045 if (creature == rabbittype)
1046 for (i = startx; i < endx; i++) {
1047 for (j = starty; j < endy; j++) {
1048 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) {
1049 color = Random() % 85 + 170;
1050 where = i * skeleton.skinsize * 3 + j * 3;
1051 if (skeleton.skinText[where + 0] > color / 2)
1052 skeleton.skinText[where + 0] = color / 2;
1053 skeleton.skinText[where + 1] = 0;
1054 skeleton.skinText[where + 2] = 0;
1055 } 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) {
1056 color = Random() % 85 + 170;
1057 where = i * skeleton.skinsize * 3 + j * 3;
1058 if (skeleton.skinText[where + 0] > color / 2)
1059 skeleton.skinText[where + 0] = color / 2;
1060 skeleton.skinText[where + 1] = 0;
1061 skeleton.skinText[where + 2] = 0;
1065 if (creature == wolftype)
1066 for (i = startx; i < endx; i++) {
1067 for (j = starty; j < endy; j++) {
1068 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) {
1069 color = Random() % 85 + 170;
1070 where = i * skeleton.skinsize * 3 + j * 3;
1071 if (skeleton.skinText[where + 0] > color / 2)
1072 skeleton.skinText[where + 0] = color / 2;
1073 skeleton.skinText[where + 1] = 0;
1074 skeleton.skinText[where + 2] = 0;
1075 } 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) {
1076 color = Random() % 85 + 170;
1077 where = i * skeleton.skinsize * 3 + j * 3;
1078 if (skeleton.skinText[where + 0] > color / 2)
1079 skeleton.skinText[where + 0] = color / 2;
1080 skeleton.skinText[where + 1] = 0;
1081 skeleton.skinText[where + 2] = 0;
1085 skeleton.drawmodel.textureptr.bind();
1088 bleedy = (1 + coordsy) * 512;
1089 bleedx = coordsx * 512;
1090 bleedy /= realtexdetail;
1091 bleedx /= realtexdetail;
1096 if (bleedx > skeleton.skinsize - 1)
1097 bleedx = skeleton.skinsize - 1;
1098 if (bleedy > skeleton.skinsize - 1)
1099 bleedy = skeleton.skinsize - 1;
1100 direction = abs(Random() % 2) * 2 - 1;
1105 bleeding = howmuch + (float)abs(Random() % 100) / 200 - .25;
1106 deathbleeding += bleeding;
1107 bloodloss += bleeding * 3;
1109 if (tutoriallevel != 1 && aitype != playercontrolled && bloodloss > damagetolerance * 2 / 3 && bloodloss < damagetolerance && creature == rabbittype) {
1110 if (abs(Random() % 2) == 0) {
1111 aitype = gethelptype;
1114 aitype = attacktypecutoff;
1125 * guessing this performs a reversal
1127 void Person::Reverse()
1129 if (!((victim->aitype == playercontrolled
1131 || staggerdelay <= 0)
1132 && victim->animTarget != jumpupanim
1133 && victim->animTarget != jumpdownanim
1134 && (tutoriallevel != 1 || cananger)
1138 if (normaldotproduct (victim->facing, victim->coords - coords) > 0
1139 && (victim->id != 0 || difficulty >= 2)
1140 && (creature != wolftype || victim->creature == wolftype))
1143 if (animTarget == sweepanim) {
1144 animTarget = sweepreversedanim;
1145 animCurrent = sweepreversedanim;
1146 victim->animCurrent = sweepreversalanim;
1147 victim->animTarget = sweepreversalanim;
1149 if (animTarget == spinkickanim) {
1150 animTarget = spinkickreversedanim;
1151 animCurrent = spinkickreversedanim;
1152 victim->animCurrent = spinkickreversalanim;
1153 victim->animTarget = spinkickreversalanim;
1155 if (animTarget == upunchanim || animTarget == rabbittacklinganim) {
1156 if (animTarget == rabbittacklinganim) {
1159 victim->frameCurrent = 6;
1160 victim->frameTarget = 7;
1162 animTarget = upunchreversedanim;
1163 animCurrent = upunchreversedanim;
1164 victim->animCurrent = upunchreversalanim;
1165 victim->animTarget = upunchreversalanim;
1167 if (animTarget == staffhitanim && distsq(&victim->coords, &coords) < 2 && ((victim->id == 0 && victim->crouchkeydown) || Random() % 4 == 0)) {
1168 if (victim->weaponactive != -1) {
1169 victim->throwtogglekeydown = 1;
1170 XYZ tempVelocity = victim->velocity * .2;
1171 if (tempVelocity.x == 0)
1172 tempVelocity.x = .1;
1173 weapons[victim->weaponids[0]].drop(tempVelocity, tempVelocity, false);
1174 victim->num_weapons--;
1175 if (victim->num_weapons) {
1176 victim->weaponids[0] = victim->weaponids[victim->num_weapons];
1177 if (victim->weaponstuck == victim->num_weapons)
1178 victim->weaponstuck = 0;
1181 victim->weaponactive = -1;
1182 for (unsigned j = 0; j < Person::players.size(); j++) {
1183 Person::players[j]->wentforweapon = 0;
1187 animTarget = staffhitreversedanim;
1188 animCurrent = staffhitreversedanim;
1189 victim->animCurrent = staffhitreversalanim;
1190 victim->animTarget = staffhitreversalanim;
1192 if (animTarget == staffspinhitanim && distsq(&victim->coords, &coords) < 2 && ((victim->id == 0 && victim->crouchkeydown) || Random() % 2 == 0)) {
1193 if (victim->weaponactive != -1) {
1194 victim->throwtogglekeydown = 1;
1195 XYZ tempVelocity = victim->velocity * .2;
1196 if (tempVelocity.x == 0)
1197 tempVelocity.x = .1;
1198 weapons[victim->weaponids[0]].drop(tempVelocity, tempVelocity, false);
1199 victim->num_weapons--;
1200 if (victim->num_weapons) {
1201 victim->weaponids[0] = victim->weaponids[victim->num_weapons];
1202 if (victim->weaponstuck == victim->num_weapons)
1203 victim->weaponstuck = 0;
1206 victim->weaponactive = -1;
1207 for (unsigned j = 0; j < Person::players.size(); j++) {
1208 Person::players[j]->wentforweapon = 0;
1211 animTarget = staffspinhitreversedanim;
1212 animCurrent = staffspinhitreversedanim;
1213 victim->animCurrent = staffspinhitreversalanim;
1214 victim->animTarget = staffspinhitreversalanim;
1216 if (animTarget == swordslashanim && distsq(&victim->coords, &coords) < 2 && ((victim->id == 0 && victim->crouchkeydown) || Random() % 4 == 0)) {
1217 if (victim->weaponactive != -1) {
1218 victim->throwtogglekeydown = 1;
1219 XYZ tempVelocity = victim->velocity * .2;
1220 if (tempVelocity.x == 0)
1221 tempVelocity.x = .1;
1222 weapons[victim->weaponids[0]].drop(tempVelocity, tempVelocity, false);
1223 victim->num_weapons--;
1224 if (victim->num_weapons) {
1225 victim->weaponids[0] = victim->weaponids[victim->num_weapons];
1226 if (victim->weaponstuck == victim->num_weapons)
1227 victim->weaponstuck = 0;
1230 victim->weaponactive = -1;
1231 for (unsigned j = 0; j < Person::players.size(); j++) {
1232 Person::players[j]->wentforweapon = 0;
1235 animTarget = swordslashreversedanim;
1236 animCurrent = swordslashreversedanim;
1237 victim->animCurrent = swordslashreversalanim;
1238 victim->animTarget = swordslashreversalanim;
1240 if (animTarget == knifeslashstartanim && distsq(&victim->coords, &coords) < 2 && (victim->id == 0 || Random() % 4 == 0)) {
1241 if (victim->weaponactive != -1) {
1242 victim->throwtogglekeydown = 1;
1243 XYZ tempVelocity = victim->velocity * .2;
1244 if (tempVelocity.x == 0)
1245 tempVelocity.x = .1;
1246 weapons[victim->weaponids[0]].drop(tempVelocity, tempVelocity, false);
1247 victim->num_weapons--;
1248 if (victim->num_weapons) {
1249 victim->weaponids[0] = victim->weaponids[victim->num_weapons];
1250 if (victim->weaponstuck == victim->num_weapons)
1251 victim->weaponstuck = 0;
1254 victim->weaponactive = -1;
1255 for (unsigned j = 0; j < Person::players.size(); j++) {
1256 Person::players[j]->wentforweapon = 0;
1259 animTarget = knifeslashreversedanim;
1260 animCurrent = knifeslashreversedanim;
1261 victim->animCurrent = knifeslashreversalanim;
1262 victim->animTarget = knifeslashreversalanim;
1264 if (animTarget != knifeslashstartanim && animTarget != staffhitanim && animTarget != staffspinhitanim && animTarget != winduppunchanim && animTarget != wolfslapanim && animTarget != swordslashanim) {
1265 victim->targettilt2 = targettilt2;
1266 victim->frameCurrent = frameCurrent;
1267 victim->frameTarget = frameTarget;
1268 victim->target = target;
1269 victim->velocity = 0;
1270 victim->oldcoords = victim->coords;
1271 victim->coords = coords;
1272 victim->targetyaw = targetyaw;
1273 victim->yaw = targetyaw;
1274 victim->victim = this->shared_from_this();
1276 if (animTarget == winduppunchanim) {
1277 animTarget = winduppunchblockedanim;
1278 victim->animTarget = blockhighleftanim;
1279 victim->frameTarget = 1;
1280 victim->target = .5;
1281 victim->victim = this->shared_from_this();
1282 victim->targetyaw = targetyaw + 180;
1284 if (animTarget == wolfslapanim) {
1285 animTarget = winduppunchblockedanim;
1286 victim->animTarget = blockhighleftanim;
1287 victim->frameTarget = 1;
1288 victim->target = .5;
1289 victim->victim = this->shared_from_this();
1290 victim->targetyaw = targetyaw + 180;
1292 if ((animTarget == swordslashanim || animTarget == staffhitanim || animTarget == staffspinhitanim) && victim->weaponactive != -1) {
1293 animTarget = swordslashparriedanim;
1294 parriedrecently = .4;
1295 victim->parriedrecently = 0;
1296 victim->animTarget = swordslashparryanim;
1297 victim->frameTarget = 1;
1298 victim->target = .5;
1299 victim->victim = this->shared_from_this();
1300 victim->targetyaw = targetyaw + 180;
1302 if (abs(Random() % 20) == 0 || weapons[victim->weaponids[victim->weaponactive]].getType() == knife) {
1303 if (victim->weaponactive != -1) {
1304 if (weapons[victim->weaponids[0]].getType() == staff || weapons[weaponids[0]].getType() == staff) {
1305 if (weapons[victim->weaponids[0]].getType() == staff)
1306 weapons[victim->weaponids[0]].damage += .2 + float(abs(Random() % 100) - 50) / 250;
1307 if (weapons[weaponids[0]].getType() == staff)
1308 weapons[weaponids[0]].damage += .2 + float(abs(Random() % 100) - 50) / 250;
1309 emit_sound_at(swordstaffsound, victim->coords);
1311 emit_sound_at(metalhitsound, victim->coords);
1315 victim->Puff(righthand);
1317 victim->frameTarget = 0;
1318 victim->animTarget = staggerbackhighanim;
1319 victim->targetyaw = targetyaw + 180;
1321 aim = DoRotation(facing, 0, 90, 0) * 21;
1323 weapons[victim->weaponids[0]].drop(aim * -.2, aim);
1324 victim->num_weapons--;
1325 if (victim->num_weapons) {
1326 victim->weaponids[0] = victim->weaponids[num_weapons];
1327 if (victim->weaponstuck == victim->num_weapons)
1328 victim->weaponstuck = 0;
1330 victim->weaponactive = -1;
1331 for (unsigned i = 0; i < Person::players.size(); i++) {
1332 Person::players[i]->wentforweapon = 0;
1336 if (abs(Random() % 20) == 0) {
1337 if (weaponactive != -1) {
1338 if (weapons[victim->weaponids[0]].getType() == staff || weapons[weaponids[0]].getType() == staff) {
1339 if (weapons[victim->weaponids[0]].getType() == staff)
1340 weapons[victim->weaponids[0]].damage += .2 + float(abs(Random() % 100) - 50) / 250;
1341 if (weapons[weaponids[0]].getType() == staff)
1342 weapons[weaponids[0]].damage += .2 + float(abs(Random() % 100) - 50) / 250;
1344 emit_sound_at(swordstaffsound, coords);
1346 emit_sound_at(metalhitsound, coords);
1354 animTarget = staggerbackhighanim;
1355 targetyaw = targetyaw + 180;
1357 aim = DoRotation(facing, 0, 90, 0) * 21;
1359 weapons[victim->weaponids[0]].drop(aim * -.2, aim);
1362 weaponids[0] = weaponids[num_weapons];
1363 if (weaponstuck == num_weapons)
1367 for (unsigned i = 0; i < Person::players.size(); i++) {
1368 Person::players[i]->wentforweapon = 0;
1375 if (animTarget == knifeslashstartanim || animTarget == swordslashanim || animTarget == staffhitanim || animTarget == staffspinhitanim) {
1376 if ((animTarget != staffhitanim && animTarget != staffspinhitanim) || distsq(&coords, &victim->coords) > .2) {
1377 victim->animTarget = dodgebackanim;
1378 victim->frameTarget = 0;
1382 rotatetarget = coords - victim->coords;
1383 Normalise(&rotatetarget);
1384 victim->targetyaw = -asin(0 - rotatetarget.x);
1385 victim->targetyaw *= 360 / 6.28;
1386 if (rotatetarget.z < 0)
1387 victim->targetyaw = 180 - victim->targetyaw;
1389 victim->targettilt2 = -asin(rotatetarget.y) * 360 / 6.28; //*-70;
1391 victim->lastattack3 = victim->lastattack2;
1392 victim->lastattack2 = victim->lastattack;
1393 victim->lastattack = victim->animTarget;
1395 victim->animTarget = sweepanim;
1396 victim->frameTarget = 0;
1400 rotatetarget = coords - victim->coords;
1401 Normalise(&rotatetarget);
1402 victim->targetyaw = -asin(0 - rotatetarget.x);
1403 victim->targetyaw *= 360 / 6.28;
1404 if (rotatetarget.z < 0)
1405 victim->targetyaw = 180 - victim->targetyaw;
1407 victim->targettilt2 = -asin(rotatetarget.y) * 360 / 6.28; //*-70;
1409 victim->lastattack3 = victim->lastattack2;
1410 victim->lastattack2 = victim->lastattack;
1411 victim->lastattack = victim->animTarget;
1416 victim->velocity = 0;
1418 if (aitype != playercontrolled)
1420 if (aitype != playercontrolled && Random() % 3 == 0 && escapednum < 2 && difficulty == 2)
1422 if (aitype != playercontrolled && Random() % 5 == 0 && escapednum < 2 && difficulty == 1)
1424 if (aitype != playercontrolled && Random() % 10 == 0 && escapednum < 2 && difficulty == 0)
1427 if (victim->id == 0 && animation[victim->animTarget].attack == reversal)
1434 void Person::DoDamage(float howmuch)
1436 // subtract health (temporary?)
1437 if (tutoriallevel != 1)
1438 damage += howmuch / power;
1441 damagedealt += howmuch / power;
1443 damagetaken += howmuch / power;
1446 if (id == 0 && (bonus == solidhit || bonus == twoxcombo || bonus == threexcombo || bonus == fourxcombo || bonus == megacombo))
1449 if (tutoriallevel != 1)
1450 permanentdamage += howmuch / 2 / power;
1451 if (tutoriallevel != 1)
1452 superpermanentdamage += howmuch / 4 / power;
1454 if (permanentdamage > damagetolerance / 2 && permanentdamage - howmuch < damagetolerance / 2 && Random() % 2)
1456 if ((permanentdamage > damagetolerance * .8 && Random() % 2 && !deathbleeding) || spurt)
1460 camerashake += howmuch / 100;
1461 if (id == 0 && ((howmuch > 50 && damage > damagetolerance / 2)))
1462 blackout = damage / damagetolerance;
1467 if (aitype == passivetype && damage < damagetolerance && ((tutoriallevel != 1 || cananger) && hostile))
1468 aitype = attacktypecutoff;
1469 if (tutoriallevel != 1 && aitype != playercontrolled && damage < damagetolerance && damage > damagetolerance * 2 / 3 && creature == rabbittype) {
1470 if (abs(Random() % 2) == 0) {
1471 aitype = gethelptype;
1474 aitype = attacktypecutoff;
1478 if (howmuch > damagetolerance * 50 && skeleton.free != 2) {
1481 for (int i = 0; i < skeleton.num_joints; i++) {
1482 if (skeleton.free) {
1483 flatvelocity2 = skeleton.joints[i].velocity;
1484 flatfacing2 = skeleton.joints[i].position * scale + coords;
1486 flatvelocity2 = velocity;
1487 flatfacing2 = DoRotation(DoRotation(DoRotation(skeleton.joints[i].position, 0, 0, tilt), tilt2, 0, 0), 0, yaw, 0) * scale + coords;
1489 flatvelocity2.x += (float)(abs(Random() % 100) - 50) / 10;
1490 flatvelocity2.y += (float)(abs(Random() % 100) - 50) / 10;
1491 flatvelocity2.z += (float)(abs(Random() % 100) - 50) / 10;
1492 Sprite::MakeSprite(bloodflamesprite, flatfacing2, flatvelocity2, 1, 1, 1, 3, 1);
1493 Sprite::MakeSprite(bloodsprite, flatfacing2, flatvelocity2, 1, 1, 1, .4, 1);
1494 Sprite::MakeSprite(cloudsprite, flatfacing2, flatvelocity2 * 0, .6, 0, 0, 1, .5);
1497 emit_sound_at(splattersound, coords);
1502 if (!dead && creature == wolftype) {
1503 award_bonus(0, Wolfbonus);
1510 if (tutoriallevel != 1 || id == 0)
1511 if (speechdelay <= 0 && !dead && aitype != playercontrolled) {
1512 int whichsound = -1;
1514 if (creature == wolftype) {
1515 int i = abs(Random() % 2);
1517 whichsound = snarlsound;
1519 whichsound = snarl2sound;
1521 if (creature == rabbittype) {
1522 int i = abs(Random() % 2);
1524 whichsound = rabbitpainsound;
1525 if (i == 1 && damage > damagetolerance)
1526 whichsound = rabbitpain1sound;
1529 if (whichsound != -1) {
1530 emit_sound_at(whichsound, coords);
1531 addEnvSound(coords);
1538 * calculate/animate head facing direction?
1540 void Person::DoHead()
1542 static XYZ rotatearound;
1544 static float lookspeed = 500;
1546 if (!freeze && !winfreeze) {
1549 targetheadyaw = (float)((int)((0 - yaw - targetheadyaw + 180) * 100) % 36000) / 100;
1550 targetheadpitch = (float)((int)(targetheadpitch * 100) % 36000) / 100;
1552 while (targetheadyaw > 180)targetheadyaw -= 360;
1553 while (targetheadyaw < -180)targetheadyaw += 360;
1555 if (targetheadyaw > 160)
1556 targetheadpitch = targetheadpitch * -1;
1557 if (targetheadyaw < -160)
1558 targetheadpitch = targetheadpitch * -1;
1559 if (targetheadyaw > 160)
1560 targetheadyaw = targetheadyaw - 180;
1561 if (targetheadyaw < -160)
1562 targetheadyaw = targetheadyaw + 180;
1564 if (targetheadpitch > 120)
1565 targetheadpitch = 120;
1566 if (targetheadpitch < -120)
1567 targetheadpitch = -120;
1568 if (targetheadyaw > 120)
1569 targetheadyaw = 120;
1570 if (targetheadyaw < -120)
1571 targetheadyaw = -120;
1574 targetheadpitch = 0;
1576 if (targetheadyaw > 80)
1578 if (targetheadyaw < -80)
1579 targetheadyaw = -80;
1580 if (targetheadpitch > 50)
1581 targetheadpitch = 50;
1582 if (targetheadpitch < -50)
1583 targetheadpitch = -50;
1586 if (abs(headyaw - targetheadyaw) < multiplier * lookspeed)
1587 headyaw = targetheadyaw;
1588 else if (headyaw > targetheadyaw) {
1589 headyaw -= multiplier * lookspeed;
1590 } else if (headyaw < targetheadyaw) {
1591 headyaw += multiplier * lookspeed;
1594 if (abs(headpitch - targetheadpitch) < multiplier * lookspeed / 2)
1595 headpitch = targetheadpitch;
1596 else if (headpitch > targetheadpitch) {
1597 headpitch -= multiplier * lookspeed / 2;
1598 } else if (headpitch < targetheadpitch) {
1599 headpitch += multiplier * lookspeed / 2;
1602 rotatearound = jointPos(neck);
1603 jointPos(head) = rotatearound + DoRotation(jointPos(head) - rotatearound, headpitch, 0, 0);
1607 if (animTarget != bounceidleanim && animTarget != fightidleanim && animTarget != wolfidle && animTarget != knifefightidleanim && animTarget != drawrightanim && animTarget != drawleftanim && animTarget != walkanim) {
1608 facing = DoRotation(facing, headpitch * .4, 0, 0);
1609 facing = DoRotation(facing, 0, headyaw * .4, 0);
1612 if (animTarget == bounceidleanim || animTarget == fightidleanim || animTarget == wolfidle || animTarget == knifefightidleanim || animTarget == drawrightanim || animTarget == drawleftanim) {
1613 facing = DoRotation(facing, headpitch * .8, 0, 0);
1614 facing = DoRotation(facing, 0, headyaw * .8, 0);
1617 if (animTarget == walkanim) {
1618 facing = DoRotation(facing, headpitch * .6, 0, 0);
1619 facing = DoRotation(facing, 0, headyaw * .6, 0);
1622 skeleton.specialforward[0] = facing;
1623 //skeleton.specialforward[0]=DoRotation(facing,0,yaw,0);
1624 for (int i = 0; i < skeleton.num_muscles; i++) {
1625 if (skeleton.muscles[i].visible && (skeleton.muscles[i].parent1->label == head || skeleton.muscles[i].parent2->label == head)) {
1626 skeleton.FindRotationMuscle(i, animTarget);
1633 * ragdolls character?
1635 void Person::RagDoll(bool checkcollision)
1640 if (!skeleton.free) {
1643 if (id == 0 && isFlip())
1650 facing = DoRotation(facing, 0, yaw, 0);
1652 skeleton.freetime = 0;
1654 skeleton.longdead = 0;
1657 skeleton.broken = 0;
1658 skeleton.spinny = 1;
1660 skeleton.freefall = 1;
1662 if (!isnormal(velocity.x)) velocity.x = 0;
1663 if (!isnormal(velocity.y)) velocity.y = 0;
1664 if (!isnormal(velocity.z)) velocity.z = 0;
1665 if (!isnormal(yaw)) yaw = 0;
1666 if (!isnormal(coords.x)) coords = 0;
1667 if (!isnormal(tilt)) tilt = 0;
1668 if (!isnormal(tilt2)) tilt2 = 0;
1670 for (int i = 0; i < skeleton.num_joints; i++) {
1671 skeleton.joints[i].delay = 0;
1672 skeleton.joints[i].locked = 0;
1673 skeleton.joints[i].position = DoRotation(DoRotation(DoRotation(skeleton.joints[i].position, 0, 0, tilt), tilt2, 0, 0), 0, yaw, 0);
1674 if (!isnormal(skeleton.joints[i].position.x)) skeleton.joints[i].position = DoRotation(skeleton.joints[i].position, 0, yaw, 0);
1675 if (!isnormal(skeleton.joints[i].position.x)) skeleton.joints[i].position = coords;
1676 skeleton.joints[i].position.y += .1;
1677 skeleton.joints[i].oldposition = skeleton.joints[i].position;
1678 skeleton.joints[i].realoldposition = skeleton.joints[i].position * scale + coords;
1681 for (int i = 0; i < skeleton.num_joints; i++) {
1682 skeleton.joints[i].velocity = 0;
1683 skeleton.joints[i].velchange = 0;
1685 skeleton.DoConstraints(&coords, &scale);
1686 if (animation[animCurrent].height == lowheight || animation[animTarget].height == lowheight) {
1687 skeleton.DoConstraints(&coords, &scale);
1688 skeleton.DoConstraints(&coords, &scale);
1689 skeleton.DoConstraints(&coords, &scale);
1690 skeleton.DoConstraints(&coords, &scale);
1693 speed = animation[animTarget].speed[frameTarget] * 2;
1694 if (animation[animCurrent].speed[frameCurrent] > animation[animTarget].speed[frameTarget]) {
1695 speed = animation[animCurrent].speed[frameCurrent] * 2;
1698 speed = transspeed * 2;
1702 for (int i = 0; i < skeleton.num_joints; i++) {
1703 if ((animation[animCurrent].attack != reversed || animCurrent == swordslashreversedanim) && animCurrent != rabbitkickanim && !isLanding() && !wasLanding() && animation[animCurrent].height == animation[animTarget].height)
1704 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);
1706 skeleton.joints[i].velocity = velocity / scale + facing * 5;
1707 change.x = (float)(Random() % 100) / 100;
1708 change.y = (float)(Random() % 100) / 100;
1709 change.z = (float)(Random() % 100) / 100;
1710 skeleton.joints[i].velocity += change;
1711 skeleton.joints[abs(Random() % skeleton.num_joints)].velocity -= change;
1713 change.x = (float)(Random() % 100) / 100;
1714 change.y = (float)(Random() % 100) / 100;
1715 change.z = (float)(Random() % 100) / 100;
1716 skeleton.joints[i].velchange += change;
1717 skeleton.joints[abs(Random() % skeleton.num_joints)].velchange -= change;
1720 if (checkcollision) {
1727 for (j = 0; j < skeleton.num_joints; j++) {
1728 average += skeleton.joints[j].position;
1732 coords += average * scale;
1733 for (j = 0; j < skeleton.num_joints; j++) {
1734 skeleton.joints[j].position -= average;
1737 whichpatchx = coords.x / (terrain.size / subdivision * terrain.scale);
1738 whichpatchz = coords.z / (terrain.size / subdivision * terrain.scale);
1739 if (terrain.patchobjectnum[whichpatchx][whichpatchz])
1740 for (l = 0; l < terrain.patchobjectnum[whichpatchx][whichpatchz]; l++) {
1741 i = terrain.patchobjects[whichpatchx][whichpatchz][l];
1744 if (SphereCheck(&lowpoint, 3, &colpoint, &objects.position[i], &objects.yaw[i], &objects.model[i]) != -1) {
1745 coords.x = lowpoint.x;
1746 coords.z = lowpoint.z;
1755 for (int i = 0; i < skeleton.num_joints; i++) {
1756 velocity += skeleton.joints[i].velocity * scale;
1758 velocity /= skeleton.num_joints;
1761 if (Random() % 2 == 0) {
1762 if (weaponactive != -1 && animTarget != rabbitkickanim && num_weapons > 0) {
1763 weapons[weaponids[0]].drop(jointVel(righthand) * scale * -.3, jointVel(righthand) * scale);
1764 weapons[weaponids[0]].velocity.x += .01;
1767 weaponids[0] = weaponids[num_weapons];
1768 if (weaponstuck == num_weapons)
1772 for (unsigned i = 0; i < Person::players.size(); i++) {
1773 Person::players[i]->wentforweapon = 0;
1778 animTarget = bounceidleanim;
1779 animCurrent = bounceidleanim;
1789 void Person::FootLand(int which, float opacity)
1791 static XYZ terrainlight;
1792 static XYZ footvel, footpoint;
1793 if (opacity >= 1 || skiddelay <= 0)
1797 footpoint = DoRotation(jointPos(leftfoot), 0, yaw, 0) * scale + coords;
1799 footpoint = DoRotation(jointPos(rightfoot), 0, yaw, 0) * scale + coords;
1800 //footpoint.y=coords.y;
1801 if (distsq(&footpoint, &viewer))
1802 Sprite::MakeSprite(cloudsprite, footpoint, footvel, 1, 1, 1, .5, .2 * opacity);
1803 } else if (environment == snowyenvironment && onterrain && terrain.getOpacity(coords.x, coords.z) < .2) {
1804 footvel = velocity / 5;
1808 footpoint = DoRotation(jointPos(leftfoot), 0, yaw, 0) * scale + coords;
1810 footpoint = DoRotation(jointPos(rightfoot), 0, yaw, 0) * scale + coords;
1811 footpoint.y = terrain.getHeight(footpoint.x, footpoint.z);
1812 terrainlight = terrain.getLighting(footpoint.x, footpoint.z);
1813 if (distsq(&footpoint, &viewer) < viewdistance * viewdistance / 4)
1814 Sprite::MakeSprite(cloudsprite, footpoint, footvel * .6, terrainlight.x, terrainlight.y, terrainlight.z, .5, .7 * opacity);
1815 if (opacity >= 1 || detail == 2)
1817 if (distsq(&footpoint, &viewer) < viewdistance * viewdistance / 4)
1818 terrain.MakeDecal(footprintdecal, footpoint, .2, 1 * opacity, yaw);
1819 } else if (environment == grassyenvironment && onterrain && terrain.getOpacity(coords.x, coords.z) < .2) {
1820 footvel = velocity / 5;
1824 footpoint = DoRotation(jointPos(leftfoot), 0, yaw, 0) * scale + coords;
1826 footpoint = DoRotation(jointPos(rightfoot), 0, yaw, 0) * scale + coords;
1827 footpoint.y = terrain.getHeight(footpoint.x, footpoint.z);
1828 terrainlight = terrain.getLighting(footpoint.x, footpoint.z);
1829 if (distsq(&footpoint, &viewer) < viewdistance * viewdistance / 4)
1830 Sprite::MakeSprite(cloudsprite, footpoint, footvel * .6, terrainlight.x * 90 / 255, terrainlight.y * 70 / 255, terrainlight.z * 8 / 255, .5, .5 * opacity);
1831 } else if (environment == desertenvironment && onterrain && terrain.getOpacity(coords.x, coords.z) < .2) {
1832 footvel = velocity / 5;
1836 footpoint = DoRotation(jointPos(leftfoot), 0, yaw, 0) * scale + coords;
1838 footpoint = DoRotation(jointPos(rightfoot), 0, yaw, 0) * scale + coords;
1839 footpoint.y = terrain.getHeight(footpoint.x, footpoint.z);
1840 terrainlight = terrain.getLighting(footpoint.x, footpoint.z);
1841 if (distsq(&footpoint, &viewer) < viewdistance * viewdistance / 4)
1842 Sprite::MakeSprite(cloudsprite, footpoint, footvel * .6, terrainlight.x * 190 / 255, terrainlight.y * 170 / 255, terrainlight.z * 108 / 255, .5, .7 * opacity);
1843 if (opacity >= 1 || detail == 2)
1845 if (distsq(&footpoint, &viewer) < viewdistance * viewdistance / 4)
1846 terrain.MakeDecal(footprintdecal, footpoint, .2, .25 * opacity, yaw);
1847 } else if (isLanding() || animTarget == jumpupanim || isLandhard()) {
1848 footvel = velocity / 5;
1852 footpoint = DoRotation(jointPos(leftfoot), 0, yaw, 0) * scale + coords;
1854 footpoint = DoRotation(jointPos(rightfoot), 0, yaw, 0) * scale + coords;
1855 //footpoint.y=coords.y;
1856 if (distsq(&footpoint, &viewer) < viewdistance * viewdistance / 4)
1857 Sprite::MakeSprite(cloudsprite, footpoint, footvel * .6, 1, 1, 1, .5, .2 * opacity);
1862 * make a puff effect at a body part (dust effect?)
1864 void Person::Puff(int whichlabel)
1866 static XYZ footvel, footpoint;
1869 footpoint = DoRotation(jointPos(whichlabel), 0, yaw, 0) * scale + coords;
1870 Sprite::MakeSprite(cloudimpactsprite, footpoint, footvel, 1, 1, 1, .9, .3);
1874 * I think I added this in an attempt to clean up code
1876 void Person::setAnimation(int animation)
1878 animTarget = animation;
1887 void Person::DoAnimations()
1889 if (!skeleton.free) {
1890 static float oldtarget;
1892 if (isIdle() && animCurrent != getIdle())
1893 normalsupdatedelay = 0;
1895 if (animTarget == tempanim || animCurrent == tempanim) {
1896 animation[tempanim] = tempanimation;
1898 if (animTarget == jumpupanim || animTarget == jumpdownanim || isFlip()) {
1904 vel[0] = velocity.x;
1905 vel[1] = velocity.y;
1906 vel[2] = velocity.z;
1909 OPENAL_3D_SetAttributes(channels[whooshsound], gLoc, vel);
1910 OPENAL_SetVolume(channels[whooshsound], 64 * findLength(&velocity) / 5);
1912 if (((velocity.y < -15) || (crouchkeydown && velocity.y < -8)) && abs(velocity.y) * 4 > fast_sqrt(velocity.x * velocity.x * velocity.z * velocity.z))
1914 if (!crouchkeydown && velocity.y >= -15)
1917 if ((animCurrent == jumpupanim || animTarget == jumpdownanim)/*&&velocity.y<40*/ && !isFlip() && (!isLanding() && !isLandhard()) && ((crouchkeydown && !crouchtogglekeydown))) {
1922 targfacing = DoRotation(targfacing, 0, targetyaw, 0);
1924 if (normaldotproduct(targfacing, velocity) >= -.3)
1925 animTarget = flipanim;
1927 animTarget = backflipanim;
1928 crouchtogglekeydown = 1;
1936 if (animation[animTarget].attack != reversed)
1938 if (!crouchkeydown || (isLanding() || isLandhard()) || (wasLanding() || wasLandhard())) {
1939 crouchtogglekeydown = 0;
1940 if (aitype == playercontrolled)
1943 if (!crouchtogglekeydown && animation[animTarget].attack == reversed && aitype == playercontrolled && (escapednum < 2 || reversaltrain))
1946 crouchtogglekeydown = 1;
1950 if (animation[animTarget].attack || animCurrent == getupfrombackanim || animCurrent == getupfromfrontanim) {
1952 normalsupdatedelay = 0;
1956 if (animTarget == rollanim && frameTarget == 3 && onfire) {
1958 emit_sound_at(fireendsound, coords);
1959 pause_sound(stream_firesound);
1963 if (animTarget == rabbittacklinganim && frameTarget == 1) {
1964 if (victim->aitype == attacktypecutoff && victim->stunned <= 0 && victim->surprised <= 0 && victim->id != 0)
1966 if (animTarget == rabbittacklinganim && frameTarget == 1 && !victim->isCrouch() && victim->animTarget != backhandspringanim) {
1967 if (normaldotproduct(victim->facing, facing) > 0)
1968 victim->animTarget = rabbittackledbackanim;
1970 victim->animTarget = rabbittackledfrontanim;
1971 victim->frameTarget = 2;
1974 victim->targetyaw = yaw;
1975 if (victim->aitype == gethelptype)
1976 victim->DoDamage(victim->damagetolerance - victim->damage);
1977 //victim->DoDamage(30);
1978 if (creature == wolftype) {
1980 emit_sound_at(clawslicesound, victim->coords);
1982 victim->DoBloodBig(1 / victim->armorhead, 210);
1984 award_bonus(id, TackleBonus,
1985 victim->aitype == gethelptype ? 50 : 0);
1989 if (!drawtogglekeydown && drawkeydown && (weaponactive == -1 || num_weapons == 1) && (animation[animTarget].label[frameTarget] || (animTarget != animCurrent && animCurrent == rollanim)) && num_weapons > 0 && creature != wolftype) {
1990 if (weapons[weaponids[0]].getType() == knife) {
1991 if (weaponactive == -1)
1993 else if (weaponactive == 0)
1996 if (weaponactive == -1) {
1997 emit_sound_at(knifesheathesound, coords);
1999 if (weaponactive != -1) {
2000 emit_sound_at(knifedrawsound, coords, 128);
2003 drawtogglekeydown = 1;
2006 if (tutoriallevel != 1 || id == 0)
2007 if ((animation[animTarget].label[frameTarget] && (animation[animTarget].label[frameTarget] < 5 || animation[animTarget].label[frameTarget] == 8))/*||(animTarget==rollanim&&frameTarget==animation[rollanim].numframes-1)*/) {
2010 if (terrain.getOpacity(coords.x, coords.z) < .2) {
2011 if (animation[animTarget].label[frameTarget] == 1)
2012 whichsound = footstepsound;
2014 whichsound = footstepsound2;
2015 if (animation[animTarget].label[frameTarget] == 1)
2017 if (animation[animTarget].label[frameTarget] == 2)
2019 if (animation[animTarget].label[frameTarget] == 3 && isRun()) {
2025 if (terrain.getOpacity(coords.x, coords.z) >= .2) {
2026 if (animation[animTarget].label[frameTarget] == 1)
2027 whichsound = footstepsound3;
2029 whichsound = footstepsound4;
2033 if (animation[animTarget].label[frameTarget] == 1)
2034 whichsound = footstepsound3;
2036 whichsound = footstepsound4;
2038 if (animation[animTarget].label[frameTarget] == 4 && (weaponactive == -1 || (animTarget != knifeslashstartanim && animTarget != knifethrowanim && animTarget != crouchstabanim && animTarget != swordgroundstabanim && animTarget != knifefollowanim))) {
2039 if (animation[animTarget].attack != neutral) {
2040 unsigned r = abs(Random() % 3);
2042 whichsound = lowwhooshsound;
2044 whichsound = midwhooshsound;
2046 whichsound = highwhooshsound;
2048 if (animation[animTarget].attack == neutral)
2049 whichsound = movewhooshsound;
2050 } else if (animation[animTarget].label[frameTarget] == 4)
2051 whichsound = knifeswishsound;
2052 if (animation[animTarget].label[frameTarget] == 8 && tutoriallevel != 1)
2053 whichsound = landsound2;
2055 emit_sound_at(whichsound, coords, 256.);
2058 if (whichsound == footstepsound || whichsound == footstepsound2 || whichsound == footstepsound3 || whichsound == footstepsound4) {
2059 if (animTarget == wolfrunninganim || animTarget == rabbitrunninganim) {
2060 addEnvSound(coords, 15);
2062 addEnvSound(coords, 6);
2066 if (animation[animTarget].label[frameTarget] == 3) {
2068 emit_sound_at(whichsound, coords, 128.);
2073 if (tutoriallevel != 1 || id == 0)
2074 if (speechdelay <= 0)
2075 if (animTarget != crouchstabanim && animTarget != swordgroundstabanim && animTarget != staffgroundsmashanim)
2076 if ((animation[animTarget].label[frameTarget] && (animation[animTarget].label[frameTarget] < 5 || animation[animTarget].label[frameTarget] == 8))/*||(animTarget==rollanim&&frameTarget==animation[rollanim].numframes-1)*/) {
2077 int whichsound = -1;
2078 if (animation[animTarget].label[frameTarget] == 4 && aitype != playercontrolled) {
2079 if (animation[animTarget].attack != neutral) {
2080 unsigned r = abs(Random() % 4);
2081 if (creature == rabbittype) {
2082 if (r == 0) whichsound = rabbitattacksound;
2083 if (r == 1) whichsound = rabbitattack2sound;
2084 if (r == 2) whichsound = rabbitattack3sound;
2085 if (r == 3) whichsound = rabbitattack4sound;
2087 if (creature == wolftype) {
2088 if (r == 0) whichsound = barksound;
2089 if (r == 1) whichsound = bark2sound;
2090 if (r == 2) whichsound = bark3sound;
2091 if (r == 3) whichsound = barkgrowlsound;
2097 if (whichsound != -1) {
2098 emit_sound_at(whichsound, coords);
2104 if ((!wasLanding() && !wasLandhard()) && animCurrent != getIdle() && (isLanding() || isLandhard())) {
2110 currentoffset = targetoffset;
2111 frameTarget = frameCurrent;
2112 animCurrent = animTarget;
2115 if (animTarget == removeknifeanim && animation[animTarget].label[frameCurrent] == 5) {
2116 for (unsigned i = 0; i < weapons.size(); i++) {
2117 if (weapons[i].owner == -1)
2118 if (distsqflat(&coords, &weapons[i].position) < 4 && weaponactive == -1) {
2119 if (distsq(&coords, &weapons[i].position) >= 1) {
2120 if (weapons[i].getType() != staff) {
2121 emit_sound_at(knifedrawsound, coords, 128.);
2130 if (animTarget == crouchremoveknifeanim && animation[animTarget].label[frameCurrent] == 5) {
2131 for (unsigned i = 0; i < weapons.size(); i++) {
2132 bool willwork = true;
2133 if (weapons[i].owner != -1)
2134 if (Person::players[weapons[i].owner]->weaponstuck != -1)
2135 if (Person::players[weapons[i].owner]->weaponids[Person::players[weapons[i].owner]->weaponstuck] == int(i))
2136 if (Person::players[weapons[i].owner]->num_weapons > 1)
2138 if ((weapons[i].owner == -1) || (hasvictim && (weapons[i].owner == int(victim->id)) && victim->skeleton.free))
2139 if (willwork && distsqflat(&coords, &weapons[i].position) < 3 && weaponactive == -1) {
2140 if (distsq(&coords, &weapons[i].position) < 1 || hasvictim) {
2141 bool fleshstuck = false;
2142 if (weapons[i].owner != -1)
2143 if (victim->weaponstuck != -1) {
2144 if (victim->weaponids[victim->weaponstuck] == int(i)) {
2149 emit_sound_at(fleshstabremovesound, coords, 128.);
2151 if (weapons[i].getType() != staff) {
2152 emit_sound_at(knifedrawsound, coords, 128.);
2155 if (weapons[i].owner != -1) {
2156 victim = Person::players[weapons[i].owner];
2157 if (victim->num_weapons == 1)
2158 victim->num_weapons = 0;
2160 victim->num_weapons = 1;
2162 //victim->weaponactive=-1;
2163 victim->skeleton.longdead = 0;
2164 victim->skeleton.free = 1;
2165 victim->skeleton.broken = 0;
2167 for (int j = 0; j < victim->skeleton.num_joints; j++) {
2168 victim->skeleton.joints[j].velchange = 0;
2169 victim->skeleton.joints[j].locked = 0;
2175 Normalise(&relative);
2176 XYZ footvel, footpoint;
2178 footpoint = weapons[i].position;
2179 if (victim->weaponstuck != -1) {
2180 if (victim->weaponids[victim->weaponstuck] == int(i)) {
2182 Sprite::MakeSprite(cloudimpactsprite, footpoint, footvel, 1, 0, 0, .8, .3);
2183 weapons[i].bloody = 2;
2184 weapons[i].blooddrip = 5;
2185 victim->weaponstuck = -1;
2188 if (victim->num_weapons > 0) {
2189 if (victim->weaponstuck != 0 && victim->weaponstuck != -1)
2190 victim->weaponstuck = 0;
2191 if (victim->weaponids[0] == int(i))
2192 victim->weaponids[0] = victim->weaponids[victim->num_weapons];
2195 victim->jointVel(abdomen) += relative * 6;
2196 victim->jointVel(neck) += relative * 6;
2197 victim->jointVel(rightshoulder) += relative * 6;
2198 victim->jointVel(leftshoulder) += relative * 6;
2206 if (animCurrent == drawleftanim && animation[animTarget].label[frameCurrent] == 5) {
2207 if (weaponactive == -1)
2209 else if (weaponactive == 0) {
2211 if (num_weapons == 2) {
2213 buffer = weaponids[0];
2214 weaponids[0] = weaponids[1];
2215 weaponids[1] = buffer;
2218 if (weaponactive == -1) {
2219 emit_sound_at(knifesheathesound, coords, 128.);
2221 if (weaponactive != -1) {
2222 emit_sound_at(knifedrawsound, coords, 128.);
2227 if ((animCurrent == walljumprightkickanim && animTarget == walljumprightkickanim) || (animCurrent == walljumpleftkickanim && animTarget == walljumpleftkickanim)) {
2228 XYZ rotatetarget = DoRotation(skeleton.forward, 0, yaw, 0);
2229 Normalise(&rotatetarget);
2230 targetyaw = -asin(0 - rotatetarget.x);
2231 targetyaw *= 360 / 6.28;
2232 if (rotatetarget.z < 0)
2233 targetyaw = 180 - targetyaw;
2235 if (animTarget == walljumprightkickanim)
2237 if (animTarget == walljumpleftkickanim)
2243 if ((animTarget == rabbitrunninganim || animTarget == wolfrunninganim) && frameTarget == 3 && (jumpkeydown || attackkeydown || id != 0))
2246 if (distsq(&victim->coords, &/*Person::players[i]->*/coords) < 5 && victim->aitype == gethelptype && (attackkeydown) && !victim->skeleton.free && victim->isRun() && victim->runninghowlong >= 1)
2251 if ((animTarget == rabbitrunninganim || animTarget == wolfrunninganim) && id == 0) {
2252 animTarget = rabbittackleanim;
2254 emit_sound_at(jumpsound, coords);
2262 targetloc = velocity;
2263 Normalise(&targetloc);
2264 targetloc += coords;
2265 for (unsigned i = 0; i < Person::players.size(); i++) {
2267 if (distsq(&targetloc, &Person::players[i]->coords) < closestdist || closestdist == 0) {
2268 closestdist = distsq(&targetloc, &Person::players[i]->coords);
2272 if (closestid != -1)
2273 if (closestdist < 5 && !Person::players[closestid]->dead && animation[Person::players[closestid]->animTarget].height != lowheight && Person::players[closestid]->animTarget != backhandspringanim) {
2275 victim = Person::players[closestid];
2276 coords = victim->coords;
2277 animCurrent = rabbittacklinganim;
2278 animTarget = rabbittacklinganim;
2282 if (coords.z != victim->coords.z || coords.x != victim->coords.x) {
2283 rotatetarget = coords - victim->coords;
2284 Normalise(&rotatetarget);
2285 targetyaw = -asin(0 - rotatetarget.x);
2286 targetyaw *= 360 / 6.28;
2287 if (rotatetarget.z < 0)
2288 targetyaw = 180 - targetyaw;
2290 if (animTarget != rabbitrunninganim) {
2291 emit_sound_at(jumpsound, coords, 128.);
2297 float damagemult = 1 * power;
2298 if (creature == wolftype)
2299 damagemult = 2.5 * power;
2301 damagemult /= victim->damagetolerance / 200;
2303 if ((animation[animTarget].attack == normalattack || animTarget == walljumprightkickanim || animTarget == walljumpleftkickanim) && (!feint) && (victim->skeleton.free != 2 || animTarget == killanim || animTarget == dropkickanim || animTarget == crouchstabanim || animTarget == swordgroundstabanim || animTarget == staffgroundsmashanim)) {
2304 if (animTarget == spinkickanim && animation[animTarget].label[frameCurrent] == 5) {
2305 if (distsq(&coords, &victim->coords) < (scale * 5) * (scale * 5) * 3 && 3 && animation[victim->animTarget].height != lowheight) {
2309 if (Random() % 2 || creature == wolftype) {
2312 if (creature == wolftype)
2315 if (tutoriallevel != 1) {
2316 emit_sound_at(heavyimpactsound, victim->coords, 128.);
2318 if (creature == wolftype) {
2319 emit_sound_at(clawslicesound, victim->coords, 128.);
2321 victim->DoBloodBig(2 / victim->armorhead, 175);
2325 relative = victim->coords - coords;
2327 Normalise(&relative);
2328 relative = DoRotation(relative, 0, -90, 0);
2329 for (int i = 0; i < victim->skeleton.num_joints; i++) {
2330 victim->skeleton.joints[i].velocity += relative * damagemult * 40;
2332 victim->jointVel(head) += relative * damagemult * 200;
2335 victim->DoDamage(damagemult * 100 / victim->protectionhead);
2341 if (animTarget == wolfslapanim && animation[animTarget].label[frameCurrent] == 5) {
2342 if (distsq(&coords, &victim->coords) < (scale * 5) * (scale * 5) * 3 && 3 && animation[victim->animTarget].height != lowheight) {
2346 if (Random() % 2 || creature == wolftype) {
2348 if (creature == wolftype)
2351 emit_sound_at(whooshhitsound, victim->coords);
2352 if (creature == wolftype) {
2353 emit_sound_at(clawslicesound, victim->coords, 128.);
2355 victim->DoBloodBig(2, 175);
2359 relative = victim->coords - coords;
2361 Normalise(&relative);
2363 Normalise(&relative);
2364 relative = DoRotation(relative, 0, 90, 0);
2365 for (int i = 0; i < victim->skeleton.num_joints; i++) {
2366 victim->skeleton.joints[i].velocity += relative * damagemult * 20;
2368 victim->jointVel(head) += relative * damagemult * 100;
2371 victim->DoDamage(damagemult * 50 / victim->protectionhead);
2375 if (animTarget == walljumprightkickanim && animation[animTarget].label[frameCurrent] == 5) {
2376 if (distsq(&coords, &victim->coords) < (scale * 5) * (scale * 5) * 3 && animation[victim->animTarget].height != lowheight) {
2382 if (tutoriallevel != 1) {
2383 emit_sound_at(heavyimpactsound, victim->coords, 160.);
2385 if (creature == wolftype) {
2386 emit_sound_at(clawslicesound, victim->coords, 128.);
2388 victim->DoBloodBig(2 / victim->armorhead, 175);
2394 Normalise(&relative);
2395 relative = DoRotation(relative, 0, -90, 0);
2396 for (int i = 0; i < victim->skeleton.num_joints; i++) {
2397 victim->skeleton.joints[i].velocity += relative * damagemult * 40;
2399 victim->jointVel(head) += relative * damagemult * 200;
2402 victim->DoDamage(damagemult * 150 / victim->protectionhead);
2404 if (victim->damage > victim->damagetolerance)
2405 award_bonus(id, style);
2411 if (animTarget == walljumpleftkickanim && animation[animTarget].label[frameCurrent] == 5) {
2412 if (distsq(&coords, &victim->coords) < (scale * 5) * (scale * 5) * 3 && animation[victim->animTarget].height != lowheight) {
2418 if (tutoriallevel != 1) {
2419 emit_sound_at(heavyimpactsound, victim->coords, 160.);
2421 if (creature == wolftype) {
2422 emit_sound_at(clawslicesound, victim->coords, 128.);
2424 victim->DoBloodBig(2 / victim->armorhead, 175);
2430 Normalise(&relative);
2431 relative = DoRotation(relative, 0, 90, 0);
2432 for (int i = 0; i < victim->skeleton.num_joints; i++) {
2433 victim->skeleton.joints[i].velocity += relative * damagemult * 40;
2435 victim->jointVel(head) += relative * damagemult * 200;
2438 victim->DoDamage(damagemult * 150 / victim->protectionhead);
2440 if (victim->damage > victim->damagetolerance)
2441 award_bonus(id, style);
2447 if (animTarget == blockhighleftstrikeanim && animation[animTarget].label[frameCurrent] == 5) {
2448 if (distsq(&coords, &victim->coords) < (scale * 5) * (scale * 5) * 3 && animation[victim->animTarget].height != lowheight) {
2456 emit_sound_at(whooshhitsound, victim->coords);
2459 relative = victim->coords - coords;
2461 Normalise(&relative);
2462 for (int i = 0; i < victim->skeleton.num_joints; i++) {
2463 victim->skeleton.joints[i].velocity += relative * damagemult * 30;
2465 victim->jointVel(head) += relative * damagemult * 100;
2468 victim->DoDamage(damagemult * 50 / victim->protectionhead);
2472 if (animTarget == killanim && animation[animTarget].label[frameCurrent] == 8) {
2473 if (distsq(&coords, &victim->coords) < (scale * 5) * (scale * 5) * 3 && victim->dead) {
2477 emit_sound_at(whooshhitsound, victim->coords, 128.);
2479 victim->skeleton.longdead = 0;
2480 victim->skeleton.free = 1;
2481 victim->skeleton.broken = 0;
2482 victim->skeleton.spinny = 1;
2484 for (int i = 0; i < victim->skeleton.num_joints; i++) {
2485 victim->skeleton.joints[i].velchange = 0;
2486 victim->skeleton.joints[i].delay = 0;
2487 victim->skeleton.joints[i].locked = 0;
2488 //victim->skeleton.joints[i].velocity=0;
2494 Normalise(&relative);
2495 for (int i = 0; i < victim->skeleton.num_joints; i++) {
2496 victim->skeleton.joints[i].velocity.y = relative.y * 10;
2497 victim->skeleton.joints[i].position.y += relative.y * .3;
2498 victim->skeleton.joints[i].oldposition.y += relative.y * .3;
2499 victim->skeleton.joints[i].realoldposition.y += relative.y * .3;
2501 victim->Puff(abdomen);
2502 victim->jointVel(abdomen).y = relative.y * 400;
2506 if (animTarget == killanim && animation[animTarget].label[frameCurrent] == 5) {
2507 if (distsq(&coords, &victim->coords) < (scale * 5) * (scale * 5) * 9 && victim->dead) {
2511 if (tutoriallevel != 1) {
2512 emit_sound_at(heavyimpactsound, coords, 128.);
2515 relative = victim->coords - coords;
2517 Normalise(&relative);
2518 for (int i = 0; i < victim->skeleton.num_joints; i++) {
2519 victim->skeleton.joints[i].velocity += relative * damagemult * 90;
2521 victim->Puff(abdomen);
2522 if (victim->dead != 2 && victim->permanentdamage > victim->damagetolerance - 250 && autoslomo) {
2526 victim->DoDamage(damagemult * 500 / victim->protectionhigh);
2527 victim->jointVel(abdomen) += relative * damagemult * 300;
2531 if (animTarget == dropkickanim && animation[animTarget].label[frameCurrent] == 7) {
2532 if (distsq(&coords, &victim->coords) < (scale * 5) * (scale * 5) * 9 && victim->skeleton.free) {
2536 if (tutoriallevel != 1) {
2537 emit_sound_at(thudsound, coords);
2540 victim->skeleton.longdead = 0;
2541 victim->skeleton.free = 1;
2542 victim->skeleton.broken = 0;
2543 victim->skeleton.spinny = 1;
2545 for (int i = 0; i < victim->skeleton.num_joints; i++) {
2546 victim->skeleton.joints[i].velchange = 0;
2547 //victim->skeleton.joints[i].delay=0;
2548 victim->skeleton.joints[i].locked = 0;
2551 relative = victim->coords - coords;
2552 Normalise(&relative);
2554 Normalise(&relative);
2555 for (int i = 0; i < victim->skeleton.num_joints; i++) {
2556 victim->skeleton.joints[i].velocity += relative * damagemult * 20;
2561 victim->Puff(abdomen);
2562 victim->DoDamage(damagemult * 20 / victim->protectionhigh);
2563 victim->jointVel(abdomen) += relative * damagemult * 200;
2572 if ((animTarget == crouchstabanim || animTarget == swordgroundstabanim) && animation[animTarget].label[frameCurrent] == 5) {
2575 if (!victim->skeleton.free)
2579 terrain.MakeDecal(blooddecalfast, (weapons[weaponids[weaponactive]].tippoint * .8 + weapons[weaponids[weaponactive]].position * .2), .08, .6, Random() % 360);
2580 emit_sound_at(knifesheathesound, coords, 128.);
2583 if (victim && hasvictim) {
2584 if (distsq(&coords, &victim->coords) < (scale * 5) * (scale * 5) * 3) {
2586 XYZ where, startpoint, endpoint, movepoint, colpoint;
2587 float rotationpoint;
2589 if (weapons[weaponids[weaponactive]].getType() == knife) {
2590 where = (weapons[weaponids[weaponactive]].tippoint * .6 + weapons[weaponids[weaponactive]].position * .4);
2591 where -= victim->coords;
2592 if (!victim->skeleton.free)
2593 where = DoRotation(where, 0, -victim->yaw, 0);
2596 startpoint.y += 100;
2600 if (weapons[weaponids[weaponactive]].getType() == sword) {
2601 where = weapons[weaponids[weaponactive]].position;
2602 where -= victim->coords;
2603 if (!victim->skeleton.free)
2604 where = DoRotation(where, 0, -victim->yaw, 0);
2606 where = weapons[weaponids[weaponactive]].tippoint;
2607 where -= victim->coords;
2608 if (!victim->skeleton.free)
2609 where = DoRotation(where, 0, -victim->yaw, 0);
2612 if (weapons[weaponids[weaponactive]].getType() == staff) {
2613 where = weapons[weaponids[weaponactive]].position;
2614 where -= victim->coords;
2615 if (!victim->skeleton.free)
2616 where = DoRotation(where, 0, -victim->yaw, 0);
2618 where = weapons[weaponids[weaponactive]].tippoint;
2619 where -= victim->coords;
2620 if (!victim->skeleton.free)
2621 where = DoRotation(where, 0, -victim->yaw, 0);
2626 whichtri = victim->skeleton.drawmodel.LineCheck(&startpoint, &endpoint, &colpoint, &movepoint, &rotationpoint);
2628 if (whichtri != -1) {
2629 if (victim->dead != 2) {
2630 victim->DoDamage(abs((victim->damagetolerance - victim->permanentdamage) * 2));
2632 award_bonus(id, FinishedBonus);
2635 weapons[weaponids[weaponactive]].bloody = 2;
2637 victim->skeleton.longdead = 0;
2638 victim->skeleton.free = 1;
2639 victim->skeleton.broken = 0;
2641 for (int i = 0; i < victim->skeleton.num_joints; i++) {
2642 victim->skeleton.joints[i].velchange = 0;
2643 victim->skeleton.joints[i].locked = 0;
2644 //victim->skeleton.joints[i].velocity=0;
2646 emit_sound_at(fleshstabsound, coords, 128);
2649 if (whichtri != -1 || weapons[weaponids[weaponactive]].bloody) {
2650 weapons[weaponids[weaponactive]].blooddrip += 5;
2651 weapons[weaponids[weaponactive]].blooddripdelay = 0;
2653 if (whichtri == -1) {
2655 emit_sound_at(knifesheathesound, coords, 128.);
2661 if ((animTarget == crouchstabanim || animTarget == swordgroundstabanim) && animation[animTarget].label[frameCurrent] == 6) {
2663 emit_sound_at(knifedrawsound, coords, 128);
2666 if (victim && hasvictim) {
2667 XYZ footvel, footpoint;
2669 emit_sound_at(fleshstabremovesound, coords, 128.);
2672 footpoint = (weapons[weaponids[weaponactive]].tippoint * .8 + weapons[weaponids[weaponactive]].position * .2);
2674 if (weapons[weaponids[weaponactive]].getType() == sword) {
2675 XYZ where, startpoint, endpoint, movepoint;
2676 float rotationpoint;
2679 where = weapons[weaponids[weaponactive]].position;
2680 where -= victim->coords;
2681 if (!victim->skeleton.free)
2682 where = DoRotation(where, 0, -victim->yaw, 0);
2684 where = weapons[weaponids[weaponactive]].tippoint;
2685 where -= victim->coords;
2686 if (!victim->skeleton.free)
2687 where = DoRotation(where, 0, -victim->yaw, 0);
2692 whichtri = victim->skeleton.drawmodel.LineCheck(&startpoint, &endpoint, &footpoint, &movepoint, &rotationpoint);
2693 footpoint += victim->coords;
2695 if (whichtri == -1) {
2696 footpoint = (weapons[weaponids[weaponactive]].tippoint * .8 + weapons[weaponids[weaponactive]].position * .2);
2699 if (weapons[weaponids[weaponactive]].getType() == staff) {
2700 XYZ where, startpoint, endpoint, movepoint;
2701 float rotationpoint;
2704 where = weapons[weaponids[weaponactive]].position;
2705 where -= victim->coords;
2706 if (!victim->skeleton.free)
2707 where = DoRotation(where, 0, -victim->yaw, 0);
2709 where = weapons[weaponids[weaponactive]].tippoint;
2710 where -= victim->coords;
2711 if (!victim->skeleton.free)
2712 where = DoRotation(where, 0, -victim->yaw, 0);
2717 whichtri = victim->skeleton.drawmodel.LineCheck(&startpoint, &endpoint, &footpoint, &movepoint, &rotationpoint);
2718 footpoint += victim->coords;
2720 if (whichtri == -1) {
2721 footpoint = (weapons[weaponids[weaponactive]].tippoint * .8 + weapons[weaponids[weaponactive]].position * .2);
2724 hasvictim = victim->DoBloodBigWhere(2, 220, footpoint);
2726 if (distsq(&coords, &victim->coords) < (scale * 5) * (scale * 5) * 3) {
2727 victim->skeleton.longdead = 0;
2728 victim->skeleton.free = 1;
2729 victim->skeleton.broken = 0;
2731 for (int i = 0; i < victim->skeleton.num_joints; i++) {
2732 victim->skeleton.joints[i].velchange = 0;
2733 victim->skeleton.joints[i].locked = 0;
2734 //victim->skeleton.joints[i].velocity=0;
2740 Normalise(&relative);
2741 //victim->Puff(abdomen);
2743 Sprite::MakeSprite(cloudimpactsprite, footpoint, footvel, 1, 0, 0, .8, .3);
2745 if (victim->bloodloss < victim->damagetolerance) {
2746 victim->bloodloss += 1000;
2750 victim->jointVel(abdomen) += relative * damagemult * 20;
2754 if (!hasvictim && onterrain) {
2755 weapons[weaponids[weaponactive]].bloody = 0;
2756 weapons[weaponids[weaponactive]].blooddrip = 0;
2760 if (animTarget == upunchanim && animation[animTarget].label[frameCurrent] == 5) {
2761 if (distsq(&coords, &victim->coords) < (scale * 5) * (scale * 5) * 3) {
2769 if (tutoriallevel != 1) {
2770 emit_sound_at(heavyimpactsound, victim->coords, 128);
2775 relative = victim->coords - coords;
2777 Normalise(&relative);
2778 for (int i = 0; i < victim->skeleton.num_joints; i++) {
2779 victim->skeleton.joints[i].velocity = relative * 30;
2781 victim->jointVel(head) += relative * damagemult * 150;
2783 victim->frameTarget = 0;
2784 victim->animTarget = staggerbackhardanim;
2785 victim->targetyaw = targetyaw + 180;
2787 victim->stunned = 1;
2790 victim->Puff(abdomen);
2791 victim->DoDamage(damagemult * 60 / victim->protectionhigh);
2798 if (animTarget == winduppunchanim && animation[animTarget].label[frameCurrent] == 5) {
2799 if (distsq(&coords, &victim->coords) < (scale * 5) * (scale * 5) * 2) {
2803 if (victim->damage <= victim->damagetolerance - 60 && normaldotproduct(victim->facing, victim->coords - coords) < (scale * 5) * (scale * 5) * 0 && animation[victim->animTarget].height != lowheight) {
2804 if (tutoriallevel != 1) {
2805 emit_sound_at(thudsound, victim->coords);
2807 } else if (victim->damage <= victim->damagetolerance - 60 && normaldotproduct(victim->facing, victim->coords - coords) < (scale * 5) * (scale * 5) * 0 && animation[victim->animTarget].height == lowheight) {
2808 if (tutoriallevel != 1) {
2809 emit_sound_at(whooshhitsound, victim->coords);
2812 if (tutoriallevel != 1) {
2813 emit_sound_at(heavyimpactsound, victim->coords);
2817 if (victim->damage > victim->damagetolerance - 60 || normaldotproduct(victim->facing, victim->coords - coords) > 0 || animation[victim->animTarget].height == lowheight)
2820 relative = victim->coords - coords;
2822 Normalise(&relative);
2824 Normalise(&relative);
2825 for (int i = 0; i < victim->skeleton.num_joints; i++) {
2826 victim->skeleton.joints[i].velocity = relative * 5;
2828 victim->jointVel(abdomen) += relative * damagemult * 400;
2830 victim->frameTarget = 0;
2831 victim->animTarget = staggerbackhardanim;
2832 victim->targetyaw = targetyaw + 180;
2834 victim->stunned = 1;
2836 victim->Puff(abdomen);
2837 victim->DoDamage(damagemult * 60 / victim->protectionhigh);
2843 if (animTarget == blockhighleftanim && animation[animTarget].label[frameCurrent] == 5) {
2844 if (distsq(&coords, &victim->coords) < (scale * 5) * (scale * 5) * 4) {
2845 if (victim->id == 0)
2847 emit_sound_at(landsound2, victim->coords);
2853 if (animTarget == swordslashparryanim && animation[animTarget].label[frameCurrent] == 5) {
2854 if (distsq(&coords, &victim->coords) < (scale * 5) * (scale * 5) * 4) {
2855 if (victim->id == 0)
2858 if (weaponactive != -1) {
2859 if (weapons[victim->weaponids[0]].getType() == staff || weapons[weaponids[0]].getType() == staff) {
2860 if (weapons[victim->weaponids[0]].getType() == staff)
2861 weapons[victim->weaponids[0]].damage += .2 + float(abs(Random() % 100) - 50) / 250;
2862 if (weapons[weaponids[0]].getType() == staff)
2863 weapons[weaponids[0]].damage += .2 + float(abs(Random() % 100) - 50) / 250;
2865 emit_sound_at(swordstaffsound, victim->coords);
2867 emit_sound_at(metalhitsound, victim->coords);
2875 if (animTarget == knifethrowanim && animation[animTarget].label[frameCurrent] == 5) {
2876 if (weaponactive != -1) {
2879 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);
2881 weapons[weaponids[0]].thrown(aim * 50);
2884 weaponids[0] = weaponids[num_weapons];
2890 if (animTarget == knifeslashstartanim && animation[animTarget].label[frameCurrent] == 5) {
2892 if (distsq(&coords, &victim->coords) < (scale * 5) * (scale * 5) * 4.5 &&/*animation[victim->animTarget].height!=lowheight&&*/victim->animTarget != dodgebackanim && victim->animTarget != rollanim) {
2894 if (tutoriallevel != 1)
2895 victim->DoBloodBig(1.5 / victim->armorhigh, 225);
2897 award_bonus(id, Slicebonus);
2898 if (tutoriallevel != 1) {
2899 emit_sound_at(knifeslicesound, victim->coords);
2901 //victim->jointVel(abdomen)+=relative*damagemult*200;
2902 if (animation[victim->animTarget].attack && (victim->aitype != playercontrolled || victim->animTarget == knifeslashstartanim) && (victim->creature == rabbittype || victim->deathbleeding <= 0)) {
2903 if (victim->id != 0 || difficulty == 2) {
2904 victim->frameTarget = 0;
2905 victim->animTarget = staggerbackhardanim;
2906 victim->targetyaw = targetyaw + 180;
2910 victim->lowreversaldelay = 0;
2911 victim->highreversaldelay = 0;
2912 if (aitype != playercontrolled)
2913 weaponmissdelay = .6;
2915 if (tutoriallevel != 1)
2916 if (bloodtoggle && !weapons[weaponids[weaponactive]].bloody)
2917 weapons[weaponids[weaponactive]].bloody = 1;
2918 if (tutoriallevel != 1)
2919 weapons[weaponids[weaponactive]].blooddrip += 3;
2921 XYZ footvel, footpoint;
2923 if (skeleton.free) {
2924 footpoint = (victim->jointPos(abdomen) + victim->jointPos(neck)) / 2 * victim->scale + victim->coords;
2926 footpoint = DoRotation((victim->jointPos(abdomen) + victim->jointPos(neck)) / 2, 0, victim->yaw, 0) * victim->scale + victim->coords;
2928 if (tutoriallevel != 1) {
2930 Sprite::MakeSprite(cloudimpactsprite, footpoint, footvel, 1, 0, 0, .6, .3);
2931 footvel = DoRotation(facing, 0, 90, 0) * .8;
2933 Sprite::MakeSprite(bloodsprite, footpoint, DoRotation(footvel * 7, (float)(Random() % 20), (float)(Random() % 20), 0), 1, 1, 1, .05, .9);
2934 Sprite::MakeSprite(bloodsprite, footpoint, DoRotation(footvel * 3, (float)(Random() % 20), (float)(Random() % 20), 0), 1, 1, 1, .05, .9);
2935 Sprite::MakeSprite(bloodflamesprite, footpoint, footvel * 5, 1, 1, 1, .2, 1);
2936 Sprite::MakeSprite(bloodflamesprite, footpoint, footvel * 2, 1, 1, 1, .2, 1);
2938 if (tutoriallevel == 1) {
2939 Sprite::MakeSprite(cloudimpactsprite, footpoint, footvel, 1, 1, 1, .6, .3);
2941 victim->DoDamage(damagemult * 0);
2944 if (animTarget == swordslashanim && animation[animTarget].label[frameCurrent] == 5 && victim->animTarget != rollanim) {
2945 if (distsq(&coords, &victim->coords) < (scale * 5) * (scale * 5) * 6.5 && victim->animTarget != dodgebackanim) {
2946 if (victim->weaponactive == -1 || normaldotproduct(victim->facing, victim->coords - coords) > 0 || (Random() % 2 == 0)) {
2947 award_bonus(id, Slashbonus);
2949 if (tutoriallevel != 1) {
2950 if (normaldotproduct(victim->facing, victim->coords - coords) < 0)
2951 victim->DoBloodBig(2 / victim->armorhigh, 190);
2953 victim->DoBloodBig(2 / victim->armorhigh, 185);
2954 victim->deathbleeding = 1;
2955 emit_sound_at(swordslicesound, victim->coords);
2957 //victim->jointVel(abdomen)+=relative*damagemult*200;
2958 if (tutoriallevel != 1) {
2959 victim->frameTarget = 0;
2960 victim->animTarget = staggerbackhardanim;
2961 victim->targetyaw = targetyaw + 180;
2965 if (tutoriallevel != 1) {
2966 if (bloodtoggle && !weapons[weaponids[weaponactive]].bloody)
2967 weapons[weaponids[weaponactive]].bloody = 1;
2968 weapons[weaponids[weaponactive]].blooddrip += 3;
2970 float bloodlossamount;
2971 bloodlossamount = 200 + abs((float)(Random() % 40)) - 20;
2972 victim->bloodloss += bloodlossamount / victim->armorhigh;
2973 //victim->bloodloss+=100*(6.5-distsq(&coords,&victim->coords));
2974 victim->DoDamage(damagemult * 0);
2976 XYZ footvel, footpoint;
2978 if (skeleton.free) {
2979 footpoint = (victim->jointPos(abdomen) + victim->jointPos(neck)) / 2 * victim->scale + victim->coords;
2981 footpoint = DoRotation((victim->jointPos(abdomen) + victim->jointPos(neck)) / 2, 0, victim->yaw, 0) * victim->scale + victim->coords;
2984 Sprite::MakeSprite(cloudimpactsprite, footpoint, footvel, 1, 0, 0, .9, .3);
2985 footvel = DoRotation(facing, 0, 90, 0) * .8;
2987 Sprite::MakeSprite(bloodsprite, footpoint, DoRotation(footvel * 7, (float)(Random() % 20), (float)(Random() % 20), 0), 1, 1, 1, .05, .9);
2988 Sprite::MakeSprite(bloodsprite, footpoint, DoRotation(footvel * 3, (float)(Random() % 20), (float)(Random() % 20), 0), 1, 1, 1, .05, .9);
2989 Sprite::MakeSprite(bloodflamesprite, footpoint, footvel * 5, 1, 1, 1, .3, 1);
2990 Sprite::MakeSprite(bloodflamesprite, footpoint, footvel * 2, 1, 1, 1, .3, 1);
2993 if (victim->weaponactive != -1) {
2994 if (weapons[victim->weaponids[0]].getType() == staff || weapons[weaponids[0]].getType() == staff) {
2995 if (weapons[victim->weaponids[0]].getType() == staff)
2996 weapons[victim->weaponids[0]].damage += .2 + float(abs(Random() % 100) - 50) / 250;
2997 if (weapons[weaponids[0]].getType() == staff)
2998 weapons[weaponids[0]].damage += .2 + float(abs(Random() % 100) - 50) / 250;
3000 emit_sound_at(swordstaffsound, victim->coords);
3002 emit_sound_at(metalhitsound, victim->coords);
3008 victim->Puff(righthand);
3010 victim->frameTarget = 0;
3011 victim->animTarget = staggerbackhighanim;
3012 victim->targetyaw = targetyaw + 180;
3014 aim = DoRotation(facing, 0, 90, 0) * 21;
3016 weapons[victim->weaponids[0]].drop(aim * -.2, aim);
3017 victim->num_weapons--;
3018 if (victim->num_weapons) {
3019 victim->weaponids[0] = victim->weaponids[num_weapons];
3020 if (victim->weaponstuck == victim->num_weapons)
3021 victim->weaponstuck = 0;
3023 victim->weaponactive = -1;
3024 for (unsigned i = 0; i < Person::players.size(); i++) {
3025 Person::players[i]->wentforweapon = 0;
3032 if (animTarget == staffhitanim && animation[animTarget].label[frameCurrent] == 5 && victim->animTarget != rollanim) {
3033 if (distsq(&coords, &victim->coords) < (scale * 5) * (scale * 5) * 6.5 && victim->animTarget != dodgebackanim && victim->animTarget != sweepanim) {
3034 if (tutoriallevel != 1) {
3035 weapons[weaponids[0]].damage += .4 + float(abs(Random() % 100) - 50) / 250;
3039 if (Random() % 2 || creature == wolftype) {
3042 emit_sound_at(staffheadsound, victim->coords);
3046 relative = victim->coords - coords;
3048 Normalise(&relative);
3049 relative = DoRotation(relative, 0, 90, 0);
3051 Normalise(&relative);
3052 for (int i = 0; i < victim->skeleton.num_joints; i++) {
3053 victim->skeleton.joints[i].velocity += relative * damagemult * 60;
3055 victim->jointVel(head) += relative * damagemult * 230;
3056 victim->jointVel(neck) += relative * damagemult * 230;
3059 if (tutoriallevel != 1) {
3060 victim->DoDamage(damagemult * 120 / victim->protectionhigh);
3062 award_bonus(id, solidhit, 30);
3067 if (animTarget == staffspinhitanim && animation[animTarget].label[frameCurrent] == 5 && victim->animTarget != rollanim) {
3068 if (distsq(&coords, &victim->coords) < (scale * 5) * (scale * 5) * 6.5 && victim->animTarget != dodgebackanim && victim->animTarget != sweepanim) {
3069 if (tutoriallevel != 1) {
3070 weapons[weaponids[0]].damage += .6 + float(abs(Random() % 100) - 50) / 250;
3074 if (Random() % 2 || creature == wolftype) {
3077 emit_sound_at(staffheadsound, victim->coords);
3081 relative = victim->coords - coords;
3083 Normalise(&relative);
3084 relative = DoRotation(relative, 0, -90, 0);
3085 for (int i = 0; i < victim->skeleton.num_joints; i++) {
3086 victim->skeleton.joints[i].velocity += relative * damagemult * 40;
3088 victim->jointVel(head) += relative * damagemult * 220;
3089 victim->jointVel(neck) += relative * damagemult * 220;
3092 if (tutoriallevel != 1) {
3093 victim->DoDamage(damagemult * 350 / victim->protectionhead);
3095 award_bonus(id, solidhit, 60);
3100 if (animTarget == staffgroundsmashanim && animation[animTarget].label[frameCurrent] == 5) {
3101 if (distsq(&coords, &victim->coords) < (scale * 5) * (scale * 5) * 6.5) {
3103 if (tutoriallevel != 1) {
3105 weapons[weaponids[0]].damage += .4 + float(abs(Random() % 100) - 50) / 500;
3108 if (Random() % 2 || creature == wolftype) {
3111 emit_sound_at(staffbodysound, victim->coords);
3113 victim->skeleton.longdead = 0;
3114 victim->skeleton.free = 1;
3115 victim->skeleton.broken = 0;
3117 for (int i = 0; i < victim->skeleton.num_joints; i++) {
3118 victim->skeleton.joints[i].velchange = 0;
3119 victim->skeleton.joints[i].locked = 0;
3120 //victim->skeleton.joints[i].velocity=0;
3126 /*relative=victim->coords-coords;
3128 Normalise(&relative);
3129 relative=DoRotation(relative,0,90,0);*/
3131 Normalise(&relative);
3132 if (!victim->dead) {
3133 for (int i = 0; i < victim->skeleton.num_joints; i++) {
3134 victim->skeleton.joints[i].velocity = relative * damagemult * 40;
3137 victim->jointVel(abdomen) += relative * damagemult * 40;
3140 for (int i = 0; i < victim->skeleton.num_joints; i++) {
3141 victim->skeleton.joints[i].velocity = relative * damagemult * abs(Random() % 20);
3144 //victim->jointVel(abdomen)+=relative*damagemult*20;
3146 victim->Puff(abdomen);
3147 if (tutoriallevel != 1) {
3148 victim->DoDamage(damagemult * 100 / victim->protectionhigh);
3150 if (!victim->dead) {
3151 award_bonus(id, solidhit, 40);
3157 if (animTarget == lowkickanim && animation[animTarget].label[frameCurrent] == 5) {
3158 if (distsq(&coords, &victim->coords) < (scale * 5) * (scale * 5) * 3 && animation[victim->animTarget].height != highheight) {
3163 relative = victim->coords - coords;
3165 Normalise(&relative);
3169 if (animation[victim->animTarget].height == lowheight) {
3175 for (int i = 0; i < victim->skeleton.num_joints; i++) {
3176 victim->skeleton.joints[i].velocity += relative * damagemult * 40;
3178 victim->jointVel(head) += relative * damagemult * 200;
3179 if (tutoriallevel != 1) {
3180 emit_sound_at(heavyimpactsound, victim->coords, 128.);
3183 victim->DoDamage(damagemult * 100 / victim->protectionhead);
3184 if (victim->howactive == typesleeping)
3185 victim->DoDamage(damagemult * 150 / victim->protectionhead);
3186 if (creature == wolftype) {
3187 emit_sound_at(clawslicesound, victim->coords, 128.);
3189 victim->DoBloodBig(2 / victim->armorhead, 175);
3192 if (victim->damage >= victim->damagetolerance)
3194 for (int i = 0; i < victim->skeleton.num_joints; i++) {
3195 victim->skeleton.joints[i].velocity += relative * damagemult * 10;
3197 victim->jointVel(abdomen) += relative * damagemult * 200;
3198 victim->frameTarget = 0;
3199 victim->animTarget = staggerbackhighanim;
3200 victim->targetyaw = targetyaw + 180;
3202 if (tutoriallevel != 1) {
3203 emit_sound_at(landsound2, victim->coords, 128.);
3205 victim->Puff(abdomen);
3206 victim->DoDamage(damagemult * 30 / victim->protectionhigh);
3207 if (creature == wolftype) {
3208 emit_sound_at(clawslicesound, victim->coords, 128.);
3210 victim->DoBloodBig(2 / victim->armorhigh, 170);
3217 if (animTarget == sweepanim && animation[animTarget].label[frameCurrent] == 5) {
3218 if ((victim->animTarget != jumpupanim) &&
3219 (distsq(&coords, &victim->coords) < (scale * 5) * (scale * 5) * 3) &&
3220 (victim != this->shared_from_this())) {
3224 if (tutoriallevel != 1) {
3225 emit_sound_at(landsound2, victim->coords, 128.);
3228 relative = victim->coords - coords;
3230 Normalise(&relative);
3232 if (animation[victim->animTarget].height == middleheight || animation[victim->animCurrent].height == middleheight || victim->damage >= victim->damagetolerance - 40) {
3235 for (int i = 0; i < victim->skeleton.num_joints; i++) {
3236 victim->skeleton.joints[i].velocity += relative * damagemult * 15;
3238 relative = DoRotation(relative, 0, -90, 0);
3240 for (int i = 0; i < victim->skeleton.num_joints; i++) {
3241 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)
3242 victim->skeleton.joints[i].velocity = relative * 80;
3244 victim->Puff(rightankle);
3245 victim->Puff(leftankle);
3246 victim->DoDamage(damagemult * 40 / victim->protectionlow);
3248 if (victim->damage >= victim->damagetolerance)
3250 for (int i = 0; i < victim->skeleton.num_joints; i++) {
3251 victim->skeleton.joints[i].velocity += relative * damagemult * 10;
3253 relative = DoRotation(relative, 0, -90, 0);
3254 for (int i = 0; i < victim->skeleton.num_joints; i++) {
3255 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)
3256 victim->skeleton.joints[i].velocity += relative * damagemult * 80;
3258 victim->jointVel(abdomen) += relative * damagemult * 200;
3259 victim->frameTarget = 0;
3260 victim->animTarget = staggerbackhighanim;
3261 victim->targetyaw = targetyaw + 180;
3263 if (tutoriallevel != 1) {
3264 emit_sound_at(landsound2, victim->coords, 128.);
3266 victim->Puff(abdomen);
3267 victim->DoDamage(damagemult * 30 / victim->protectionlow);
3275 if (animation[animTarget].attack == reversal && (!victim->feint || (victim->lastattack == victim->lastattack2 && victim->lastattack2 == victim->lastattack3 && Random() % 2) || animTarget == knifefollowanim)) {
3276 if (animTarget == spinkickreversalanim && animation[animTarget].label[frameCurrent] == 7) {
3284 if (tutoriallevel != 1) {
3285 emit_sound_at(heavyimpactsound, victim->coords, 128.);
3287 if (creature == wolftype) {
3288 emit_sound_at(clawslicesound, victim->coords, 128);
3290 victim->DoBloodBig(2 / victim->armorhigh, 170);
3294 relative = victim->coords - oldcoords;
3296 Normalise(&relative);
3297 //relative=DoRotation(relative,0,-90,0);
3298 for (int i = 0; i < victim->skeleton.num_joints; i++) {
3299 victim->skeleton.joints[i].velocity += relative * damagemult * 40;
3301 victim->jointVel(abdomen) += relative * damagemult * 200;
3303 victim->Puff(abdomen);
3304 victim->DoDamage(damagemult * 150 / victim->protectionhigh);
3306 award_bonus(id, Reversal);
3309 if ((animTarget == swordslashreversalanim || animTarget == knifeslashreversalanim || animTarget == staffhitreversalanim || animTarget == staffspinhitreversalanim) && animation[animTarget].label[frameCurrent] == 5) {
3310 if (victim->weaponactive != -1 && victim->num_weapons > 0) {
3311 if (weapons[victim->weaponids[victim->weaponactive]].owner == int(victim->id)) {
3312 takeWeapon(victim->weaponids[victim->weaponactive]);
3313 victim->num_weapons--;
3314 if (victim->num_weapons > 0) {
3315 victim->weaponids[victim->weaponactive] = victim->weaponids[victim->num_weapons];
3317 victim->weaponactive = -1;
3322 if (animTarget == staffhitreversalanim && animation[animTarget].label[frameCurrent] == 5) {
3330 emit_sound_at(whooshhitsound, victim->coords, 128.);
3333 relative = victim->coords - oldcoords;
3335 Normalise(&relative);
3336 for (int i = 0; i < victim->skeleton.num_joints; i++) {
3337 victim->skeleton.joints[i].velocity += relative * damagemult * 30;
3339 victim->jointVel(abdomen) += relative * damagemult * 200;
3341 victim->DoDamage(damagemult * 70 / victim->protectionhigh);
3344 if (animTarget == staffspinhitreversalanim && animation[animTarget].label[frameCurrent] == 7) {
3353 award_bonus(id, staffreversebonus);
3355 if (tutoriallevel != 1) {
3356 emit_sound_at(heavyimpactsound, victim->coords, 128.);
3359 award_bonus(id, staffreversebonus); // Huh, again?
3362 relative = victim->coords - oldcoords;
3364 Normalise(&relative);
3365 for (int i = 0; i < victim->skeleton.num_joints; i++) {
3366 victim->skeleton.joints[i].velocity += relative * damagemult * 30;
3368 victim->jointVel(abdomen) += relative * damagemult * 200;
3370 victim->DoDamage(damagemult * 70 / victim->protectionhigh);
3373 if (animTarget == upunchreversalanim && animation[animTarget].label[frameCurrent] == 7) {
3379 Normalise(&relative);
3381 for (int i = 0; i < victim->skeleton.num_joints; i++) {
3382 victim->skeleton.joints[i].velocity += relative * damagemult * 70;
3384 victim->jointVel(lefthand) *= .1;
3385 victim->jointVel(leftwrist) *= .2;
3386 victim->jointVel(leftelbow) *= .5;
3387 victim->jointVel(leftshoulder) *= .7;
3388 victim->jointVel(righthand) *= .1;
3389 victim->jointVel(rightwrist) *= .2;
3390 victim->jointVel(rightelbow) *= .5;
3391 victim->jointVel(rightshoulder) *= .7;
3393 victim->Puff(abdomen);
3394 victim->DoDamage(damagemult * 90 / victim->protectionhigh);
3396 award_bonus(id, Reversal);
3400 if (weaponactive != -1 || creature == wolftype)
3402 if (creature == rabbittype && weaponactive != -1)
3403 if (weapons[weaponids[0]].getType() == staff)
3406 if (weaponactive != -1) {
3407 victim->DoBloodBig(2 / victim->armorhigh, 225);
3408 emit_sound_at(knifeslicesound, victim->coords);
3409 if (bloodtoggle && !weapons[weaponids[weaponactive]].bloody)
3410 weapons[weaponids[weaponactive]].bloody = 1;
3411 weapons[weaponids[weaponactive]].blooddrip += 3;
3413 if (weaponactive == -1 && creature == wolftype) {
3414 emit_sound_at(clawslicesound, victim->coords, 128.);
3416 victim->DoBloodBig(2 / victim->armorhigh, 175);
3423 if (animTarget == swordslashreversalanim && animation[animTarget].label[frameCurrent] == 7) {
3429 Normalise(&relative);
3431 for (int i = 0; i < victim->skeleton.num_joints; i++) {
3432 victim->skeleton.joints[i].velocity += relative * damagemult * 70;
3434 victim->jointVel(lefthand) *= .1 - 1;
3435 victim->jointVel(leftwrist) *= .2 - 1;
3436 victim->jointVel(leftelbow) *= .5 - 1;
3437 victim->jointVel(leftshoulder) *= .7 - 1;
3438 victim->jointVel(righthand) *= .1 - 1;
3439 victim->jointVel(rightwrist) *= .2 - 1;
3440 victim->jointVel(rightelbow) *= .5 - 1;
3441 victim->jointVel(rightshoulder) *= .7 - 1;
3443 award_bonus(id, swordreversebonus);
3446 if (hasvictim && animTarget == knifeslashreversalanim && animation[animTarget].label[frameCurrent] == 7) {
3454 if (tutoriallevel != 1) {
3455 emit_sound_at(heavyimpactsound, victim->coords, 128.);
3459 relative = victim->coords - oldcoords;
3461 Normalise(&relative);
3462 relative = DoRotation(relative, 0, -90, 0);
3463 for (int i = 0; i < victim->skeleton.num_joints; i++) {
3464 victim->skeleton.joints[i].velocity += relative * damagemult * 40;
3466 victim->jointVel(abdomen) += relative * damagemult * 200;
3467 victim->Puff(abdomen);
3468 victim->DoDamage(damagemult * 30 / victim->protectionhigh);
3470 award_bonus(id, Reversal);
3473 if (hasvictim && animTarget == sneakattackanim && animation[animTarget].label[frameCurrent] == 7) {
3476 victim->skeleton.spinny = 0;
3478 relative = facing * -1;
3480 Normalise(&relative);
3481 if (victim->id == 0)
3483 for (int i = 0; i < victim->skeleton.num_joints; i++) {
3484 victim->skeleton.joints[i].velocity += relative * damagemult * 40;
3486 victim->damage = victim->damagetolerance;
3487 victim->permanentdamage = victim->damagetolerance - 1;
3490 if (weaponactive != -1 || creature == wolftype)
3492 if (creature == rabbittype && weaponactive != -1)
3493 if (weapons[weaponids[0]].getType() == staff)
3496 if (weaponactive != -1) {
3497 victim->DoBloodBig(200, 225);
3498 emit_sound_at(knifeslicesound, victim->coords);
3500 weapons[weaponids[weaponactive]].bloody = 2;
3501 weapons[weaponids[weaponactive]].blooddrip += 5;
3504 if (creature == wolftype && weaponactive == -1) {
3505 emit_sound_at(clawslicesound, victim->coords, 128.);
3507 victim->DoBloodBig(2, 175);
3510 award_bonus(id, spinecrusher);
3513 if (hasvictim && (animTarget == knifefollowanim || animTarget == knifesneakattackanim) && animation[animTarget].label[frameCurrent] == 5) {
3514 if (weaponactive != -1 && victim->bloodloss < victim->damagetolerance) {
3516 if (animTarget == knifefollowanim)
3517 victim->DoBloodBig(200, 210);
3518 if (animTarget == knifesneakattackanim) {
3519 XYZ footvel, footpoint;
3521 footpoint = weapons[weaponids[0]].tippoint;
3523 Sprite::MakeSprite(cloudimpactsprite, footpoint, footvel, 1, 0, 0, .9, .3);
3524 footvel = (weapons[weaponids[0]].tippoint - weapons[weaponids[0]].position);
3525 Sprite::MakeSprite(bloodsprite, footpoint, DoRotation(footvel * 7, (float)(Random() % 20), (float)(Random() % 20), 0), 1, 1, 1, .05, .9);
3526 Sprite::MakeSprite(bloodsprite, footpoint, DoRotation(footvel * 3, (float)(Random() % 20), (float)(Random() % 20), 0), 1, 1, 1, .05, .9);
3527 Sprite::MakeSprite(bloodflamesprite, footpoint, footvel * 5, 1, 1, 1, .3, 1);
3528 Sprite::MakeSprite(bloodflamesprite, footpoint, footvel * 2, 1, 1, 1, .3, 1);
3529 victim->DoBloodBig(200, 195);
3530 award_bonus(id, tracheotomy);
3532 if (animTarget == knifefollowanim) {
3533 award_bonus(id, Stabbonus);
3534 XYZ footvel, footpoint;
3536 footpoint = weapons[weaponids[0]].tippoint;
3538 Sprite::MakeSprite(cloudimpactsprite, footpoint, footvel, 1, 0, 0, .9, .3);
3539 footvel = (weapons[weaponids[0]].tippoint - weapons[weaponids[0]].position) * -1;
3540 Sprite::MakeSprite(bloodsprite, footpoint, DoRotation(footvel * 7, (float)(Random() % 20), (float)(Random() % 20), 0), 1, 1, 1, .05, .9);
3541 Sprite::MakeSprite(bloodsprite, footpoint, DoRotation(footvel * 3, (float)(Random() % 20), (float)(Random() % 20), 0), 1, 1, 1, .05, .9);
3542 Sprite::MakeSprite(bloodflamesprite, footpoint, footvel * 5, 1, 1, 1, .2, 1);
3543 Sprite::MakeSprite(bloodflamesprite, footpoint, footvel * 2, 1, 1, 1, .2, 1);
3546 victim->bloodloss += 10000;
3547 victim->velocity = 0;
3548 emit_sound_at(fleshstabsound, victim->coords);
3550 weapons[weaponids[weaponactive]].bloody = 2;
3551 weapons[weaponids[weaponactive]].blooddrip += 5;
3555 if (hasvictim && (animTarget == knifefollowanim || animTarget == knifesneakattackanim) && animation[animTarget].label[frameCurrent] == 6) {
3557 victim->velocity = 0;
3558 for (int i = 0; i < victim->skeleton.num_joints; i++) {
3559 victim->skeleton.joints[i].velocity = 0;
3561 if (animTarget == knifefollowanim) {
3563 for (int i = 0; i < victim->skeleton.num_joints; i++) {
3564 victim->skeleton.joints[i].velocity = 0;
3567 if (weaponactive != -1 && animation[victim->animTarget].attack != reversal) {
3568 emit_sound_at(fleshstabremovesound, victim->coords);
3570 weapons[weaponids[weaponactive]].bloody = 2;
3571 weapons[weaponids[weaponactive]].blooddrip += 5;
3573 XYZ footvel, footpoint;
3575 footpoint = weapons[weaponids[0]].tippoint;
3577 Sprite::MakeSprite(cloudimpactsprite, footpoint, footvel, 1, 0, 0, .9, .3);
3578 footvel = (weapons[weaponids[0]].tippoint - weapons[weaponids[0]].position) * -1;
3579 Sprite::MakeSprite(bloodsprite, footpoint, DoRotation(footvel * 7, (float)(Random() % 20), (float)(Random() % 20), 0), 1, 1, 1, .05, .9);
3580 Sprite::MakeSprite(bloodsprite, footpoint, DoRotation(footvel * 3, (float)(Random() % 20), (float)(Random() % 20), 0), 1, 1, 1, .05, .9);
3581 Sprite::MakeSprite(bloodflamesprite, footpoint, footvel * 5, 1, 1, 1, .3, 1);
3582 Sprite::MakeSprite(bloodflamesprite, footpoint, footvel * 2, 1, 1, 1, .3, 1);
3586 if (hasvictim && (animTarget == swordsneakattackanim) && animation[animTarget].label[frameCurrent] == 5) {
3587 if (weaponactive != -1 && victim->bloodloss < victim->damagetolerance) {
3588 award_bonus(id, backstab);
3592 XYZ footvel, footpoint;
3594 footpoint = (weapons[weaponids[0]].tippoint + weapons[weaponids[0]].position) / 2;
3596 Sprite::MakeSprite(cloudimpactsprite, footpoint, footvel, 1, 0, 0, .9, .3);
3597 footvel = (weapons[weaponids[0]].tippoint - weapons[weaponids[0]].position);
3598 Sprite::MakeSprite(bloodsprite, footpoint, DoRotation(footvel * 7, (float)(Random() % 20), (float)(Random() % 20), 0), 1, 1, 1, .05, .9);
3599 Sprite::MakeSprite(bloodsprite, footpoint, DoRotation(footvel * 3, (float)(Random() % 20), (float)(Random() % 20), 0), 1, 1, 1, .05, .9);
3600 Sprite::MakeSprite(bloodflamesprite, footpoint, DoRotation(footvel * 5, (float)(Random() % 20), (float)(Random() % 20), 0), 1, 1, 1, .3, 1);
3601 Sprite::MakeSprite(bloodflamesprite, footpoint, DoRotation(footvel * 3, (float)(Random() % 20), (float)(Random() % 20), 0), 1, 1, 1, .3, 1);
3602 victim->DoBloodBig(200, 180);
3603 victim->DoBloodBig(200, 215);
3604 victim->bloodloss += 10000;
3605 victim->velocity = 0;
3606 emit_sound_at(fleshstabsound, victim->coords);
3608 weapons[weaponids[weaponactive]].bloody = 2;
3609 weapons[weaponids[weaponactive]].blooddrip += 5;
3613 if (hasvictim && animTarget == swordsneakattackanim && animation[animTarget].label[frameCurrent] == 6) {
3615 victim->velocity = 0;
3616 for (int i = 0; i < victim->skeleton.num_joints; i++) {
3617 victim->skeleton.joints[i].velocity = 0;
3619 if (weaponactive != -1) {
3620 emit_sound_at(fleshstabremovesound, victim->coords);
3622 weapons[weaponids[weaponactive]].bloody = 2;
3623 weapons[weaponids[weaponactive]].blooddrip += 5;
3625 XYZ footvel, footpoint;
3627 footpoint = weapons[weaponids[0]].tippoint;
3629 Sprite::MakeSprite(cloudimpactsprite, footpoint, footvel, 1, 0, 0, .9, .3);
3630 footvel = (weapons[weaponids[0]].tippoint - weapons[weaponids[0]].position) * -1;
3631 Sprite::MakeSprite(bloodsprite, footpoint, DoRotation(footvel * 7, (float)(Random() % 20), (float)(Random() % 20), 0), 1, 1, 1, .05, .9);
3632 Sprite::MakeSprite(bloodsprite, footpoint, DoRotation(footvel * 3, (float)(Random() % 20), (float)(Random() % 20), 0), 1, 1, 1, .05, .9);
3633 Sprite::MakeSprite(bloodflamesprite, footpoint, footvel * 5, 1, 1, 1, .3, 1);
3634 Sprite::MakeSprite(bloodflamesprite, footpoint, footvel * 2, 1, 1, 1, .3, 1);
3638 if (animTarget == sweepreversalanim && animation[animTarget].label[frameCurrent] == 7) {
3646 if (weaponactive == -1) {
3647 if (tutoriallevel != 1) {
3648 emit_sound_at(heavyimpactsound, victim->coords, 128.);
3653 if (weaponactive != -1 || creature == wolftype)
3655 if (creature == rabbittype && weaponactive != -1)
3656 if (weapons[weaponids[0]].getType() == staff)
3659 if (weaponactive != -1) {
3660 victim->DoBloodBig(2 / victim->armorhead, 225);
3661 emit_sound_at(knifeslicesound, victim->coords);
3662 if (bloodtoggle && !weapons[weaponids[weaponactive]].bloody)
3663 weapons[weaponids[weaponactive]].bloody = 1;
3664 weapons[weaponids[weaponactive]].blooddrip += 3;
3666 if (weaponactive == -1 && creature == wolftype) {
3667 emit_sound_at(clawslicesound, victim->coords, 128.);
3669 victim->DoBloodBig(2 / victim->armorhead, 175);
3673 award_bonus(id, Reversal);
3678 relative = facing * -1;
3680 Normalise(&relative);
3681 relative = DoRotation(relative, 0, 90, 0);
3683 Normalise(&relative);
3684 for (int i = 0; i < victim->skeleton.num_joints; i++) {
3685 victim->skeleton.joints[i].velocity += relative * damagemult * 20;
3687 victim->jointVel(head) += relative * damagemult * 200;
3688 if (victim->damage < victim->damagetolerance - 100)
3689 victim->velocity = relative * 200;
3690 victim->DoDamage(damagemult * 100 / victim->protectionhead);
3691 victim->velocity = 0;
3694 if (animTarget == sweepreversalanim && ((animation[animTarget].label[frameCurrent] == 9 && victim->damage < victim->damagetolerance) || (animation[animTarget].label[frameCurrent] == 7 && victim->damage > victim->damagetolerance))) {
3698 relative = facing * -1;
3700 Normalise(&relative);
3701 relative = DoRotation(relative, 0, 90, 0);
3703 Normalise(&relative);
3704 for (int i = 0; i < victim->skeleton.num_joints; i++) {
3705 victim->skeleton.joints[i].velocity += relative * damagemult * 20;
3707 victim->jointVel(head) += relative * damagemult * 200;
3710 if (hasvictim && (animTarget == spinkickreversalanim || animTarget == sweepreversalanim || animTarget == rabbitkickreversalanim || animTarget == upunchreversalanim || animTarget == jumpreversalanim || animTarget == swordslashreversalanim || animTarget == knifeslashreversalanim || animTarget == rabbittacklereversal || animTarget == wolftacklereversal || animTarget == staffhitreversalanim || animTarget == staffspinhitreversalanim))
3711 if (victim->damage > victim->damagetolerance && bonus != reverseko) {
3712 award_bonus(id, reverseko);
3718 if (frameTarget > animation[animCurrent].numframes - 1) {
3721 animTarget = getIdle();
3725 if (animCurrent == rabbittackleanim || animCurrent == rabbittacklinganim) {
3726 animTarget = rollanim;
3728 emit_sound_at(movewhooshsound, coords, 128.);
3730 if (animCurrent == staggerbackhighanim) {
3731 animTarget = getIdle();
3733 if (animCurrent == staggerbackhardanim) {
3734 animTarget = getIdle();
3736 if (animCurrent == removeknifeanim) {
3737 animTarget = getIdle();
3739 if (animCurrent == crouchremoveknifeanim) {
3740 animTarget = getCrouch();
3742 if (animCurrent == backhandspringanim) {
3743 animTarget = getIdle();
3745 if (animCurrent == dodgebackanim) {
3746 animTarget = getIdle();
3748 if (animCurrent == drawleftanim) {
3749 animTarget = getIdle();
3751 if (animCurrent == drawrightanim || animCurrent == crouchdrawrightanim) {
3752 animTarget = getIdle();
3753 if (animCurrent == crouchdrawrightanim) {
3754 animTarget = getCrouch();
3756 if (weaponactive == -1)
3758 else if (weaponactive == 0) {
3760 if (num_weapons == 2) {
3762 buffer = weaponids[0];
3763 weaponids[0] = weaponids[1];
3764 weaponids[1] = buffer;
3768 if (weaponactive == -1) {
3769 emit_sound_at(knifesheathesound, coords, 128.);
3771 if (weaponactive != -1) {
3772 emit_sound_at(knifedrawsound, coords, 128.);
3775 if (animCurrent == rollanim) {
3776 animTarget = getCrouch();
3781 if (animTarget == walljumprightkickanim) {
3784 if (animTarget == walljumpleftkickanim) {
3787 animTarget = jumpdownanim;
3789 if (animCurrent == climbanim) {
3790 animTarget = getCrouch();
3792 coords += facing * .1;
3793 if (!isnormal(coords.x))
3804 if (animTarget == rabbitkickreversalanim) {
3805 animTarget = getCrouch();
3808 if (animTarget == jumpreversalanim) {
3809 animTarget = getCrouch();
3812 if (animTarget == walljumprightanim || animTarget == walljumpbackanim || animTarget == walljumpfrontanim) {
3813 if (attackkeydown && animTarget != walljumpfrontanim) {
3815 float closestdist = -1;
3817 if (Person::players.size() > 1)
3818 for (unsigned i = 0; i < Person::players.size(); i++) {
3819 if (id != i && Person::players[i]->coords.y < coords.y && !Person::players[i]->skeleton.free) {
3820 distance = distsq(&Person::players[i]->coords, &coords);
3821 if (closestdist == -1 || distance < closestdist) {
3822 closestdist = distance;
3827 if (closestdist > 0 && closest >= 0 && closestdist < 16) {
3828 victim = Person::players[closest];
3829 animTarget = walljumprightkickanim;
3831 XYZ rotatetarget = victim->coords - coords;
3832 Normalise(&rotatetarget);
3833 yaw = -asin(0 - rotatetarget.x);
3835 if (rotatetarget.z < 0)
3837 targettilt2 = -asin(rotatetarget.y) * 360 / 6.28;
3838 velocity = (victim->coords - coords) * 4;
3843 if (animTarget == walljumpbackanim) {
3844 animTarget = backflipanim;
3846 velocity = facing * -8;
3849 resume_stream(whooshsound);
3851 if (animTarget == walljumprightanim) {
3852 animTarget = rightflipanim;
3856 velocity = DoRotation(facing, 0, 30, 0) * -8;
3859 if (animTarget == walljumpfrontanim) {
3860 animTarget = frontflipanim;
3864 velocity = facing * 8;
3868 resume_stream(whooshsound);
3870 if (animTarget == walljumpleftanim) {
3871 if (attackkeydown) {
3873 float closestdist = -1;
3875 if (Person::players.size() > 1)
3876 for (unsigned i = 0; i < Person::players.size(); i++) {
3877 if (id != i && Person::players[i]->coords.y < coords.y && !Person::players[i]->skeleton.free) {
3878 distance = distsq(&Person::players[i]->coords, &coords);
3879 if (closestdist == -1 || distance < closestdist) {
3880 closestdist = distance;
3885 if (closestdist > 0 && closest >= 0 && closestdist < 16) {
3886 victim = Person::players[closest];
3887 animTarget = walljumpleftkickanim;
3889 XYZ rotatetarget = victim->coords - coords;
3890 Normalise(&rotatetarget);
3891 yaw = -asin(0 - rotatetarget.x);
3893 if (rotatetarget.z < 0)
3895 targettilt2 = -asin(rotatetarget.y) * 360 / 6.28;
3896 velocity = (victim->coords - coords) * 4;
3901 if (animTarget != walljumpleftkickanim) {
3902 animTarget = leftflipanim;
3906 velocity = DoRotation(facing, 0, -30, 0) * -8;
3910 resume_stream(whooshsound);
3912 if (animTarget == sneakattackanim) {
3913 animCurrent = getCrouch();
3914 animTarget = getCrouch();
3921 transspeed = 1000000;
3922 targetheadyaw += 180;
3923 coords -= facing * .7;
3925 coords.y = terrain.getHeight(coords.x, coords.z);
3929 if (animTarget == knifesneakattackanim || animTarget == swordsneakattackanim) {
3930 animTarget = getIdle();
3933 coords.y = terrain.getHeight(coords.x, coords.z);
3937 if (animCurrent == knifefollowanim) {
3938 animTarget = getIdle();
3941 if (animation[animTarget].attack == reversal && animCurrent != sneakattackanim && animCurrent != knifesneakattackanim && animCurrent != swordsneakattackanim && animCurrent != knifefollowanim) {
3942 float ycoords = oldcoords.y;
3943 animTarget = getStop();
3948 transspeed = 1000000;
3949 targetheadyaw += 180;
3950 if (!isnormal(coords.x))
3952 if (animCurrent == spinkickreversalanim || animCurrent == swordslashreversalanim)
3953 oldcoords = coords + facing * .5;
3954 else if (animCurrent == sweepreversalanim)
3955 oldcoords = coords + facing * 1.1;
3956 else if (animCurrent == upunchreversalanim) {
3957 oldcoords = coords + facing * 1.5;
3960 targetheadyaw += 180;
3963 } else if (animCurrent == knifeslashreversalanim) {
3964 oldcoords = coords + facing * .5;
3967 targetheadyaw += 90;
3970 } else if (animCurrent == staffspinhitreversalanim) {
3973 targetheadyaw += 180;
3978 oldcoords.y = terrain.getHeight(oldcoords.x, oldcoords.z);
3980 oldcoords.y = ycoords;
3981 currentoffset = coords - oldcoords;
3987 if (animCurrent == knifesneakattackedanim || animCurrent == swordsneakattackedanim) {
3992 if (animation[animTarget].attack == reversed) {
3994 if (animTarget == sweepreversedanim)
3996 animTarget = backhandspringanim;
3998 emit_sound_at(landsound, coords, 128);
4000 if (animCurrent == upunchreversedanim || animCurrent == swordslashreversedanim) {
4001 animTarget = rollanim;
4004 coords += (DoRotation(jointPos(leftfoot), 0, yaw, 0) + DoRotation(jointPos(rightfoot), 0, yaw, 0)) / 2 * scale;
4005 coords.y = oldcoords.y;
4007 if (animCurrent == knifeslashreversedanim) {
4008 animTarget = rollanim;
4013 coords += (DoRotation(jointPos(leftfoot), 0, yaw, 0) + DoRotation(jointPos(rightfoot), 0, yaw, 0)) / 2 * scale;
4014 coords.y = oldcoords.y;
4018 animTarget = jumpdownanim;
4021 animTarget = getIdle();
4023 animTarget = getIdle();
4024 if (animCurrent == spinkickanim || animCurrent == getupfrombackanim || animCurrent == getupfromfrontanim || animCurrent == lowkickanim) {
4025 animTarget = getIdle();
4027 coords += (DoRotation(jointPos(leftfoot), 0, yaw, 0) + DoRotation(jointPos(rightfoot), 0, yaw, 0)) / 2 * scale;
4028 coords.y = oldcoords.y;
4029 //coords+=DoRotation(animation[animCurrent].offset,0,yaw,0)*scale;
4030 targetoffset.y = coords.y;
4032 targetoffset.y = terrain.getHeight(coords.x, coords.z);
4033 currentoffset = DoRotation(animation[animCurrent].offset * -1, 0, yaw, 0) * scale;
4034 currentoffset.y -= (coords.y - targetoffset.y);
4035 coords.y = targetoffset.y;
4037 normalsupdatedelay = 0;
4039 if (animCurrent == upunchanim) {
4040 animTarget = getStop();
4041 normalsupdatedelay = 0;
4044 if (animCurrent == rabbitkickanim && animTarget != backflipanim) {
4048 if (num_weapons > 0)
4049 if (weapons[0].getType() == staff)
4055 rabbitkickragdoll = 1;
4057 if (animCurrent == rabbitkickreversedanim) {
4063 skeleton.spinny = 0;
4064 SolidHitBonus(!id); // FIXME: tricky id
4068 animTarget = rollanim;
4071 pause_sound(whooshsound);
4075 if (animCurrent == rabbittackledbackanim || animCurrent == rabbittackledfrontanim) {
4079 skeleton.spinny = 0;
4081 if (animCurrent == jumpreversedanim) {
4087 skeleton.spinny = 0;
4088 SolidHitBonus(!id); // FIXME: tricky id
4092 animTarget = rollanim;
4093 coords += facing * 2;
4095 pause_sound(whooshsound);
4100 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) {
4101 animTarget = getupfromfrontanim;
4103 } else if (animation[animCurrent].attack == normalattack) {
4104 animTarget = getIdle();
4107 if (animCurrent == blockhighleftanim && aitype != playercontrolled) {
4108 animTarget = blockhighleftstrikeanim;
4110 if (animCurrent == knifeslashstartanim || animCurrent == knifethrowanim || animCurrent == swordslashanim || animCurrent == staffhitanim || animCurrent == staffgroundsmashanim || animCurrent == staffspinhitanim) {
4111 animTarget = getIdle();
4114 if (animCurrent == spinkickanim && victim->skeleton.free) {
4115 if (creature == rabbittype)
4116 animTarget = fightidleanim;
4121 if (isIdle() && !wasIdle())
4122 normalsupdatedelay = 0;
4124 if (animCurrent == jumpupanim && velocity.y < 0 && !isFlip()) {
4125 animTarget = jumpdownanim;
4128 if (!skeleton.free) {
4130 if (!transspeed && animation[animTarget].attack != 2 && animation[animTarget].attack != 3) {
4131 if (!isRun() || !wasRun()) {
4132 if (animation[animTarget].speed[frameTarget] > animation[animCurrent].speed[frameCurrent])
4133 target += multiplier * animation[animTarget].speed[frameTarget] * speed * 2;
4134 if (animation[animTarget].speed[frameTarget] <= animation[animCurrent].speed[frameCurrent])
4135 target += multiplier * animation[animCurrent].speed[frameCurrent] * speed * 2;
4137 if (isRun() && wasRun()) {
4139 tempspeed = velspeed;
4140 if (tempspeed < 10 * speedmult)
4141 tempspeed = 10 * speedmult;
4142 target += multiplier * animation[animTarget].speed[frameCurrent] * speed * 1.7 * tempspeed / (speed * 45 * scale);
4144 } else if (transspeed)
4145 target += multiplier * transspeed * speed * 2;
4147 if (!isRun() || !wasRun()) {
4148 if (animation[animTarget].speed[frameTarget] > animation[animCurrent].speed[frameCurrent])
4149 target += multiplier * animation[animTarget].speed[frameTarget] * 2;
4150 if (animation[animTarget].speed[frameTarget] <= animation[animCurrent].speed[frameCurrent])
4151 target += multiplier * animation[animCurrent].speed[frameCurrent] * 2;
4155 if (animCurrent != animTarget)
4156 target = (target + oldtarget) / 2;
4159 frameCurrent = frameTarget;
4163 rot = targetrot * target;
4164 yaw += rot - oldrot;
4170 if (animCurrent != oldanimCurrent || animTarget != oldanimTarget || ((frameCurrent != oldframeCurrent || frameTarget != oldframeTarget) && !calcrot)) {
4172 for (int i = 0; i < skeleton.num_joints; i++) {
4173 skeleton.joints[i].position = animation[animCurrent].position[i][frameCurrent];
4176 skeleton.FindForwards();
4178 for (int i = 0; i < skeleton.num_muscles; i++) {
4179 if (skeleton.muscles[i].visible) {
4180 skeleton.FindRotationMuscle(i, animTarget);
4183 for (int i = 0; i < skeleton.num_muscles; i++) {
4184 if (skeleton.muscles[i].visible) {
4185 if (isnormal((float)((int)(skeleton.muscles[i].rotate1 * 100) % 36000) / 100))
4186 skeleton.muscles[i].oldrotate1 = (float)((int)(skeleton.muscles[i].rotate1 * 100) % 36000) / 100;
4187 if (isnormal((float)((int)(skeleton.muscles[i].rotate2 * 100) % 36000) / 100))
4188 skeleton.muscles[i].oldrotate2 = (float)((int)(skeleton.muscles[i].rotate2 * 100) % 36000) / 100;
4189 if (isnormal((float)((int)(skeleton.muscles[i].rotate3 * 100) % 36000) / 100))
4190 skeleton.muscles[i].oldrotate3 = (float)((int)(skeleton.muscles[i].rotate3 * 100) % 36000) / 100;
4195 for (int i = 0; i < skeleton.num_joints; i++) {
4196 skeleton.joints[i].position = animation[animTarget].position[i][frameTarget];
4199 skeleton.FindForwards();
4201 for (int i = 0; i < skeleton.num_muscles; i++) {
4202 if (skeleton.muscles[i].visible) {
4203 skeleton.FindRotationMuscle(i, animTarget);
4206 for (int i = 0; i < skeleton.num_muscles; i++) {
4207 if (skeleton.muscles[i].visible) {
4208 if (isnormal((float)((int)(skeleton.muscles[i].rotate1 * 100) % 36000) / 100))
4209 skeleton.muscles[i].newrotate1 = (float)((int)(skeleton.muscles[i].rotate1 * 100) % 36000) / 100;
4210 if (isnormal((float)((int)(skeleton.muscles[i].rotate2 * 100) % 36000) / 100))
4211 skeleton.muscles[i].newrotate2 = (float)((int)(skeleton.muscles[i].rotate2 * 100) % 36000) / 100;
4212 if (isnormal((float)((int)(skeleton.muscles[i].rotate3 * 100) % 36000) / 100))
4213 skeleton.muscles[i].newrotate3 = (float)((int)(skeleton.muscles[i].rotate3 * 100) % 36000) / 100;
4214 if (skeleton.muscles[i].newrotate3 > skeleton.muscles[i].oldrotate3 + 180) skeleton.muscles[i].newrotate3 -= 360;
4215 if (skeleton.muscles[i].newrotate3 < skeleton.muscles[i].oldrotate3 - 180) skeleton.muscles[i].newrotate3 += 360;
4216 if (skeleton.muscles[i].newrotate2 > skeleton.muscles[i].oldrotate2 + 180) skeleton.muscles[i].newrotate2 -= 360;
4217 if (skeleton.muscles[i].newrotate2 < skeleton.muscles[i].oldrotate2 - 180) skeleton.muscles[i].newrotate2 += 360;
4218 if (skeleton.muscles[i].newrotate1 > skeleton.muscles[i].oldrotate1 + 180) skeleton.muscles[i].newrotate1 -= 360;
4219 if (skeleton.muscles[i].newrotate1 < skeleton.muscles[i].oldrotate1 - 180) skeleton.muscles[i].newrotate1 += 360;
4223 if (frameCurrent >= animation[animCurrent].numframes)
4224 frameCurrent = animation[animCurrent].numframes - 1;
4226 oldanimCurrent = animCurrent;
4227 oldanimTarget = animTarget;
4228 oldframeTarget = frameTarget;
4229 oldframeCurrent = frameCurrent;
4231 for (int i = 0; i < skeleton.num_joints; i++) {
4232 skeleton.joints[i].velocity = (animation[animCurrent].position[i][frameCurrent] * (1 - target) + animation[animTarget].position[i][frameTarget] * (target) - skeleton.joints[i].position) / multiplier;
4233 skeleton.joints[i].position = animation[animCurrent].position[i][frameCurrent] * (1 - target) + animation[animTarget].position[i][frameTarget] * (target);
4235 offset = currentoffset * (1 - target) + targetoffset * target;
4236 for (int i = 0; i < skeleton.num_muscles; i++) {
4237 if (skeleton.muscles[i].visible) {
4238 skeleton.muscles[i].rotate1 = skeleton.muscles[i].oldrotate1 * (1 - target) + skeleton.muscles[i].newrotate1 * (target);
4239 skeleton.muscles[i].rotate2 = skeleton.muscles[i].oldrotate2 * (1 - target) + skeleton.muscles[i].newrotate2 * (target);
4240 skeleton.muscles[i].rotate3 = skeleton.muscles[i].oldrotate3 * (1 - target) + skeleton.muscles[i].newrotate3 * (target);
4245 if (isLanding() && landhard) {
4248 animTarget = getLandhard();
4261 void Person::DoStuff()
4263 static XYZ terrainnormal;
4264 static XYZ flatfacing;
4265 static XYZ flatvelocity;
4266 static float flatvelspeed;
4270 static int bloodsize;
4271 static int startx, starty, endx, endy;
4272 static GLubyte color;
4273 static XYZ bloodvel;
4275 onfiredelay -= multiplier;
4276 if (onfiredelay < 0 && onfire) {
4277 if (Random() % 2 == 0) {
4283 crouchkeydowntime += multiplier;
4285 crouchkeydowntime = 0;
4286 jumpkeydowntime += multiplier;
4287 if (!jumpkeydown && skeleton.free)
4288 jumpkeydowntime = 0;
4290 if (hostile || damage > 0 || bloodloss > 0)
4293 if (isIdle() || isRun())
4296 if (num_weapons == 1 && weaponactive != -1)
4300 blooddimamount -= multiplier * .3;
4301 speechdelay -= multiplier;
4302 texupdatedelay -= multiplier;
4303 interestdelay -= multiplier;
4304 flamedelay -= multiplier;
4305 parriedrecently -= multiplier;
4307 victim = this->shared_from_this();
4312 speed = 1.1 * speedmult;
4314 speed = 1.0 * speedmult;
4316 rabbitkickragdoll = 0;
4320 if (id != 0 && (creature == rabbittype || difficulty != 2))
4322 if (id != 0 && creature == wolftype && difficulty == 2) {
4324 if (aitype != passivetype) {
4326 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) {
4332 if (animTarget == wolfrunninganim && !superruntoggle) {
4333 animTarget = getRun();
4337 if (weaponactive == -1 && num_weapons > 0) {
4338 if (weapons[weaponids[0]].getType() == staff) {
4344 burnt += multiplier;
4348 OPENAL_SetVolume(channels[stream_firesound], 256 + 256 * findLength(&velocity) / 3);
4350 if (animTarget == jumpupanim || animTarget == jumpdownanim || isFlip()) {
4356 vel[0] = velocity.x;
4357 vel[1] = velocity.y;
4358 vel[2] = velocity.z;
4361 OPENAL_3D_SetAttributes(channels[whooshsound], gLoc, vel);
4362 OPENAL_SetVolume(channels[whooshsound], 64 * findLength(&velocity) / 5);
4366 while (flamedelay < 0 && onfire) {
4368 howmany = abs(Random() % (skeleton.num_joints));
4369 if (skeleton.free) {
4370 flatvelocity = skeleton.joints[howmany].velocity * scale / 2;
4371 flatfacing = skeleton.joints[howmany].position * scale + coords;
4373 flatfacing = DoRotation(DoRotation(DoRotation(skeleton.joints[howmany].position, 0, 0, tilt), tilt2, 0, 0), 0, yaw, 0) * scale + coords;
4374 flatvelocity = (coords - oldcoords) / multiplier / 2;
4376 Sprite::MakeSprite(flamesprite, flatfacing, flatvelocity, 1, 1, 1, .6 + (float)abs(Random() % 100) / 200 - .25, 1);
4379 while (flamedelay < 0 && !onfire && tutoriallevel == 1 && id != 0) {
4381 howmany = abs(Random() % (skeleton.num_joints));
4382 if (skeleton.free) {
4383 flatvelocity = skeleton.joints[howmany].velocity * scale / 2;
4384 flatfacing = skeleton.joints[howmany].position * scale + coords;
4386 flatvelocity = (coords - oldcoords) / multiplier / 2;
4387 flatfacing = DoRotation(DoRotation(DoRotation(skeleton.joints[howmany].position, 0, 0, tilt), tilt2, 0, 0), 0, yaw, 0) * scale + coords;
4389 Sprite::MakeSprite(breathsprite, flatfacing, flatvelocity, 1, 1, 1, .6 + (float)abs(Random() % 100) / 200 - .25, .3);
4393 bleeding -= multiplier * .3;
4394 if (bloodtoggle == 2) {
4395 skeleton.drawmodel.textureptr.bind();
4396 if ((bleeding <= 0) && (detail != 2))
4401 if (neckspurtamount > 0) {
4402 neckspurtamount -= multiplier;
4403 neckspurtdelay -= multiplier * 3;
4404 neckspurtparticledelay -= multiplier * 3;
4405 if (neckspurtparticledelay < 0 && neckspurtdelay > 2) {
4408 if (skeleton.free) {
4409 bloodvel -= DoRotation(skeleton.forward * 10 * scale, ((float)(Random() % 100)) / 40, ((float)(Random() % 100)) / 40, 0);
4410 bloodvel += DoRotation(jointVel(head), ((float)(Random() % 100)) / 40, yaw + ((float)(Random() % 100)) / 40, 0) * scale;
4411 Sprite::MakeSprite(bloodsprite, (jointPos(neck) + (jointPos(neck) - jointPos(head)) / 5)*scale + coords, bloodvel, 1, 1, 1, .05, .9);
4413 bloodvel.z = 5 * neckspurtamount;
4414 bloodvel = DoRotation(bloodvel, ((float)(Random() % 100)) / 40, yaw + ((float)(Random() % 100)) / 40, 0) * scale;
4415 bloodvel += DoRotation(velocity, ((float)(Random() % 100)) / 40, ((float)(Random() % 100)) / 40, 0) * scale;
4416 Sprite::MakeSprite(bloodsprite, DoRotation(jointPos(neck) + (jointPos(neck) - jointPos(head)) / 5, 0, yaw, 0)*scale + coords, bloodvel, 1, 1, 1, .05, .9);
4418 neckspurtparticledelay = .05;
4420 if (neckspurtdelay < 0) {
4425 if (deathbleeding > 0 && dead != 2) {
4426 if (deathbleeding < 5)
4427 bleeddelay -= deathbleeding * multiplier / 4;
4429 bleeddelay -= 5 * multiplier / 4;
4430 if (bleeddelay < 0 && bloodtoggle) {
4435 if (skeleton.free) {
4436 bloodvel += DoRotation(jointVel(abdomen), ((float)(Random() % 100)) / 4, yaw + ((float)(Random() % 100)) / 4, 0) * scale;
4437 Sprite::MakeSprite(bloodsprite, jointPos(abdomen) * scale + coords, bloodvel, 1, 1, 1, .05, 1);
4439 bloodvel += DoRotation(velocity, ((float)(Random() % 100)) / 4, ((float)(Random() % 100)) / 4, 0) * scale;
4440 Sprite::MakeSprite(bloodsprite, DoRotation((jointPos(abdomen) + jointPos(abdomen)) / 2, 0, yaw, 0)*scale + coords, bloodvel, 1, 1, 1, .05, 1);
4444 bloodloss += deathbleeding * multiplier * 80;
4445 deathbleeding -= multiplier * 1.6;
4446 if (deathbleeding < 0)
4448 if (bloodloss > damagetolerance && animation[animTarget].attack == neutral) {
4449 if (weaponactive != -1) {
4450 weapons[weaponids[0]].drop(velocity * scale * -.3, velocity * scale);
4451 weapons[weaponids[0]].velocity.x += .01;
4454 weaponids[0] = weaponids[num_weapons];
4455 if (weaponstuck == num_weapons)
4459 for (unsigned i = 0; i < Person::players.size(); i++) {
4460 Person::players[i]->wentforweapon = 0;
4468 if (!dead && creature == wolftype) {
4469 award_bonus(0, Wolfbonus);
4472 if (animTarget == knifefollowedanim && !skeleton.free) {
4473 for (int i = 0; i < skeleton.num_joints; i++) {
4474 skeleton.joints[i].velocity = 0;
4475 skeleton.joints[i].velocity.y = -2;
4478 if (id != 0 && unconscioustime > .1) {
4486 if (texupdatedelay < 0 && bleeding > 0 && bloodtoggle == 2 && distsq(&viewer, &coords) < 9) {
4487 texupdatedelay = .12;
4489 bloodsize = 5 - realtexdetail;
4493 startx = bleedy; //abs(Random()%(skeleton.skinsize-bloodsize-1));
4494 starty = bleedx; //abs(Random()%(skeleton.skinsize-bloodsize-1));
4495 endx = startx + bloodsize;
4496 endy = starty + bloodsize;
4506 if (endx > skeleton.skinsize - 1) {
4507 endx = skeleton.skinsize - 1;
4510 if (endy > skeleton.skinsize - 1) {
4511 endy = skeleton.skinsize - 1;
4519 for (i = startx; i < endx; i++) {
4520 for (j = starty; j < endy; j++) {
4521 if (Random() % 2 == 0) {
4522 color = Random() % 85 + 170;
4523 if (skeleton.skinText[i * skeleton.skinsize * 3 + j * 3 + 0] > color / 2)
4524 skeleton.skinText[i * skeleton.skinsize * 3 + j * 3 + 0] = color / 2;
4525 skeleton.skinText[i * skeleton.skinsize * 3 + j * 3 + 1] = 0;
4526 skeleton.skinText[i * skeleton.skinsize * 3 + j * 3 + 2] = 0;
4531 skeleton.drawmodel.textureptr.bind();
4535 if (skeleton.free) {
4536 bleedx += 4 * direction / realtexdetail;
4538 bleedy += (abs(Random() % 3) - 1) * 2 / realtexdetail;
4540 bleedy += (abs(Random() % 3) - 1) * 4 / realtexdetail;
4542 bleedy -= 4 / realtexdetail;
4544 bleedx += (abs(Random() % 3) - 1) * 2 / realtexdetail;
4546 bleedx += (abs(Random() % 3) - 1) * 4 / realtexdetail;
4550 if (abs(righthandmorphness - targetrighthandmorphness) < multiplier * 4) {
4551 righthandmorphness = targetrighthandmorphness;
4552 righthandmorphstart = righthandmorphend;
4553 } else if (righthandmorphness > targetrighthandmorphness) {
4554 righthandmorphness -= multiplier * 4;
4555 } else if (righthandmorphness < targetrighthandmorphness) {
4556 righthandmorphness += multiplier * 4;
4559 if (abs(lefthandmorphness - targetlefthandmorphness) < multiplier * 4) {
4560 lefthandmorphness = targetlefthandmorphness;
4561 lefthandmorphstart = lefthandmorphend;
4562 } else if (lefthandmorphness > targetlefthandmorphness) {
4563 lefthandmorphness -= multiplier * 4;
4564 } else if (lefthandmorphness < targetlefthandmorphness) {
4565 lefthandmorphness += multiplier * 4;
4568 if (creature == rabbittype || targettailmorphness == 5 || targettailmorphness == 0) {
4569 if (abs(tailmorphness - targettailmorphness) < multiplier * 10) {
4570 tailmorphness = targettailmorphness;
4571 tailmorphstart = tailmorphend;
4572 } else if (tailmorphness > targettailmorphness) {
4573 tailmorphness -= multiplier * 10;
4574 } else if (tailmorphness < targettailmorphness) {
4575 tailmorphness += multiplier * 10;
4579 if (creature == wolftype) {
4580 if (abs(tailmorphness - targettailmorphness) < multiplier * 4) {
4581 tailmorphness = targettailmorphness;
4582 tailmorphstart = tailmorphend;
4583 } else if (tailmorphness > targettailmorphness) {
4584 tailmorphness -= multiplier * 2;
4585 } else if (tailmorphness < targettailmorphness) {
4586 tailmorphness += multiplier * 2;
4590 if (headmorphend == 3 || headmorphstart == 3) {
4591 if (abs(headmorphness - targetheadmorphness) < multiplier * 7) {
4592 headmorphness = targetheadmorphness;
4593 headmorphstart = headmorphend;
4594 } else if (headmorphness > targetheadmorphness) {
4595 headmorphness -= multiplier * 7;
4596 } else if (headmorphness < targetheadmorphness) {
4597 headmorphness += multiplier * 7;
4599 } else if (headmorphend == 5 || headmorphstart == 5) {
4600 if (abs(headmorphness - targetheadmorphness) < multiplier * 10) {
4601 headmorphness = targetheadmorphness;
4602 headmorphstart = headmorphend;
4603 } else if (headmorphness > targetheadmorphness) {
4604 headmorphness -= multiplier * 10;
4605 } else if (headmorphness < targetheadmorphness) {
4606 headmorphness += multiplier * 10;
4609 if (abs(headmorphness - targetheadmorphness) < multiplier * 4) {
4610 headmorphness = targetheadmorphness;
4611 headmorphstart = headmorphend;
4612 } else if (headmorphness > targetheadmorphness) {
4613 headmorphness -= multiplier * 4;
4614 } else if (headmorphness < targetheadmorphness) {
4615 headmorphness += multiplier * 4;
4619 if (abs(chestmorphness - targetchestmorphness) < multiplier) {
4620 chestmorphness = targetchestmorphness;
4621 chestmorphstart = chestmorphend;
4622 } else if (chestmorphness > targetchestmorphness) {
4623 chestmorphness -= multiplier;
4624 } else if (chestmorphness < targetchestmorphness) {
4625 chestmorphness += multiplier;
4628 if (dead != 2 && howactive <= typesleeping) {
4629 if (chestmorphstart == 0 && chestmorphend == 0) {
4631 targetchestmorphness = 1;
4634 if (chestmorphstart != 0 && chestmorphend != 0) {
4636 targetchestmorphness = 1;
4638 if (environment == snowyenvironment) {
4641 if (skeleton.free) {
4642 footvel = skeleton.specialforward[0] * -1;
4643 footpoint = ((jointPos(head) + jointPos(neck)) / 2) * scale + coords;
4645 footvel = DoRotation(skeleton.specialforward[0], 0, yaw, 0) * -1;
4646 footpoint = DoRotation((jointPos(head) + jointPos(neck)) / 2, 0, yaw, 0) * scale + coords;
4648 if (animTarget == sleepanim)
4649 footvel = DoRotation(footvel, 0, 90, 0);
4650 Sprite::MakeSprite(breathsprite, footpoint + footvel * .2, footvel * .4, 1, 1, 1, .4, .3);
4654 if (!dead && howactive < typesleeping) {
4655 blinkdelay -= multiplier * 2;
4656 if (headmorphstart == 0 && headmorphend == 0 && blinkdelay <= 0) {
4658 targetheadmorphness = 1;
4660 blinkdelay = (float)(abs(Random() % 40)) / 5;
4662 if (headmorphstart == 3 && headmorphend == 3) {
4664 targetheadmorphness = 1;
4669 twitchdelay -= multiplier * 1.5;
4670 if (animTarget != hurtidleanim) {
4671 if (headmorphstart == 0 && headmorphend == 0 && twitchdelay <= 0) {
4673 targetheadmorphness = 1;
4675 twitchdelay = (float)(abs(Random() % 40)) / 5;
4677 if (headmorphstart == 5 && headmorphend == 5) {
4679 targetheadmorphness = 1;
4683 if ((isIdle() || isCrouch()) && animTarget != hurtidleanim) {
4684 twitchdelay3 -= multiplier * 1;
4685 if (Random() % 2 == 0) {
4686 if (righthandmorphstart == 0 && righthandmorphend == 0 && twitchdelay3 <= 0) {
4687 righthandmorphness = 0;
4688 targetrighthandmorphness = 1;
4689 righthandmorphend = 1;
4690 if (Random() % 2 == 0)twitchdelay3 = (float)(abs(Random() % 40)) / 5;
4692 if (righthandmorphstart == 1 && righthandmorphend == 1) {
4693 righthandmorphness = 0;
4694 targetrighthandmorphness = 1;
4695 righthandmorphend = 0;
4698 if (Random() % 2 == 0) {
4699 if (lefthandmorphstart == 0 && lefthandmorphend == 0 && twitchdelay3 <= 0) {
4700 lefthandmorphness = 0;
4701 targetlefthandmorphness = 1;
4702 lefthandmorphend = 1;
4703 twitchdelay3 = (float)(abs(Random() % 40)) / 5;
4705 if (lefthandmorphstart == 1 && lefthandmorphend == 1) {
4706 lefthandmorphness = 0;
4707 targetlefthandmorphness = 1;
4708 lefthandmorphend = 0;
4714 if (creature == rabbittype) {
4715 if (howactive < typesleeping)
4716 twitchdelay2 -= multiplier * 1.5;
4718 twitchdelay2 -= multiplier * 0.5;
4719 if (howactive <= typesleeping) {
4720 if (tailmorphstart == 0 && tailmorphend == 0 && twitchdelay2 <= 0) {
4722 targettailmorphness = 1;
4724 twitchdelay2 = (float)(abs(Random() % 40)) / 5;
4726 if (tailmorphstart == 1 && tailmorphend == 1) {
4728 targettailmorphness = 1;
4731 if (tailmorphstart == 2 && tailmorphend == 2) {
4733 targettailmorphness = 1;
4740 if (creature == wolftype) {
4741 twitchdelay2 -= multiplier * 1.5;
4742 if (tailmorphend != 0)
4743 if ((isRun() || animTarget == jumpupanim || animTarget == jumpdownanim || animTarget == backflipanim) && !skeleton.free) {
4745 targettailmorphness = 1;
4749 if (tailmorphend != 5)
4750 if (animTarget == flipanim || animTarget == frontflipanim || animTarget == rollanim || skeleton.free) {
4752 targettailmorphness = 1;
4756 if (twitchdelay2 <= 0) {
4757 if (((tailmorphstart == 0 && tailmorphend == 0) || (tailmorphstart == 5 && tailmorphend == 5))) {
4759 targettailmorphness = 1;
4762 if (tailmorphstart == 1 && tailmorphend == 1) {
4764 targettailmorphness = 1;
4767 if (tailmorphstart == 2 && tailmorphend == 2) {
4769 targettailmorphness = 1;
4772 if (tailmorphstart == 3 && tailmorphend == 3) {
4774 targettailmorphness = 1;
4777 if (tailmorphstart == 4 && tailmorphend == 4) {
4779 targettailmorphness = 1;
4786 unconscioustime = 0;
4788 if (dead == 1 || howactive == typesleeping) {
4789 unconscioustime += multiplier;
4790 //If unconscious, close eyes and mouth
4791 if (righthandmorphend != 0)
4792 righthandmorphness = 0;
4793 righthandmorphend = 0;
4794 targetrighthandmorphness = 1;
4796 if (lefthandmorphend != 0)
4797 lefthandmorphness = 0;
4798 lefthandmorphend = 0;
4799 targetlefthandmorphness = 1;
4801 if (headmorphend != 3 && headmorphend != 5)
4804 targetheadmorphness = 1;
4808 if (howactive > typesleeping) {
4811 if (bloodtoggle && !bled) {
4812 terrain.MakeDecal(blooddecalslow, headpoint, .8, .5, 0);
4814 if (bloodtoggle && !bled)
4815 for (l = 0; l < terrain.patchobjectnum[whichpatchx][whichpatchz]; l++) {
4816 j = terrain.patchobjects[whichpatchx][whichpatchz][l];
4817 XYZ point = DoRotation(headpoint - objects.position[j], 0, -objects.yaw[j], 0);
4821 objects.model[j].MakeDecal(blooddecalslow, &point, &size, &opacity, &yaw);
4826 if (dead == 2 || howactive > typesleeping) {
4827 //If dead, open mouth and hands
4828 if (righthandmorphend != 0)
4829 righthandmorphness = 0;
4830 righthandmorphend = 0;
4831 targetrighthandmorphness = 1;
4833 if (lefthandmorphend != 0)
4834 lefthandmorphness = 0;
4835 lefthandmorphend = 0;
4836 targetlefthandmorphness = 1;
4838 if (headmorphend != 2)
4841 targetheadmorphness = 1;
4844 if (stunned > 0 && !dead && headmorphend != 2) {
4845 if (headmorphend != 4)
4848 targetheadmorphness = 1;
4851 if (damage > damagetolerance && !dead) {
4854 unconscioustime = 0;
4856 if (creature == wolftype) {
4857 award_bonus(0, Wolfbonus);
4862 if (weaponactive != -1) {
4863 weapons[weaponids[0]].drop(velocity * scale * -.3, velocity * scale);
4864 weapons[weaponids[0]].velocity.x += .01;
4867 weaponids[0] = weaponids[num_weapons];
4868 if (weaponstuck == num_weapons)
4872 for (unsigned i = 0; i < Person::players.size(); i++) {
4873 Person::players[i]->wentforweapon = 0;
4879 if ((id == 0 || distsq(&coords, &viewer) < 50) && autoslomo) {
4888 damage -= multiplier * 13;
4890 permanentdamage -= multiplier * 4;
4891 if (isIdle() || isCrouch()) {
4893 permanentdamage -= multiplier * 4;
4897 if (permanentdamage < 0)
4898 permanentdamage = 0;
4899 if (superpermanentdamage < 0)
4900 superpermanentdamage = 0;
4901 if (permanentdamage < superpermanentdamage) {
4902 permanentdamage = superpermanentdamage;
4904 if (damage < permanentdamage) {
4905 damage = permanentdamage;
4907 if (dead == 1 && damage < damagetolerance) {
4911 for (int i = 0; i < skeleton.num_joints; i++) {
4912 skeleton.joints[i].velocity = 0;
4915 if (permanentdamage > damagetolerance && dead != 2) {
4918 if (weaponactive != -1) {
4919 weapons[weaponids[0]].drop(velocity * scale * -.3, velocity * scale);
4920 weapons[weaponids[0]].velocity.x += .01;
4923 weaponids[0] = weaponids[num_weapons];
4924 if (weaponstuck == num_weapons)
4928 for (unsigned i = 0; i < Person::players.size(); i++) {
4929 Person::players[i]->wentforweapon = 0;
4935 if (!dead && creature == wolftype) {
4936 award_bonus(0, Wolfbonus);
4939 if (unconscioustime < .1 && (bonus != spinecrusher || bonustime > 1) && (bonus != FinishedBonus || bonustime > 1) && bloodloss < damagetolerance)
4940 award_bonus(id, touchofdeath);
4941 if (id != 0 && unconscioustime > .1) {
4949 emit_sound_at(breaksound, coords);
4952 if (skeleton.free == 1) {
4954 pause_sound(whooshsound);
4957 //If knocked over, open hands and close mouth
4958 if (righthandmorphend != 0)
4959 righthandmorphness = 0;
4960 righthandmorphend = 0;
4961 targetrighthandmorphness = 1;
4963 if (lefthandmorphend != 0)
4964 lefthandmorphness = 0;
4965 lefthandmorphend = 0;
4966 targetlefthandmorphness = 1;
4968 if (headmorphend != 3 && headmorphend != 5 && headmorphstart != 3 && headmorphstart != 5) {
4969 if (headmorphend != 0)
4972 targetheadmorphness = 1;
4976 skeleton.DoGravity(&scale);
4978 damageamount = skeleton.DoConstraints(&coords, &scale) * 5;
4979 if (damage > damagetolerance - damageamount && !dead && (bonus != spinecrusher || bonustime > 1) && (bonus != style || bonustime > 1) && (bonus != cannon || bonustime > 1))
4980 award_bonus(id, deepimpact);
4981 DoDamage(damageamount / ((protectionhigh + protectionhead + protectionlow) / 3));
4985 for (j = 0; j < skeleton.num_joints; j++) {
4986 average += skeleton.joints[j].position;
4990 coords += average * scale;
4991 for (j = 0; j < skeleton.num_joints; j++) {
4992 skeleton.joints[j].position -= average;
4994 average /= multiplier;
4997 for (int i = 0; i < skeleton.num_joints; i++) {
4998 velocity += skeleton.joints[i].velocity * scale;
5000 velocity /= skeleton.num_joints;
5002 if (!isnormal(velocity.x) && velocity.x) {
5006 if (findLength(&average) < 10 && dead && skeleton.free) {
5007 skeleton.longdead += (2000 - findLength(&average)) * multiplier + multiplier;
5008 if (skeleton.longdead > 2000) {
5009 if (skeleton.longdead > 6000) {
5011 pause_sound(whooshsound);
5016 if (dead == 2 && bloodloss < damagetolerance) {
5018 headpoint = (jointPos(head) + jointPos(neck)) / 2 * scale + coords;
5020 if (bloodtoggle && !bled) {
5021 terrain.MakeDecal(blooddecal, headpoint, .2 * 1.2, .5, 0);
5023 if (bloodtoggle && !bled)
5024 for (l = 0; l < terrain.patchobjectnum[whichpatchx][whichpatchz]; l++) {
5025 j = terrain.patchobjects[whichpatchx][whichpatchz][l];
5026 XYZ point = DoRotation(headpoint - objects.position[j], 0, -objects.yaw[j], 0);
5027 float size = .2 * 1.2;
5030 objects.model[j].MakeDecal(blooddecal, &point, &size, &opacity, &yaw);
5034 if (dead == 2 && bloodloss >= damagetolerance) {
5036 headpoint = (jointPos(abdomen) + jointPos(neck)) / 2 * scale + coords;
5039 if (bloodtoggle && !bled) {
5040 terrain.MakeDecal(blooddecalslow, headpoint, .8, .5, 0);
5042 if (bloodtoggle && !bled)
5043 for (l = 0; l < terrain.patchobjectnum[whichpatchx][whichpatchz]; l++) {
5044 j = terrain.patchobjects[whichpatchx][whichpatchz][l];
5045 XYZ point = DoRotation(headpoint - objects.position[j], 0, -objects.yaw[j], 0);
5049 objects.model[j].MakeDecal(blooddecalslow, &point, &size, &opacity, &yaw);
5056 if (!dead && crouchkeydown && skeleton.freetime > .5 && id == 0 && skeleton.free) {
5057 bool canrecover = 1;
5058 XYZ startpoint, endpoint, colpoint, colviewer, coltarget;
5059 startpoint = coords;
5062 if (terrain.lineTerrain(startpoint, endpoint, &colpoint) != -1)
5064 if (velocity.y < -30)
5066 for (i = 0; i < objects.numobjects; i++) {
5067 if (objects.type[i] != treeleavestype && objects.type[i] != bushtype && objects.type[i] != firetype) {
5068 colviewer = startpoint;
5069 coltarget = endpoint;
5070 if (objects.model[i].LineCheck(&colviewer, &coltarget, &colpoint, &objects.position[i], &objects.yaw[i]) != -1)
5079 terrainnormal = jointPos(groin) - jointPos(abdomen);
5080 if (joint(groin).locked && joint(abdomen).locked) {
5081 terrainnormal = jointPos(groin) - jointPos(abdomen);
5082 middle = (jointPos(groin) + jointPos(abdomen)) / 2;
5084 if (joint(abdomen).locked && joint(neck).locked) {
5085 terrainnormal = jointPos(abdomen) - jointPos(neck);
5086 middle = (jointPos(neck) + jointPos(abdomen)) / 2;
5088 if (joint(groin).locked && joint(neck).locked) {
5089 terrainnormal = jointPos(groin) - jointPos(neck);
5090 middle = (jointPos(groin) + jointPos(neck)) / 2;
5092 Normalise(&terrainnormal);
5094 targetyaw = -asin(0 - terrainnormal.x);
5095 targetyaw *= 360 / 6.28;
5096 if (terrainnormal.z < 0)
5097 targetyaw = 180 - targetyaw;
5101 animTarget = flipanim;
5102 crouchtogglekeydown = 1;
5107 animCurrent = tempanim;
5111 for (int i = 0; i < skeleton.num_joints; i++) {
5112 tempanimation.position[i][0] = skeleton.joints[i].position;
5113 tempanimation.position[i][0] = DoRotation(tempanimation.position[i][0], 0, -yaw, 0);
5118 if (findLength(&average) < 10 && !dead && skeleton.free) {
5119 skeleton.longdead += (2000 - findLength(&average)) * multiplier + multiplier;
5120 if (skeleton.longdead > (damage + 500) * 1.5) {
5122 pause_sound(whooshsound);
5128 terrainnormal = jointPos(groin) - jointPos(abdomen);
5129 if (joint(groin).locked && joint(abdomen).locked) {
5130 terrainnormal = jointPos(groin) - jointPos(abdomen);
5131 middle = (jointPos(groin) + jointPos(abdomen)) / 2;
5133 if (joint(abdomen).locked && joint(neck).locked) {
5134 terrainnormal = jointPos(abdomen) - jointPos(neck);
5135 middle = (jointPos(neck) + jointPos(abdomen)) / 2;
5137 if (joint(groin).locked && joint(neck).locked) {
5138 terrainnormal = jointPos(groin) - jointPos(neck);
5139 middle = (jointPos(groin) + jointPos(neck)) / 2;
5141 Normalise(&terrainnormal);
5143 targetyaw = -asin(0 - terrainnormal.x);
5144 targetyaw *= 360 / 6.28;
5145 if (terrainnormal.z < 0)
5146 targetyaw = 180 - targetyaw;
5149 targettilt2 = asin(terrainnormal.y) * 180 / 3.14 * -1;
5152 if (skeleton.forward.y < 0) {
5153 animTarget = getupfrombackanim;
5157 if (skeleton.forward.y > -.3) {
5158 animTarget = getupfromfrontanim;
5166 if ((Random() % 8 == 0 && id != 0 && creature == rabbittype) || (Random() % 2 == 0 && id != 0 && creature == wolftype) || (id == 0 && crouchkeydown && (forwardkeydown || backkeydown || leftkeydown || rightkeydown))) {
5167 animTarget = rollanim;
5168 targetyaw = lookyaw;
5185 if ( !leftkeydown && !rightkeydown)
5192 if (abs(targettilt2) > 50)
5194 animCurrent = tempanim;
5197 tilt2 = targettilt2;
5199 if (middle.y > 0 && animTarget != rollanim)
5200 targetoffset.y = middle.y + 1;
5202 for (int i = 0; i < skeleton.num_joints; i++) {
5203 tempanimation.position[i][0] = skeleton.joints[i].position;
5204 tempanimation.position[i][0] = DoRotation(tempanimation.position[i][0], 0, -yaw, 0);
5211 if (num_weapons > 0)
5212 if (weapons[0].getType() == staff)
5214 if (!skeleton.freefall && freefall && ((jumpkeydown && jumpkeydowntime < .2) || (hasstaff && rabbitkickragdoll)) && !dead) {
5215 if (velocity.y > -30) {
5217 tempvelocity = velocity;
5218 Normalise(&tempvelocity);
5219 targetyaw = -asin(0 - tempvelocity.x);
5220 targetyaw *= 360 / 6.28;
5222 targetyaw = 180 - targetyaw;
5226 if (dotproduct(&skeleton.forward, &tempvelocity) < 0) {
5227 animTarget = rollanim;
5230 animTarget = backhandspringanim;
5236 emit_sound_at(movewhooshsound, coords, 128.);
5238 animCurrent = animTarget;
5239 frameCurrent = frameTarget - 1;
5251 if (skeleton.freefall == 0)
5256 if (aitype != passivetype || skeleton.free == 1)
5257 if (findLengthfast(&velocity) > .1)
5258 for (i = 0; i < objects.numobjects; i++) {
5259 if (objects.type[i] == firetype)
5260 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) {
5262 if (!objects.onfire[i]) {
5263 emit_sound_at(firestartsound, objects.position[i]);
5265 objects.onfire[i] = 1;
5268 if (objects.onfire[i]) {
5273 if (objects.type[i] == bushtype)
5274 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) {
5276 if (!objects.onfire[i]) {
5277 emit_sound_at(firestartsound, objects.position[i]);
5279 objects.onfire[i] = 1;
5283 if (objects.onfire[i]) {
5287 if (objects.messedwith[i] <= 0) {
5291 emit_sound_at(bushrustle, coords, 40 * findLength(&velocity));
5294 addEnvSound(coords, 4 * findLength(&velocity));
5298 if (environment == grassyenvironment)
5299 howmany = findLength(&velocity) * 4;
5300 if (environment == snowyenvironment)
5301 howmany = findLength(&velocity) * 2;
5303 if (environment != desertenvironment)
5304 for (j = 0; j < howmany; j++) {
5305 tempvel.x = float(abs(Random() % 100) - 50) / 20;
5306 tempvel.y = float(abs(Random() % 100) - 50) / 20;
5307 tempvel.z = float(abs(Random() % 100) - 50) / 20;
5310 pos.x += float(abs(Random() % 100) - 50) / 200;
5311 pos.y += float(abs(Random() % 100) - 50) / 200;
5312 pos.z += float(abs(Random() % 100) - 50) / 200;
5313 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);
5314 Sprite::setLastSpriteSpecial(1);
5316 howmany = findLength(&velocity) * 4;
5318 if (environment == snowyenvironment)
5319 for (j = 0; j < howmany; j++) {
5320 tempvel.x = float(abs(Random() % 100) - 50) / 20;
5321 tempvel.y = float(abs(Random() % 100) - 50) / 20;
5322 tempvel.z = float(abs(Random() % 100) - 50) / 20;
5325 pos.x += float(abs(Random() % 100) - 50) / 200;
5326 pos.y += float(abs(Random() % 100) - 50) / 200;
5327 pos.z += float(abs(Random() % 100) - 50) / 200;
5328 Sprite::MakeSprite(splintersprite, pos, tempvel * .3 + velocity * float(abs(Random() % 100)) / 100 / 2, 1, 1, 1, .1, 1);
5329 Sprite::setLastSpriteSpecial(2);
5332 objects.rotx[i] += velocity.x * multiplier * 6;
5333 objects.roty[i] += velocity.z * multiplier * 6;
5334 objects.messedwith[i] = .5;
5337 if (objects.type[i] == treeleavestype && environment != desertenvironment) {
5338 if (objects.pitch[i] == 0)
5341 tempcoord = coords - objects.position[i];
5342 tempcoord = DoRotation(tempcoord, 0, -objects.yaw[i], 0);
5343 tempcoord = DoRotation(tempcoord, -objects.pitch[i], 0, 0);
5344 tempcoord += objects.position[i];
5346 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]) {
5347 if (objects.messedwith[i] <= 0) {
5351 emit_sound_at(bushrustle, coords, 40 * findLength(&velocity));
5354 addEnvSound(coords, 4 * findLength(&velocity));
5358 if (environment == grassyenvironment)
5359 howmany = findLength(&velocity) * 4;
5360 if (environment == snowyenvironment)
5361 howmany = findLength(&velocity) * 2;
5363 if (environment != desertenvironment)
5364 for (j = 0; j < howmany; j++) {
5365 tempvel.x = float(abs(Random() % 100) - 50) / 20;
5366 tempvel.y = float(abs(Random() % 100) - 50) / 20;
5367 tempvel.z = float(abs(Random() % 100) - 50) / 20;
5369 pos += velocity * .1;
5371 pos.x += float(abs(Random() % 100) - 50) / 150;
5372 pos.y += float(abs(Random() % 100) - 50) / 150;
5373 pos.z += float(abs(Random() % 100) - 50) / 150;
5374 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);
5375 Sprite::setLastSpriteSpecial(1);
5377 howmany = findLength(&velocity) * 4;
5379 if (environment == snowyenvironment)
5380 for (j = 0; j < howmany; j++) {
5381 tempvel.x = float(abs(Random() % 100) - 50) / 20;
5382 tempvel.y = float(abs(Random() % 100) - 50) / 20;
5383 tempvel.z = float(abs(Random() % 100) - 50) / 20;
5385 pos += velocity * .1;
5387 pos.x += float(abs(Random() % 100) - 50) / 150;
5388 pos.y += float(abs(Random() % 100) - 50) / 150;
5389 pos.z += float(abs(Random() % 100) - 50) / 150;
5390 Sprite::MakeSprite(splintersprite, pos, tempvel * .3 + velocity * float(abs(Random() % 100)) / 100 / 2, 1, 1, 1, .1, 1);
5391 Sprite::setLastSpriteSpecial(2);
5394 objects.messedwith[i] = .5;
5399 if (!skeleton.free) {
5402 if ((stunned > 0 || surprised > 0) && Person::players.size() > 2 && aitype != passivetype)
5405 if (aitype != passivetype && victim->skeleton.free && !victim->dead)
5407 if (tutoriallevel == 1 && id != 0)
5409 if (play && aitype != playercontrolled) {
5410 int whichsound = -1;
5411 i = abs(Random() % 4);
5412 if (speechdelay <= 0) {
5413 if (creature == rabbittype) {
5415 whichsound = rabbitchitter;
5417 whichsound = rabbitchitter2;
5419 if (creature == wolftype) {
5421 whichsound = growlsound;
5423 whichsound = growl2sound;
5428 if (whichsound != -1) {
5429 emit_sound_at(whichsound, coords);
5433 if (animTarget == staggerbackhighanim)
5435 if (animTarget == staggerbackhardanim)
5437 staggerdelay -= multiplier;
5438 if (animTarget != crouchstabanim && animTarget != swordgroundstabanim && animTarget != staffgroundsmashanim)
5440 if (velocity.y < -30 && animTarget == jumpdownanim)
5442 if (animCurrent != getIdle() && wasIdle() && animTarget != getIdle() && isIdle()) {
5443 animTarget = getIdle();
5447 weaponmissdelay -= multiplier;
5448 highreversaldelay -= multiplier;
5449 lowreversaldelay -= multiplier;
5450 lastcollide -= multiplier;
5451 skiddelay -= multiplier;
5452 if (!isnormal(velocity.x) && velocity.x) {
5455 if (!isnormal(targettilt) && targettilt) {
5458 if (!isnormal(targettilt2) && targettilt2) {
5461 if (!isnormal(targetyaw) && targetyaw) {
5465 if (animTarget == bounceidleanim || animTarget == wolfidle || animTarget == walkanim || animTarget == drawrightanim || animTarget == crouchdrawrightanim || animTarget == drawleftanim || animTarget == fightidleanim || animTarget == fightsidestep || animTarget == hanganim || isCrouch() || animTarget == backhandspringanim) {
5466 //open hands and close mouth
5467 if (righthandmorphend != 0 && righthandmorphness == targetrighthandmorphness) {
5468 righthandmorphness = 0;
5469 righthandmorphend = 0;
5470 targetrighthandmorphness = 1;
5473 if (lefthandmorphend != 0 && lefthandmorphness == targetlefthandmorphness) {
5474 lefthandmorphness = 0;
5475 lefthandmorphend = 0;
5476 targetlefthandmorphness = 1;
5479 if (headmorphend != 3 && headmorphend != 5 && headmorphstart != 3 && headmorphstart != 5 && headmorphend != 0 && headmorphness == targetheadmorphness) {
5482 targetheadmorphness = 1;
5486 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) {
5487 //open hands and mouth
5488 if (righthandmorphend != 0 && righthandmorphness == targetrighthandmorphness) {
5489 righthandmorphness = 0;
5490 righthandmorphend = 0;
5491 targetrighthandmorphness = 1;
5494 if (lefthandmorphend != 0 && lefthandmorphness == targetlefthandmorphness) {
5495 lefthandmorphness = 0;
5496 lefthandmorphend = 0;
5497 targetlefthandmorphness = 1;
5500 if (headmorphend != 1 && headmorphness == targetheadmorphness) {
5503 targetheadmorphness = 1;
5507 if (animTarget == jumpupanim || animTarget == crouchstabanim || animTarget == swordgroundstabanim || animTarget == swordfightidlebothanim || animTarget == blockhighleftanim) {
5508 //close hands and mouth
5509 if (righthandmorphend != 1 && righthandmorphness == targetrighthandmorphness) {
5510 righthandmorphness = 0;
5511 righthandmorphend = 1;
5512 targetrighthandmorphness = 1;
5515 if (lefthandmorphend != 1 && lefthandmorphness == targetlefthandmorphness) {
5516 lefthandmorphness = 0;
5517 lefthandmorphend = 1;
5518 targetlefthandmorphness = 1;
5521 if (headmorphend != 0 && headmorphness == targetheadmorphness) {
5524 targetheadmorphness = 1;
5528 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) {
5529 //close hands and yell
5530 if (righthandmorphend != 1 && righthandmorphness == targetrighthandmorphness) {
5531 righthandmorphness = 0;
5532 righthandmorphend = 1;
5533 targetrighthandmorphness = 1;
5536 if (lefthandmorphend != 1 && lefthandmorphness == targetlefthandmorphness) {
5537 lefthandmorphness = 0;
5538 lefthandmorphend = 1;
5539 targetlefthandmorphness = 1;
5542 if (headmorphend != 2 && headmorphness == targetheadmorphness) {
5545 targetheadmorphness = 1;
5552 if ((victim != this->shared_from_this()) && !victim->dead && (victim->aitype != passivetype) &&
5553 (victim->aitype != searchtype) && (aitype != passivetype) &&
5554 (aitype != searchtype) && (victim->id < Person::players.size())) {
5555 behind = (normaldotproduct(facing, coords - victim->coords) > 0);
5559 if (!dead && animTarget != hurtidleanim)
5560 if (behind || animTarget == killanim || animTarget == knifethrowanim || animTarget == knifefollowanim || animTarget == spinkickreversalanim || animTarget == rabbitkickreversedanim || animTarget == jumpreversedanim) {
5561 if (headmorphend != 4 || headmorphness == targetheadmorphness) {
5564 targetheadmorphness = 1;
5568 if (weaponactive != -1) {
5569 if (weapons[weaponids[weaponactive]].getType() != staff) {
5570 righthandmorphstart = 1;
5571 righthandmorphend = 1;
5573 if (weapons[weaponids[weaponactive]].getType() == staff) {
5574 righthandmorphstart = 2;
5575 righthandmorphend = 2;
5577 targetrighthandmorphness = 1;
5580 terrainnormal = terrain.getNormal(coords.x, coords.z);
5582 if (animation[animTarget].attack != reversal) {
5583 if (!isnormal(coords.x))
5591 flatfacing = DoRotation(flatfacing, 0, yaw, 0);
5592 facing = flatfacing;
5593 ReflectVector(&facing, terrainnormal);
5596 if (isRun() || animTarget == sneakanim || animTarget == rollanim || animTarget == walkanim) {
5598 targettilt2 = -facing.y * 20;
5603 if (!isRun() && !animation[animTarget].attack && animTarget != getupfromfrontanim && animTarget != getupfrombackanim && animTarget != sneakanim)
5605 if (animTarget == jumpupanim || animTarget == jumpdownanim || isFlip()) {
5606 flatvelocity = velocity;
5608 flatvelspeed = findLength(&flatvelocity);
5609 targettilt = flatvelspeed * fast_sqrt(abs(velocity.y) * .7) * normaldotproduct(DoRotation(flatfacing, 0, -90, 0), flatvelocity);
5610 targettilt2 = flatvelspeed * fast_sqrt(abs(velocity.y) * .7) * normaldotproduct(flatfacing, flatvelocity);
5615 if (targettilt > 25)
5617 if (targettilt < -25)
5621 if (targettilt2 > 45)
5623 if (targettilt2 < -45)
5625 if (abs(tilt2 - targettilt2) < multiplier * 400)
5626 tilt2 = targettilt2;
5627 else if (tilt2 > targettilt2) {
5628 tilt2 -= multiplier * 400;
5629 } else if (tilt2 < targettilt2) {
5630 tilt2 += multiplier * 400;
5632 if (!animation[animTarget].attack && animTarget != getupfrombackanim && animTarget != getupfromfrontanim) {
5639 if (!isnormal(targettilt) && targettilt) {
5642 if (!isnormal(targettilt2) && targettilt2) {
5647 if (animTarget == rabbittackleanim) {
5648 velocity += facing * multiplier * speed * 700 * scale;
5649 velspeed = findLength(&velocity);
5650 if (velspeed > speed * 65 * scale) {
5651 velocity /= velspeed;
5652 velspeed = speed * 65 * scale;
5653 velocity *= velspeed;
5655 velocity.y += gravity * multiplier * 20;
5656 ReflectVector(&velocity, terrain.getNormal(coords.x, coords.z));
5657 velspeed = findLength(&velocity);
5658 velocity = flatfacing * velspeed;
5660 if (animTarget != rabbitrunninganim && animTarget != wolfrunninganim) {
5661 if (isRun() || animTarget == rabbitkickanim) {
5662 velocity += facing * multiplier * speed * 700 * scale;
5663 velspeed = findLength(&velocity);
5664 if (velspeed > speed * 45 * scale) {
5665 velocity /= velspeed;
5666 velspeed = speed * 45 * scale;
5667 velocity *= velspeed;
5669 velocity.y += gravity * multiplier * 20;
5670 ReflectVector(&velocity, terrain.getNormal(coords.x, coords.z));
5671 velspeed = findLength(&velocity);
5672 if (velspeed < speed * 30 * scale)
5673 velspeed = speed * 30 * scale;
5674 velocity = flatfacing * velspeed;
5676 } else if (isRun()) {
5677 velocity += facing * multiplier * speed * 700 * scale;
5678 velspeed = findLength(&velocity);
5679 if (creature == rabbittype) {
5680 if (velspeed > speed * 55 * scale) {
5681 velocity /= velspeed;
5682 velspeed = speed * 55 * scale;
5683 velocity *= velspeed;
5686 if (creature == wolftype) {
5687 if (velspeed > speed * 75 * scale) {
5688 velocity /= velspeed;
5689 velspeed = speed * 75 * scale;
5690 velocity *= velspeed;
5693 velocity.y += gravity * multiplier * 20;
5694 ReflectVector(&velocity, terrain.getNormal(coords.x, coords.z));
5695 velspeed = findLength(&velocity);
5696 velocity = flatfacing * velspeed;
5699 if (animTarget == rollanim && animation[animTarget].label[frameTarget] != 6) {
5700 velocity += facing * multiplier * speed * 700 * scale;
5701 velspeed = findLength(&velocity);
5702 if (velspeed > speed * 45 * scale) {
5703 velocity /= velspeed;
5704 velspeed = speed * 45 * scale;
5705 velocity *= velspeed;
5707 velocity.y += gravity * multiplier * 20;
5708 ReflectVector(&velocity, terrain.getNormal(coords.x, coords.z));
5709 velspeed = findLength(&velocity);
5710 velocity = flatfacing * velspeed;
5713 if (animTarget == sneakanim || animTarget == walkanim) {
5714 velocity += facing * multiplier * speed * 700 * scale;
5715 velspeed = findLength(&velocity);
5716 if (velspeed > speed * 12 * scale) {
5717 velocity /= velspeed;
5718 velspeed = speed * 12 * scale;
5719 velocity *= velspeed;
5721 velocity.y += gravity * multiplier * 20;
5722 ReflectVector(&velocity, terrain.getNormal(coords.x, coords.z));
5723 velspeed = findLength(&velocity);
5724 velocity = flatfacing * velspeed;
5727 if ((animTarget == fightidleanim || animTarget == knifefightidleanim) && (animCurrent == bounceidleanim || animCurrent == hurtidleanim)) {
5728 velocity += facing * multiplier * speed * 700 * scale;
5729 velspeed = findLength(&velocity);
5730 if (velspeed > speed * 2 * scale) {
5731 velocity /= velspeed;
5732 velspeed = speed * 2 * scale;
5733 velocity *= velspeed;
5735 velocity.y += gravity * multiplier * 20;
5736 ReflectVector(&velocity, terrain.getNormal(coords.x, coords.z));
5737 velspeed = findLength(&velocity);
5738 velocity = flatfacing * velspeed;
5742 if ((animTarget == bounceidleanim || animCurrent == hurtidleanim) && (animCurrent == fightidleanim || animCurrent == knifefightidleanim)) {
5743 velocity -= facing * multiplier * speed * 700 * scale;
5744 velspeed = findLength(&velocity);
5745 if (velspeed > speed * 2 * scale) {
5746 velocity /= velspeed;
5747 velspeed = speed * 2 * scale;
5748 velocity *= velspeed;
5750 velocity.y += gravity * multiplier * 20;
5751 ReflectVector(&velocity, terrain.getNormal(coords.x, coords.z));
5752 velspeed = findLength(&velocity);
5753 velocity = flatfacing * velspeed * -1;
5756 if (animTarget == fightsidestep) {
5757 velocity += DoRotation(facing * multiplier * speed * 700 * scale, 0, -90, 0);
5758 velspeed = findLength(&velocity);
5759 if (velspeed > speed * 12 * scale) {
5760 velocity /= velspeed;
5761 velspeed = speed * 12 * scale;
5762 velocity *= velspeed;
5764 velocity.y += gravity * multiplier * 20;
5765 ReflectVector(&velocity, terrain.getNormal(coords.x, coords.z));
5766 velspeed = findLength(&velocity);
5767 velocity = DoRotation(flatfacing * velspeed, 0, -90, 0);
5770 if (animTarget == staggerbackhighanim) {
5771 coords -= facing * multiplier * speed * 16 * scale;
5774 if (animTarget == staggerbackhardanim && animation[staggerbackhardanim].label[frameTarget] != 6) {
5775 coords -= facing * multiplier * speed * 20 * scale;
5779 if (animTarget == backhandspringanim) {
5780 //coords-=facing*multiplier*50*scale;
5781 velocity += facing * multiplier * speed * 700 * scale * -1;
5782 velspeed = findLength(&velocity);
5783 if (velspeed > speed * 50 * scale) {
5784 velocity /= velspeed;
5785 velspeed = speed * 50 * scale;
5786 velocity *= velspeed;
5788 velocity.y += gravity * multiplier * 20;
5789 ReflectVector(&velocity, terrain.getNormal(coords.x, coords.z));
5790 velspeed = findLength(&velocity);
5791 velocity = flatfacing * velspeed * -1;
5793 if (animTarget == dodgebackanim) {
5794 //coords-=facing*multiplier*50*scale;
5795 velocity += facing * multiplier * speed * 700 * scale * -1;
5796 velspeed = findLength(&velocity);
5797 if (velspeed > speed * 60 * scale) {
5798 velocity /= velspeed;
5799 velspeed = speed * 60 * scale;
5800 velocity *= velspeed;
5802 velocity.y += gravity * multiplier * 20;
5803 ReflectVector(&velocity, terrain.getNormal(coords.x, coords.z));
5804 velspeed = findLength(&velocity);
5805 velocity = flatfacing * velspeed * -1;
5808 if (animTarget == jumpupanim || animTarget == jumpdownanim || isFlip()) {
5809 velspeed = findLength(&velocity);
5813 if (animTarget == jumpupanim || animTarget == jumpdownanim || isFlip()) {
5814 velocity.y += gravity * multiplier;
5817 if (animTarget != climbanim && animTarget != hanganim && !isWallJump())
5818 coords += velocity * multiplier;
5820 if (coords.y < terrain.getHeight(coords.x, coords.z) && (animTarget == jumpdownanim || animTarget == jumpupanim || isFlip())) {
5821 if (isFlip() && animation[animTarget].label[frameTarget] == 7)
5824 if (animTarget == jumpupanim) {
5826 animTarget = getIdle();
5833 pause_sound(whooshsound);
5834 OPENAL_SetVolume(channels[whooshsound], 0);
5837 if (animTarget == jumpdownanim || isFlip()) {
5838 if (isFlip())jumppower = -4;
5839 animTarget = getLanding();
5840 emit_sound_at(landsound, coords, 128.);
5843 addEnvSound(coords);
5848 if (animTarget != jumpupanim && animTarget != jumpdownanim && !isFlip() && animTarget != climbanim && animTarget != hanganim && !isWallJump())
5849 coords.y += gravity * multiplier * 2;
5850 if (animTarget != jumpupanim && animTarget != jumpdownanim && !isFlip() && coords.y < terrain.getHeight(coords.x, coords.z)) {
5851 coords.y = terrain.getHeight(coords.x, coords.z);
5856 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)) {
5857 velspeed = findLength(&velocity);
5859 if (velspeed < multiplier * 300 * scale) {
5862 velocity -= velocity / velspeed * multiplier * 300 * scale;
5863 if (velspeed > 5 && (isLanding() || isLandhard())) {
5864 skiddingdelay += multiplier;
5865 if (skiddelay <= 0) {
5875 velspeed = findLength(&velocity);
5877 if (velspeed < multiplier * 600 * scale) {
5880 velocity -= velocity / velspeed * multiplier * 600 * scale;
5882 if (velspeed > 5 && (isLanding() || isLandhard())) {
5883 skiddingdelay += multiplier;
5884 if (skiddelay <= 0) {
5893 if (skiddingdelay < 0)
5894 skiddingdelay += multiplier;
5895 if (skiddingdelay > .02 && !forwardkeydown && !backkeydown && !leftkeydown && !rightkeydown && !jumpkeydown && isLanding() && !landhard) {
5897 if (!onterrain || environment == grassyenvironment) {
5898 emit_sound_at(skidsound, coords, 128 * velspeed / 10);
5900 emit_sound_at(snowskidsound, coords, 128 * velspeed / 10);
5904 if (animation[animTarget].attack == normalattack && animTarget != rabbitkickanim && !victim->skeleton.free) {
5905 terrainnormal = victim->coords - coords;
5906 Normalise(&terrainnormal);
5907 targetyaw = -asin(0 - terrainnormal.x);
5908 targetyaw *= 360 / 6.28;
5909 if (terrainnormal.z < 0)
5910 targetyaw = 180 - targetyaw;
5911 targettilt2 = -asin(terrainnormal.y) * 360 / 6.28; //*-70;
5914 if (animation[animTarget].attack == reversal && animTarget != rabbittacklinganim) {
5915 targetyaw = victim->targetyaw;
5917 if (animTarget == rabbittacklinganim) {
5918 coords = victim->coords;
5921 skeleton.oldfree = skeleton.free;
5925 midterrain.x = terrain.size * terrain.scale / 2;
5926 midterrain.z = terrain.size * terrain.scale / 2;
5927 if (distsqflat(&coords, &midterrain) > (terrain.size * terrain.scale / 2 - viewdistance) * (terrain.size * terrain.scale / 2 - viewdistance)) {
5929 tempposit = coords - midterrain;
5931 Normalise(&tempposit);
5932 tempposit *= (terrain.size * terrain.scale / 2 - viewdistance);
5933 coords.x = tempposit.x + midterrain.x;
5934 coords.z = tempposit.z + midterrain.z;
5940 * inverse kinematics helper function
5942 void IKHelper(Person *p, float interp)
5944 XYZ point, change, change2;
5945 float heightleft, heightright;
5947 // TODO: implement localToWorld and worldToLocal
5948 // but keep in mind it won't be the same math if player is ragdolled or something
5949 // - localToWorldStanding / worldToLocalStanding (or crouching or...?)
5950 // then comb through code for places where to use it
5952 // point = localToWorld(jointPos(leftfoot))
5953 point = DoRotation(p->jointPos(leftfoot), 0, p->yaw, 0) * p->scale + p->coords;
5954 // adjust height of foot
5955 heightleft = terrain.getHeight(point.x, point.z) + .04;
5956 point.y = heightleft;
5957 change = p->jointPos(leftankle) - p->jointPos(leftfoot);
5958 change2 = p->jointPos(leftknee) - p->jointPos(leftfoot);
5959 // jointPos(leftfoot) = interpolate(worldToLocal(point), jointPos(leftfoot), interp)
5960 p->jointPos(leftfoot) = DoRotation((point - p->coords) / p->scale, 0, -p->yaw, 0) * interp + p->jointPos(leftfoot) * (1 - interp);
5961 // move ankle along with foot
5962 p->jointPos(leftankle) = p->jointPos(leftfoot) + change;
5963 // average knee pos between old and new pos
5964 p->jointPos(leftknee) = (p->jointPos(leftfoot) + change2) / 2 + (p->jointPos(leftknee)) / 2;
5966 // do same as above for right leg
5967 point = DoRotation(p->jointPos(rightfoot), 0, p->yaw, 0) * p->scale + p->coords;
5968 heightright = terrain.getHeight(point.x, point.z) + .04;
5969 point.y = heightright;
5970 change = p->jointPos(rightankle) - p->jointPos(rightfoot);
5971 change2 = p->jointPos(rightknee) - p->jointPos(rightfoot);
5972 p->jointPos(rightfoot) = DoRotation((point - p->coords) / p->scale, 0, -p->yaw, 0) * interp + p->jointPos(rightfoot) * (1 - interp);
5973 p->jointPos(rightankle) = p->jointPos(rightfoot) + change;
5974 p->jointPos(rightknee) = (p->jointPos(rightfoot) + change2) / 2 + (p->jointPos(rightknee)) / 2;
5976 // fix up skeleton now that we've moved body parts?
5977 p->skeleton.DoConstraints(&p->coords, &p->scale);
5984 int Person::DrawSkeleton()
5986 int oldplayerdetail;
5987 if ((frustum.SphereInFrustum(coords.x, coords.y + scale * 3, coords.z, scale * 8) && distsq(&viewer, &coords) < viewdistance * viewdistance) || skeleton.free == 3) {
5988 if (onterrain && (isIdle() || isCrouch() || wasIdle() || wasCrouch()) && !skeleton.free) {
5998 glAlphaFunc(GL_GREATER, 0.0001);
6000 float terrainheight;
6004 if (!isnormal(tilt))
6006 if (!isnormal(tilt2))
6008 oldplayerdetail = playerdetail;
6010 if (distsq(&viewer, &coords) < viewdistance * viewdistance / 32 && detail == 2) {
6013 if (distsq(&viewer, &coords) < viewdistance * viewdistance / 128 && detail == 1) {
6016 if (distsq(&viewer, &coords) < viewdistance * viewdistance / 256 && (detail != 1 && detail != 2)) {
6021 if (playerdetail != oldplayerdetail) {
6023 normalsupdatedelay = 0;
6025 static float updatedelaychange;
6026 static float morphness;
6027 static float framemult;
6029 skeleton.FindForwards();
6030 if (howactive == typesittingwall) {
6031 skeleton.specialforward[1] = 0;
6032 skeleton.specialforward[1].z = 1;
6038 static int weaponattachmuscle;
6039 static int weaponrotatemuscle;
6040 static XYZ weaponpoint;
6041 static int start, endthing;
6042 if ((dead != 2 || skeleton.free != 2) && updatedelay <= 0) {
6043 if (!isSleeping() && !isSitting()) {
6044 // TODO: give these meaningful names
6045 const bool cond1 = (isIdle() || isCrouch() || isLanding() || isLandhard()
6046 || animTarget == drawrightanim || animTarget == drawleftanim || animTarget == crouchdrawrightanim);
6047 const bool cond2 = (wasIdle() || wasCrouch() || wasLanding() || wasLandhard()
6048 || animCurrent == drawrightanim || animCurrent == drawleftanim || animCurrent == crouchdrawrightanim);
6050 if (onterrain && (cond1 && cond2) && !skeleton.free) {
6052 if (creature == wolftype)
6056 if (onterrain && (cond1 && !cond2) && !skeleton.free) {
6057 IKHelper(this, target);
6058 if (creature == wolftype)
6059 IKHelper(this, target);
6062 if (onterrain && (!cond1 && cond2) && !skeleton.free) {
6063 IKHelper(this, 1 - target);
6064 if (creature == wolftype)
6065 IKHelper(this, 1 - target);
6069 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()))
6072 targetheadyaw = -targetyaw;
6073 targetheadpitch = 0;
6074 if (animation[animTarget].attack == 3)
6075 targetheadyaw += 180;
6077 for (i = 0; i < skeleton.drawmodel.vertexNum; i++) {
6078 skeleton.drawmodel.vertex[i] = 0;
6079 skeleton.drawmodel.vertex[i].y = 999;
6081 for (i = 0; i < skeleton.drawmodellow.vertexNum; i++) {
6082 skeleton.drawmodellow.vertex[i] = 0;
6083 skeleton.drawmodellow.vertex[i].y = 999;
6085 for (i = 0; i < skeleton.drawmodelclothes.vertexNum; i++) {
6086 skeleton.drawmodelclothes.vertex[i] = 0;
6087 skeleton.drawmodelclothes.vertex[i].y = 999;
6089 for (int i = 0; i < skeleton.num_muscles; i++) {
6090 // convenience renames
6091 const int p1 = skeleton.muscles[i].parent1->label;
6092 const int p2 = skeleton.muscles[i].parent2->label;
6094 if ((skeleton.muscles[i].numvertices > 0 && playerdetail) || (skeleton.muscles[i].numverticeslow > 0 && !playerdetail)) {
6099 if (p1 == righthand || p2 == righthand) {
6100 morphness = righthandmorphness;
6101 start = righthandmorphstart;
6102 endthing = righthandmorphend;
6104 if (p1 == lefthand || p2 == lefthand) {
6105 morphness = lefthandmorphness;
6106 start = lefthandmorphstart;
6107 endthing = lefthandmorphend;
6109 if (p1 == head || p2 == head) {
6110 morphness = headmorphness;
6111 start = headmorphstart;
6112 endthing = headmorphend;
6114 if ((p1 == neck && p2 == abdomen) || (p2 == neck && p1 == abdomen)) {
6115 morphness = chestmorphness;
6116 start = chestmorphstart;
6117 endthing = chestmorphend;
6119 if ((p1 == groin && p2 == abdomen) || (p2 == groin && p1 == abdomen)) {
6120 morphness = tailmorphness;
6121 start = tailmorphstart;
6122 endthing = tailmorphend;
6125 skeleton.FindRotationMuscle(i, animTarget);
6126 mid = (skeleton.muscles[i].parent1->position + skeleton.muscles[i].parent2->position) / 2;
6127 glMatrixMode(GL_MODELVIEW);
6131 glRotatef(tilt2, 1, 0, 0);
6133 glRotatef(tilt, 0, 0, 1);
6136 glTranslatef(mid.x, mid.y, mid.z);
6138 skeleton.muscles[i].lastrotate1 = skeleton.muscles[i].rotate1;
6139 glRotatef(-skeleton.muscles[i].lastrotate1 + 90, 0, 1, 0);
6141 skeleton.muscles[i].lastrotate2 = skeleton.muscles[i].rotate2;
6142 glRotatef(-skeleton.muscles[i].lastrotate2 + 90, 0, 0, 1);
6144 skeleton.muscles[i].lastrotate3 = skeleton.muscles[i].rotate3;
6145 glRotatef(-skeleton.muscles[i].lastrotate3, 0, 1, 0);
6147 if (playerdetail || skeleton.free == 3) {
6148 for (j = 0; j < skeleton.muscles[i].numvertices; j++) {
6149 XYZ &v0 = skeleton.model[start].vertex[skeleton.muscles[i].vertices[j]];
6150 XYZ &v1 = skeleton.model[endthing].vertex[skeleton.muscles[i].vertices[j]];
6151 glMatrixMode(GL_MODELVIEW);
6153 if (p1 == abdomen || p2 == abdomen)
6154 glTranslatef((v0.x * (1 - morphness) + v1.x * morphness) * proportionbody.x,
6155 (v0.y * (1 - morphness) + v1.y * morphness) * proportionbody.y,
6156 (v0.z * (1 - morphness) + v1.z * morphness) * proportionbody.z);
6157 if (p1 == lefthand || p1 == righthand || p1 == leftwrist || p1 == rightwrist || p1 == leftelbow || p1 == rightelbow || p2 == leftelbow || p2 == rightelbow)
6158 glTranslatef((v0.x * (1 - morphness) + v1.x * morphness) * proportionarms.x,
6159 (v0.y * (1 - morphness) + v1.y * morphness) * proportionarms.y,
6160 (v0.z * (1 - morphness) + v1.z * morphness) * proportionarms.z);
6161 if (p1 == leftfoot || p1 == rightfoot || p1 == leftankle || p1 == rightankle || p1 == leftknee || p1 == rightknee || p2 == leftknee || p2 == rightknee)
6162 glTranslatef((v0.x * (1 - morphness) + v1.x * morphness) * proportionlegs.x,
6163 (v0.y * (1 - morphness) + v1.y * morphness) * proportionlegs.y,
6164 (v0.z * (1 - morphness) + v1.z * morphness) * proportionlegs.z);
6165 if (p1 == head || p2 == head)
6166 glTranslatef((v0.x * (1 - morphness) + v1.x * morphness) * proportionhead.x,
6167 (v0.y * (1 - morphness) + v1.y * morphness) * proportionhead.y,
6168 (v0.z * (1 - morphness) + v1.z * morphness) * proportionhead.z);
6169 glGetFloatv(GL_MODELVIEW_MATRIX, M);
6170 skeleton.drawmodel.vertex[skeleton.muscles[i].vertices[j]].x = M[12] * scale;
6171 skeleton.drawmodel.vertex[skeleton.muscles[i].vertices[j]].y = M[13] * scale;
6172 skeleton.drawmodel.vertex[skeleton.muscles[i].vertices[j]].z = M[14] * scale;
6176 if (!playerdetail || skeleton.free == 3) {
6177 for (j = 0; j < skeleton.muscles[i].numverticeslow; j++) {
6178 XYZ &v0 = skeleton.modellow.vertex[skeleton.muscles[i].verticeslow[j]];
6179 glMatrixMode(GL_MODELVIEW);
6181 if (p1 == abdomen || p2 == abdomen)
6182 glTranslatef(v0.x * proportionbody.x,
6183 v0.y * proportionbody.y,
6184 v0.z * proportionbody.z);
6185 if (p1 == lefthand || p1 == righthand || p1 == leftwrist || p1 == rightwrist || p1 == leftelbow || p1 == rightelbow || p2 == leftelbow || p2 == rightelbow)
6186 glTranslatef(v0.x * proportionarms.x,
6187 v0.y * proportionarms.y,
6188 v0.z * proportionarms.z);
6189 if (p1 == leftfoot || p1 == rightfoot || p1 == leftankle || p1 == rightankle || p1 == leftknee || p1 == rightknee || p2 == leftknee || p2 == rightknee)
6190 glTranslatef(v0.x * proportionlegs.x,
6191 v0.y * proportionlegs.y,
6192 v0.z * proportionlegs.z);
6193 if (p1 == head || p2 == head)
6194 glTranslatef(v0.x * proportionhead.x,
6195 v0.y * proportionhead.y,
6196 v0.z * proportionhead.z);
6198 glGetFloatv(GL_MODELVIEW_MATRIX, M);
6199 skeleton.drawmodellow.vertex[skeleton.muscles[i].verticeslow[j]].x = M[12] * scale;
6200 skeleton.drawmodellow.vertex[skeleton.muscles[i].verticeslow[j]].y = M[13] * scale;
6201 skeleton.drawmodellow.vertex[skeleton.muscles[i].verticeslow[j]].z = M[14] * scale;
6207 if (skeleton.clothes && skeleton.muscles[i].numverticesclothes > 0) {
6208 mid = (skeleton.muscles[i].parent1->position + skeleton.muscles[i].parent2->position) / 2;
6210 glMatrixMode(GL_MODELVIEW);
6214 glRotatef(tilt2, 1, 0, 0);
6216 glRotatef(tilt, 0, 0, 1);
6217 glTranslatef(mid.x, mid.y, mid.z);
6218 skeleton.muscles[i].lastrotate1 = skeleton.muscles[i].rotate1;
6219 glRotatef(-skeleton.muscles[i].lastrotate1 + 90, 0, 1, 0);
6221 skeleton.muscles[i].lastrotate2 = skeleton.muscles[i].rotate2;
6222 glRotatef(-skeleton.muscles[i].lastrotate2 + 90, 0, 0, 1);
6224 skeleton.muscles[i].lastrotate3 = skeleton.muscles[i].rotate3;
6225 glRotatef(-skeleton.muscles[i].lastrotate3, 0, 1, 0);
6227 for (j = 0; j < skeleton.muscles[i].numverticesclothes; j++) {
6228 XYZ &v0 = skeleton.modelclothes.vertex[skeleton.muscles[i].verticesclothes[j]];
6229 glMatrixMode(GL_MODELVIEW);
6231 if (p1 == abdomen || p2 == abdomen)
6232 glTranslatef(v0.x * proportionbody.x,
6233 v0.y * proportionbody.y,
6234 v0.z * proportionbody.z);
6235 if (p1 == lefthand || p1 == righthand || p1 == leftwrist || p1 == rightwrist || p1 == leftelbow || p1 == rightelbow || p2 == leftelbow || p2 == rightelbow)
6236 glTranslatef(v0.x * proportionarms.x,
6237 v0.y * proportionarms.y,
6238 v0.z * proportionarms.z);
6239 if (p1 == leftfoot || p1 == rightfoot || p1 == leftankle || p1 == rightankle || p1 == leftknee || p1 == rightknee || p2 == leftknee || p2 == rightknee)
6240 glTranslatef(v0.x * proportionlegs.x,
6241 v0.y * proportionlegs.y,
6242 v0.z * proportionlegs.z);
6243 if (p1 == head || p2 == head)
6244 glTranslatef(v0.x * proportionhead.x,
6245 v0.y * proportionhead.y,
6246 v0.z * proportionhead.z);
6247 glGetFloatv(GL_MODELVIEW_MATRIX, M);
6248 skeleton.drawmodelclothes.vertex[skeleton.muscles[i].verticesclothes[j]].x = M[12] * scale;
6249 skeleton.drawmodelclothes.vertex[skeleton.muscles[i].verticesclothes[j]].y = M[13] * scale;
6250 skeleton.drawmodelclothes.vertex[skeleton.muscles[i].verticesclothes[j]].z = M[14] * scale;
6255 updatedelay = 1 + (float)(Random() % 100) / 1000;
6257 if (skeleton.free != 2 && (skeleton.free == 1 || skeleton.free == 3 || id == 0 || (normalsupdatedelay <= 0) || animTarget == getupfromfrontanim || animTarget == getupfrombackanim || animCurrent == getupfromfrontanim || animCurrent == getupfrombackanim)) {
6258 normalsupdatedelay = 1;
6259 if (playerdetail || skeleton.free == 3)
6260 skeleton.drawmodel.CalculateNormals(0);
6261 if (!playerdetail || skeleton.free == 3)
6262 skeleton.drawmodellow.CalculateNormals(0);
6263 if (skeleton.clothes)
6264 skeleton.drawmodelclothes.CalculateNormals(0);
6266 if (playerdetail || skeleton.free == 3)
6267 skeleton.drawmodel.UpdateVertexArrayNoTexNoNorm();
6268 if (!playerdetail || skeleton.free == 3)
6269 skeleton.drawmodellow.UpdateVertexArrayNoTexNoNorm();
6270 if (skeleton.clothes) {
6271 skeleton.drawmodelclothes.UpdateVertexArrayNoTexNoNorm();
6276 updatedelaychange = -framemult * 4 * (45 - findDistance(&viewer, &coords) * 1);
6277 if (updatedelaychange > -realmultiplier * 30)
6278 updatedelaychange = -realmultiplier * 30;
6279 if (updatedelaychange > -framemult * 4)
6280 updatedelaychange = -framemult * 4;
6281 if (skeleton.free == 1)
6282 updatedelaychange *= 6;
6284 updatedelaychange *= 8;
6285 updatedelay += updatedelaychange;
6287 glMatrixMode(GL_MODELVIEW);
6289 glTranslatef(coords.x, coords.y - .02, coords.z);
6290 if (!skeleton.free) {
6291 glTranslatef(offset.x * scale, offset.y * scale, offset.z * scale);
6292 glRotatef(yaw, 0, 1, 0);
6296 glColor4f(.4, 1, .4, 1);
6297 glDisable(GL_LIGHTING);
6298 glDisable(GL_TEXTURE_2D);
6301 for (i = 0; i < skeleton.drawmodel.vertexNum; i++) {
6302 XYZ &v0 = skeleton.drawmodel.vertex[i];
6303 glVertex3f(v0.x, v0.y, v0.z);
6309 for (i = 0; i < skeleton.drawmodel.TriangleNum; i++) {
6310 XYZ &v0 = skeleton.drawmodel.vertex[skeleton.drawmodel.Triangles[i].vertex[0]];
6311 XYZ &v1 = skeleton.drawmodel.vertex[skeleton.drawmodel.Triangles[i].vertex[1]];
6312 XYZ &v2 = skeleton.drawmodel.vertex[skeleton.drawmodel.Triangles[i].vertex[2]];
6313 glVertex3f(v0.x, v0.y, v0.z);
6314 glVertex3f(v1.x, v1.y, v1.z);
6315 glVertex3f(v1.x, v1.y, v1.z);
6316 glVertex3f(v2.x, v2.y, v2.z);
6317 glVertex3f(v2.x, v2.y, v2.z);
6318 glVertex3f(v0.x, v0.y, v0.z);
6324 terrainlight = terrain.getLighting(coords.x, coords.z);
6325 distance = distsq(&viewer, &coords);
6326 distance = (viewdistance * viewdistance - (distance - (viewdistance * viewdistance * fadestart)) * (1 / (1 - fadestart))) / viewdistance / viewdistance;
6330 terrainheight = (coords.y - terrain.getHeight(coords.x, coords.z)) / 3 + 1;
6331 if (terrainheight < 1)
6333 if (terrainheight > 1.7)
6334 terrainheight = 1.7;
6336 glColor4f((1 - (1 - terrainlight.x) / terrainheight) - burnt, (1 - (1 - terrainlight.y) / terrainheight) - burnt, (1 - (1 - terrainlight.z) / terrainheight) - burnt, distance);
6337 glDisable(GL_BLEND);
6338 glAlphaFunc(GL_GREATER, 0.0001);
6339 glEnable(GL_TEXTURE_2D);
6341 glDisable(GL_TEXTURE_2D);
6342 glColor4f(.7, .35, 0, .5);
6344 glEnable(GL_LIGHTING);
6347 if (tutoriallevel && id != 0) {
6348 glColor4f(.7, .7, .7, 0.6);
6350 glEnable(GL_LIGHTING);
6352 if (canattack && cananger)
6353 if (animation[animTarget].attack == normalattack || animation[animTarget].attack == reversed) {
6354 glDisable(GL_TEXTURE_2D);
6355 glColor4f(1, 0, 0, 0.8);
6357 glMatrixMode(GL_TEXTURE);
6359 glTranslatef(0, -smoketex, 0);
6360 glTranslatef(-smoketex, 0, 0);
6364 if ((tutoriallevel && id != 0))
6365 skeleton.drawmodel.drawdifftex(Sprite::cloudimpacttexture);
6367 skeleton.drawmodel.draw();
6370 if (!playerdetail) {
6371 if ((tutoriallevel && id != 0))
6372 skeleton.drawmodellow.drawdifftex(Sprite::cloudimpacttexture);
6374 skeleton.drawmodellow.drawdifftex(skeleton.drawmodel.textureptr);
6377 if (!(animation[animTarget].attack == normalattack || animation[animTarget].attack == reversed))
6378 if (tutoriallevel && id != 0) {
6380 glMatrixMode(GL_MODELVIEW);
6381 glEnable(GL_TEXTURE_2D);
6382 glColor4f(.7, .7, .7, 0.6);
6384 glEnable(GL_LIGHTING);
6386 if (canattack && cananger)
6387 if (animation[animTarget].attack == normalattack || animation[animTarget].attack == reversed) {
6388 glDisable(GL_TEXTURE_2D);
6389 glColor4f(1, 0, 0, 0.8);
6391 glMatrixMode(GL_TEXTURE);
6393 glTranslatef(0, -smoketex * .6, 0);
6394 glTranslatef(smoketex * .6, 0, 0);
6397 if ((tutoriallevel && id != 0))
6398 skeleton.drawmodel.drawdifftex(Sprite::cloudimpacttexture);
6400 skeleton.drawmodel.draw();
6403 if (!playerdetail) {
6404 if ((tutoriallevel && id != 0))
6405 skeleton.drawmodellow.drawdifftex(Sprite::cloudimpacttexture);
6407 skeleton.drawmodellow.drawdifftex(skeleton.drawmodel.textureptr);
6412 if (tutoriallevel && id != 0) {
6414 glMatrixMode(GL_MODELVIEW);
6415 glEnable(GL_TEXTURE_2D);
6417 if (skeleton.clothes) {
6421 skeleton.drawmodelclothes.draw();
6423 skeleton.drawmodelclothes.drawimmediate();
6429 if (num_weapons > 0) {
6430 for (k = 0; k < num_weapons; k++) {
6432 if (weaponactive == k) {
6433 if (weapons[i].getType() != staff) {
6434 for (j = 0; j < skeleton.num_muscles; j++) {
6435 if ((skeleton.muscles[j].parent1->label == righthand || skeleton.muscles[j].parent2->label == righthand) && skeleton.muscles[j].numvertices > 0) {
6436 weaponattachmuscle = j;
6439 for (j = 0; j < skeleton.num_muscles; j++) {
6440 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) {
6441 weaponrotatemuscle = j;
6444 weaponpoint = (skeleton.muscles[weaponattachmuscle].parent1->position + skeleton.muscles[weaponattachmuscle].parent2->position) / 2;
6445 if (creature == wolftype)
6446 weaponpoint = (jointPos(rightwrist) * .7 + jointPos(righthand) * .3);
6448 if (weapons[i].getType() == staff) {
6449 for (j = 0; j < skeleton.num_muscles; j++) {
6450 if ((skeleton.muscles[j].parent1->label == righthand || skeleton.muscles[j].parent2->label == righthand) && skeleton.muscles[j].numvertices > 0) {
6451 weaponattachmuscle = j;
6454 for (j = 0; j < skeleton.num_muscles; j++) {
6455 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) {
6456 weaponrotatemuscle = j;
6459 //weaponpoint=jointPos(rightwrist);
6460 weaponpoint = (skeleton.muscles[weaponattachmuscle].parent1->position + skeleton.muscles[weaponattachmuscle].parent2->position) / 2;
6461 //weaponpoint+=skeleton.specialforward[1]*.1+(jointPos(rightwrist)-jointPos(rightelbow));
6462 XYZ tempnormthing, vec1, vec2;
6463 vec1 = (jointPos(rightwrist) - jointPos(rightelbow));
6464 vec2 = (jointPos(rightwrist) - jointPos(rightshoulder));
6465 CrossProduct(&vec1, &vec2, &tempnormthing);
6466 Normalise(&tempnormthing);
6467 if (animTarget != staffhitanim && animCurrent != staffhitanim && animTarget != staffgroundsmashanim && animCurrent != staffgroundsmashanim && animTarget != staffspinhitanim && animCurrent != staffspinhitanim)
6468 weaponpoint += tempnormthing * .1 - skeleton.specialforward[1] * .3 + (jointPos(rightwrist) - jointPos(rightelbow));
6471 if (weaponactive != k && weaponstuck != k) {
6472 if (weapons[i].getType() == knife)
6473 weaponpoint = jointPos(abdomen) + (jointPos(righthip) - jointPos(lefthip)) * .1 + (jointPos(rightshoulder) - jointPos(leftshoulder)) * .35;
6474 if (weapons[i].getType() == sword)
6475 weaponpoint = jointPos(abdomen) + (jointPos(lefthip) - jointPos(righthip)) * .09 + (jointPos(leftshoulder) - jointPos(rightshoulder)) * .33;
6476 if (weapons[i].getType() == staff)
6477 weaponpoint = jointPos(abdomen) + (jointPos(lefthip) - jointPos(righthip)) * .09 + (jointPos(leftshoulder) - jointPos(rightshoulder)) * .33;
6478 for (j = 0; j < skeleton.num_muscles; j++) {
6479 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) {
6480 weaponrotatemuscle = j;
6484 if (weaponstuck == k) {
6485 if (weaponstuckwhere == 0)
6486 weaponpoint = jointPos(abdomen) * .5 + jointPos(neck) * .5 - skeleton.forward * .8;
6488 weaponpoint = jointPos(abdomen) * .5 + jointPos(neck) * .5 + skeleton.forward * .8;
6489 for (j = 0; j < skeleton.num_muscles; j++) {
6490 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) {
6491 weaponrotatemuscle = j;
6495 if (skeleton.free) {
6496 weapons[i].position = weaponpoint * scale + coords;
6497 weapons[i].bigrotation = 0;
6498 weapons[i].bigtilt = 0;
6499 weapons[i].bigtilt2 = 0;
6501 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;
6502 weapons[i].bigrotation = yaw;
6503 weapons[i].bigtilt = tilt;
6504 weapons[i].bigtilt2 = tilt2;
6506 weapons[i].rotation1 = skeleton.muscles[weaponrotatemuscle].lastrotate1;
6507 weapons[i].rotation2 = skeleton.muscles[weaponrotatemuscle].lastrotate2;
6508 weapons[i].rotation3 = skeleton.muscles[weaponrotatemuscle].lastrotate3;
6509 if (weaponactive == k) {
6510 if (weapons[i].getType() == knife) {
6511 weapons[i].smallrotation = 180;
6512 weapons[i].smallrotation2 = 0;
6513 if (isCrouch() || wasCrouch()) {
6514 weapons[i].smallrotation2 = 20;
6516 if (animTarget == hurtidleanim) {
6517 weapons[i].smallrotation2 = 50;
6519 if ((animCurrent == crouchstabanim && animTarget == crouchstabanim) || (animCurrent == backhandspringanim && animTarget == backhandspringanim)) {
6520 XYZ temppoint1, temppoint2;
6523 temppoint1 = jointPos(righthand);
6524 temppoint2 = animation[animCurrent].weapontarget[frameCurrent] * (1 - target) + animation[animTarget].weapontarget[frameTarget] * (target);
6525 distance = findDistance(&temppoint1, &temppoint2);
6526 weapons[i].rotation2 = asin((temppoint1.y - temppoint2.y) / distance);
6527 weapons[i].rotation2 *= 360 / 6.28;
6530 weapons[i].rotation1 = acos((temppoint1.z - temppoint2.z) / findDistance(&temppoint1, &temppoint2));
6531 weapons[i].rotation1 *= 360 / 6.28;
6532 weapons[i].rotation3 = 0;
6533 weapons[i].smallrotation = -90;
6534 weapons[i].smallrotation2 = 0;
6535 if (temppoint1.x > temppoint2.x)
6536 weapons[i].rotation1 = 360 - weapons[i].rotation1;
6538 if ((animCurrent == knifeslashreversalanim && animTarget == knifeslashreversalanim) || (animCurrent == knifeslashreversedanim && animTarget == knifeslashreversedanim)) {
6539 XYZ temppoint1, temppoint2;
6542 temppoint1 = jointPos(righthand);
6543 temppoint2 = animation[animCurrent].weapontarget[frameCurrent] * (1 - target) + animation[animTarget].weapontarget[frameTarget] * (target);
6544 distance = findDistance(&temppoint1, &temppoint2);
6545 weapons[i].rotation2 = asin((temppoint1.y - temppoint2.y) / distance);
6546 weapons[i].rotation2 *= 360 / 6.28;
6549 weapons[i].rotation1 = acos((temppoint1.z - temppoint2.z) / findDistance(&temppoint1, &temppoint2));
6550 weapons[i].rotation1 *= 360 / 6.28;
6551 weapons[i].rotation3 = 0;
6552 weapons[i].smallrotation = 90;
6553 weapons[i].smallrotation2 = 0;
6554 if (temppoint1.x > temppoint2.x)
6555 weapons[i].rotation1 = 360 - weapons[i].rotation1;
6557 if (animTarget == knifethrowanim) {
6558 weapons[i].smallrotation = 90;
6559 //weapons[i].smallrotation2=-90;
6560 weapons[i].smallrotation2 = 0;
6561 weapons[i].rotation1 = 0;
6562 weapons[i].rotation2 = 0;
6563 weapons[i].rotation3 = 0;
6565 if (animTarget == knifesneakattackanim && frameTarget < 5) {
6566 weapons[i].smallrotation = -90;
6567 weapons[i].rotation1 = 0;
6568 weapons[i].rotation2 = 0;
6569 weapons[i].rotation3 = 0;
6572 if (weapons[i].getType() == sword) {
6573 weapons[i].smallrotation = 0;
6574 weapons[i].smallrotation2 = 0;
6575 if (animTarget == knifethrowanim) {
6576 weapons[i].smallrotation = -90;
6577 weapons[i].smallrotation2 = 0;
6578 weapons[i].rotation1 = 0;
6579 weapons[i].rotation2 = 0;
6580 weapons[i].rotation3 = 0;
6582 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)) {
6583 XYZ temppoint1, temppoint2;
6586 temppoint1 = animation[animCurrent].position[skeleton.jointlabels[righthand]][frameCurrent] * (1 - target) + animation[animTarget].position[skeleton.jointlabels[righthand]][frameTarget] * (target); //jointPos(righthand);
6587 temppoint2 = animation[animCurrent].weapontarget[frameCurrent] * (1 - target) + animation[animTarget].weapontarget[frameTarget] * (target);
6588 distance = findDistance(&temppoint1, &temppoint2);
6589 weapons[i].rotation2 = asin((temppoint1.y - temppoint2.y) / distance);
6590 weapons[i].rotation2 *= 360 / 6.28;
6593 weapons[i].rotation1 = acos((temppoint1.z - temppoint2.z) / findDistance(&temppoint1, &temppoint2));
6594 weapons[i].rotation1 *= 360 / 6.28;
6595 weapons[i].rotation3 = 0;
6596 weapons[i].smallrotation = 90;
6597 weapons[i].smallrotation2 = 0;
6598 if (temppoint1.x > temppoint2.x)
6599 weapons[i].rotation1 = 360 - weapons[i].rotation1;
6602 if (weapons[i].getType() == staff) {
6603 weapons[i].smallrotation = 100;
6604 weapons[i].smallrotation2 = 0;
6605 if ((animTarget == staffhitanim && animCurrent == staffhitanim) || (animTarget == staffhitreversedanim && animCurrent == staffhitreversedanim) || (animTarget == staffspinhitreversedanim && animCurrent == staffspinhitreversedanim) || (animTarget == staffgroundsmashanim && animCurrent == staffgroundsmashanim) || (animTarget == staffspinhitanim && animCurrent == staffspinhitanim)) {
6606 XYZ temppoint1, temppoint2;
6609 temppoint1 = animation[animCurrent].position[skeleton.jointlabels[righthand]][frameCurrent] * (1 - target) + animation[animTarget].position[skeleton.jointlabels[righthand]][frameTarget] * (target); //jointPos(righthand);
6610 temppoint2 = animation[animCurrent].weapontarget[frameCurrent] * (1 - target) + animation[animTarget].weapontarget[frameTarget] * (target);
6611 distance = findDistance(&temppoint1, &temppoint2);
6612 weapons[i].rotation2 = asin((temppoint1.y - temppoint2.y) / distance);
6613 weapons[i].rotation2 *= 360 / 6.28;
6616 weapons[i].rotation1 = acos((temppoint1.z - temppoint2.z) / findDistance(&temppoint1, &temppoint2));
6617 weapons[i].rotation1 *= 360 / 6.28;
6618 weapons[i].rotation3 = 0;
6619 weapons[i].smallrotation = 90;
6620 weapons[i].smallrotation2 = 0;
6621 if (temppoint1.x > temppoint2.x)
6622 weapons[i].rotation1 = 360 - weapons[i].rotation1;
6626 if (weaponactive != k && weaponstuck != k) {
6627 if (weapons[i].getType() == knife) {
6628 weapons[i].smallrotation = -70;
6629 weapons[i].smallrotation2 = 10;
6631 if (weapons[i].getType() == sword) {
6632 weapons[i].smallrotation = -100;
6633 weapons[i].smallrotation2 = -8;
6635 if (weapons[i].getType() == staff) {
6636 weapons[i].smallrotation = -100;
6637 weapons[i].smallrotation2 = -8;
6640 if (weaponstuck == k) {
6641 if (weaponstuckwhere == 0)
6642 weapons[i].smallrotation = 180;
6644 weapons[i].smallrotation = 0;
6645 weapons[i].smallrotation2 = 10;
6654 if (animation[animTarget].attack || isRun() || animTarget == staggerbackhardanim || isFlip() || animTarget == climbanim || animTarget == sneakanim || animTarget == rollanim || animTarget == walkanim || animTarget == backhandspringanim || isWallJump())
6656 if (animCurrent != animTarget)
6658 if (skeleton.free == 2)
6667 int Person::SphereCheck(XYZ *p1, float radius, XYZ *p, XYZ *move, float *rotate, Model *model)
6670 static float distance;
6671 static float olddistance;
6672 static int intersecting;
6673 static int firstintersecting;
6676 static XYZ start, end;
6677 static float slopethreshold = -.4;
6679 firstintersecting = -1;
6683 if (distsq(p1, &model->boundingspherecenter) > radius * radius + model->boundingsphereradius * model->boundingsphereradius)
6686 *p1 = DoRotation(*p1, 0, -*rotate, 0);
6687 for (i = 0; i < 4; i++) {
6688 for (j = 0; j < model->TriangleNum; j++) {
6689 if (model->facenormals[j].y <= slopethreshold) {
6691 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)));
6692 if (distance < radius) {
6693 point = *p1 - model->facenormals[j] * distance;
6694 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]]))
6697 intersecting = sphere_line_intersection(&model->vertex[model->Triangles[j].vertex[0]],
6698 &model->vertex[model->Triangles[j].vertex[1]],
6701 intersecting = sphere_line_intersection(&model->vertex[model->Triangles[j].vertex[1]],
6702 &model->vertex[model->Triangles[j].vertex[2]],
6705 intersecting = sphere_line_intersection(&model->vertex[model->Triangles[j].vertex[0]],
6706 &model->vertex[model->Triangles[j].vertex[2]],
6709 if (dotproduct(&model->facenormals[j], &end) > 0 && intersecting) {
6713 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)) {
6714 p1->y = point.y + radius;
6715 if ((animTarget == jumpdownanim || isFlip())) {
6716 if (isFlip() && (frameTarget < 5 || animation[animTarget].label[frameTarget] == 7 || animation[animTarget].label[frameTarget] == 4))
6719 if (animTarget == jumpupanim) {
6721 animTarget = getIdle();
6728 pause_sound(whooshsound);
6729 OPENAL_SetVolume(channels[whooshsound], 0);
6732 if ((animTarget == jumpdownanim || isFlip()) && !wasLanding() && !wasLandhard()) {
6735 animTarget = getLanding();
6736 emit_sound_at(landsound, coords, 128.);
6739 addEnvSound(coords);
6746 if ((distance < olddistance || firstintersecting == -1) && intersecting) {
6747 olddistance = distance;
6748 firstintersecting = j;
6753 for (j = 0; j < model->TriangleNum; j++) {
6754 if (model->facenormals[j].y > slopethreshold) {
6757 start.y -= radius / 4;
6758 XYZ &v0 = model->vertex[model->Triangles[j].vertex[0]];
6759 XYZ &v1 = model->vertex[model->Triangles[j].vertex[1]];
6760 XYZ &v2 = model->vertex[model->Triangles[j].vertex[2]];
6761 distance = abs((model->facenormals[j].x * start.x)
6762 + (model->facenormals[j].y * start.y)
6763 + (model->facenormals[j].z * start.z)
6764 - ((model->facenormals[j].x * v0.x)
6765 + (model->facenormals[j].y * v0.y)
6766 + (model->facenormals[j].z * v0.z)));
6767 if (distance < radius * .5) {
6768 point = start - model->facenormals[j] * distance;
6769 if (PointInTriangle( &point, model->facenormals[j], &v0, &v1, &v2))
6772 intersecting = sphere_line_intersection(v0.x, v0.y, v0.z, v1.x, v1.y, v1.z, p1->x, p1->y, p1->z, radius / 2);
6774 intersecting = sphere_line_intersection(v1.x, v1.y, v1.z, v2.x, v2.y, v2.z, p1->x, p1->y, p1->z, radius / 2);
6776 intersecting = sphere_line_intersection(v0.x, v0.y, v0.z, v2.x, v2.y, v2.z, p1->x, p1->y, p1->z, radius / 2);
6778 if (dotproduct(&model->facenormals[j], &end) > 0 && intersecting) {
6779 if ((animTarget == jumpdownanim || animTarget == jumpupanim || isFlip())) {
6781 velocity -= DoRotation(model->facenormals[j], 0, *rotate, 0) * findLength(&velocity) * abs(normaldotproduct(velocity, DoRotation(model->facenormals[j], 0, *rotate, 0))); //(distance-radius*.5)/multiplier;
6782 if (findLengthfast(&start) < findLengthfast(&velocity))
6785 *p1 += model->facenormals[j] * (distance - radius * .5);
6788 if ((distance < olddistance || firstintersecting == -1) && intersecting) {
6789 olddistance = distance;
6790 firstintersecting = j;
6797 *p = DoRotation(*p, 0, *rotate, 0);
6800 *p1 = DoRotation(*p1, 0, *rotate, 0);
6802 return firstintersecting;
6805 void Person::takeWeapon(int weaponId)
6808 weapons[weaponId].owner = id;
6809 if (num_weapons > 0) {
6810 weaponids[num_weapons] = weaponids[0];
6813 weaponids[0] = weaponId;
6816 void Person::addClothes()
6818 if (numclothes > 0) {
6819 for (int i = 0; i < numclothes; i++) {
6826 bool Person::addClothes(const int& clothesId)
6829 const char* fileName = clothes[clothesId];
6831 GLubyte* array = &skeleton.skinText[0];
6835 bool opened = load_image(fileName, texture);
6840 float tintr = clothestintr[clothesId];
6841 float tintg = clothestintg[clothesId];
6842 float tintb = clothestintb[clothesId];
6844 if (tintr > 1) tintr = 1;
6845 if (tintg > 1) tintg = 1;
6846 if (tintb > 1) tintb = 1;
6848 if (tintr < 0) tintr = 0;
6849 if (tintg < 0) tintg = 0;
6850 if (tintb < 0) tintb = 0;
6852 int bytesPerPixel = texture.bpp / 8;
6856 for (int i = 0; i < (int)(texture.sizeY * texture.sizeX * bytesPerPixel); i++) {
6857 if (bytesPerPixel == 3)
6859 else if ((i + 1) % 4 == 0)
6860 alphanum = texture.data[i];
6861 if ((i + 1) % 4 || bytesPerPixel == 3) {
6863 texture.data[i] *= tintr;
6865 texture.data[i] *= tintg;
6867 texture.data[i] *= tintb;
6868 array[tempnum] = (float)array[tempnum] * (1 - alphanum / 255) + (float)texture.data[i] * (alphanum / 255);