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 #include "Objects/Person.hpp"
23 #include "Animation/Animation.hpp"
24 #include "Audio/openal_wrapper.hpp"
25 #include "Audio/Sounds.hpp"
27 #include "Level/Awards.hpp"
28 #include "Level/Dialog.hpp"
29 #include "Utils/Folders.hpp"
30 #include "Tutorial.hpp"
32 extern float multiplier;
33 extern Terrain terrain;
35 extern int environment;
37 extern FRUSTUM frustum;
39 extern float realmultiplier;
41 extern float slomodelay;
42 extern bool cellophane;
43 extern float texdetail;
44 extern float realtexdetail;
45 extern GLubyte bloodText[512 * 512 * 3];
46 extern GLubyte wolfbloodText[512 * 512 * 3];
47 extern int bloodtoggle;
48 extern bool autoslomo;
49 extern float camerashake;
51 extern float viewdistance;
52 extern float blackout;
53 extern int difficulty;
55 extern float fadestart;
57 extern bool winfreeze;
58 extern bool showpoints;
59 extern bool immediate;
60 extern float smoketex;
61 extern bool reversaltrain;
62 extern bool canattack;
64 extern float damagedealt;
66 extern float hostiletime;
68 extern bool gamestarted;
70 std::vector<std::shared_ptr<Person>> Person::players(1, std::shared_ptr<Person>(new Person()));
75 animCurrent(bounceidleanim),
76 animTarget(bounceidleanim),
83 howactive(typeactive),
85 superruntoggle(false),
86 lastattack(0), lastattack2(0), lastattack3(0),
87 currentoffset(), targetoffset(), offset(),
119 rabbitkickenabled(false),
128 damagetolerance(200),
131 superpermanentdamage(0),
145 bleedx(0), bleedy(0),
149 headyaw(0), headpitch(0),
150 targetheadyaw(0), targetheadpitch(0),
161 normalsupdatedelay(0),
164 forwardkeydown(false),
165 forwardstogglekeydown(false),
170 jumptogglekeydown(false),
171 crouchkeydown(false),
172 crouchtogglekeydown(false),
174 drawtogglekeydown(false),
176 throwtogglekeydown(false),
177 attackkeydown(false),
182 crouchkeydowntime(0),
196 whichdirection(false),
197 whichdirectiondelay(0),
198 avoidsomething(false),
207 lefthandmorphness(0),
208 righthandmorphness(0),
212 targetlefthandmorphness(0),
213 targetrighthandmorphness(0),
214 targetheadmorphness(1),
215 targetchestmorphness(0),
216 targettailmorphness(0),
217 lefthandmorphstart(0), lefthandmorphend(0),
218 righthandmorphstart(0), righthandmorphend(0),
219 headmorphstart(0), headmorphend(0),
220 chestmorphstart(0), chestmorphend(0),
221 tailmorphstart(0), tailmorphend(0),
224 highreversaldelay(0),
227 creature(rabbittype),
274 finalpathfindpoint(0),
275 targetpathfindpoint(0),
276 lastpathfindpoint(0),
277 lastpathfindpoint2(0),
278 lastpathfindpoint3(0),
279 lastpathfindpoint4(0),
296 neckspurtparticledelay(0),
300 rabbitkickragdoll(false),
308 /* Read a person in tfile. Throws an error if it’s not valid */
309 Person::Person(FILE *tfile, int mapvers, unsigned i) : Person()
312 funpackf(tfile, "Bi Bi Bf Bf Bf Bi", &whichskin, &creature, &coords.x, &coords.y, &coords.z, &num_weapons);
314 funpackf(tfile, "Bi", &howactive);
316 howactive = typeactive;
319 funpackf(tfile, "Bf", &scale);
324 funpackf(tfile, "Bb", &immobile);
329 funpackf(tfile, "Bf", &yaw);
334 if (num_weapons < 0 || num_weapons > 5) {
335 throw InvalidPersonException();
337 if (num_weapons > 0 && num_weapons < 5) {
338 for (int j = 0; j < num_weapons; j++) {
339 weaponids[j] = weapons.size();
341 funpackf(tfile, "Bi", &type);
342 weapons.push_back(Weapon(type, id));
345 funpackf(tfile, "Bi", &numwaypoints);
346 for (int j = 0; j < numwaypoints; j++) {
347 funpackf(tfile, "Bf", &waypoints[j].x);
348 funpackf(tfile, "Bf", &waypoints[j].y);
349 funpackf(tfile, "Bf", &waypoints[j].z);
351 funpackf(tfile, "Bi", &waypointtype[j]);
353 waypointtype[j] = wpkeepwalking;
357 funpackf(tfile, "Bi", &waypoint);
358 if (waypoint > (numwaypoints - 1)) {
362 funpackf(tfile, "Bf Bf Bf", &armorhead, &armorhigh, &armorlow);
363 funpackf(tfile, "Bf Bf Bf", &protectionhead, &protectionhigh, &protectionlow);
364 funpackf(tfile, "Bf Bf Bf", &metalhead, &metalhigh, &metallow);
365 funpackf(tfile, "Bf Bf", &power, &speedmult);
367 float headprop, legprop, armprop, bodyprop;
370 funpackf(tfile, "Bf Bf Bf Bf", &headprop, &bodyprop, &armprop, &legprop);
378 if (creature == wolftype) {
379 proportionhead = 1.1 * headprop;
380 proportionbody = 1.1 * bodyprop;
381 proportionarms = 1.1 * armprop;
382 proportionlegs = 1.1 * legprop;
383 } else if (creature == rabbittype) {
384 proportionhead = 1.2 * headprop;
385 proportionbody = 1.05 * bodyprop;
386 proportionarms = 1.00 * armprop;
387 proportionlegs = 1.1 * legprop;
388 proportionlegs.y = 1.05 * legprop;
391 funpackf(tfile, "Bi", &numclothes);
392 for (int k = 0; k < numclothes; k++) {
394 funpackf(tfile, "Bi", &templength);
395 for (int l = 0; l < templength; l++)
396 funpackf(tfile, "Bb", &clothes[k][l]);
397 clothes[k][templength] = '\0';
398 funpackf(tfile, "Bf Bf Bf", &clothestintr[k], &clothestintg[k], &clothestintb[k]);
404 if (creature == wolftype) {
406 damagetolerance = 300;
413 realoldcoords = coords;
416 void Person::skeletonLoad(bool clothes)
419 if (creature != wolftype) {
421 "Skeleton/BasicFigure",
422 "Skeleton/BasicFigureLow",
423 "Skeleton/RabbitBelt",
425 "Models/Body2.solid",
426 "Models/Body3.solid",
427 "Models/Body4.solid",
428 "Models/Body5.solid",
429 "Models/Body6.solid",
430 "Models/Body7.solid",
431 "Models/BodyLow.solid",
437 "Skeleton/BasicFigureWolf",
438 "Skeleton/BasicFigureWolfLow",
439 "Skeleton/RabbitBelt",
441 "Models/Wolf2.solid",
442 "Models/Wolf3.solid",
443 "Models/Wolf4.solid",
444 "Models/Wolf5.solid",
445 "Models/Wolf6.solid",
446 "Models/Wolf7.solid",
447 "Models/WolfLow.solid",
453 skeleton.drawmodel.textureptr.load(creatureskin[creature][whichskin], 1, &skeleton.skinText[0], &skeleton.skinsize);
459 * GameTick/doPlayerCollisions
461 void Person::CheckKick()
464 && (animTarget == rabbitkickanim
466 && victim != this->shared_from_this()
468 && animCurrent == rabbitkickanim)
469 && distsq(&coords, &victim->coords) < 1.2
470 && !victim->skeleton.free))
473 if (Animation::animations[victim->animTarget].height != lowheight) {
474 float damagemult = (creature == wolftype ? 2.5 : 1.) * power * power;
475 XYZ relative = velocity;
477 Normalise(&relative);
481 if (!Tutorial::active)
482 emit_sound_at(heavyimpactsound, victim->coords);
484 for (unsigned i = 0; i < victim->skeleton.joints.size(); i++) {
485 victim->skeleton.joints[i].velocity += relative * 120 * damagemult;
488 victim->DoDamage(100 * damagemult / victim->protectionhigh);
494 animTarget = backflipanim;
496 velocity = facing * -10;
500 resume_stream(whooshsound);
502 award_bonus(id, cannon);
503 } else if (victim->isCrouch()) {
504 animTarget = rabbitkickreversedanim;
505 animCurrent = rabbitkickreversedanim;
506 victim->animCurrent = rabbitkickreversalanim;
507 victim->animTarget = rabbitkickreversalanim;
513 victim->oldcoords = victim->coords;
514 coords = victim->coords;
515 victim->targetyaw = targetyaw;
516 victim->victim = this->shared_from_this();
523 * GameTick/doPlayerCollisions - spread fire between players
524 * GameTick/doDevKeys - press f to ignite
525 * Person::DoStuff - spread fire from lit campfires and bushes
527 void Person::CatchFire()
529 XYZ flatfacing, flatvelocity;
531 for (int i = 0; i < 10; i++) {
532 howmany = fabs(Random() % (skeleton.joints.size()));
534 flatvelocity = skeleton.joints[howmany].velocity;
535 flatfacing = skeleton.joints[howmany].position * scale + coords;
537 flatvelocity = velocity;
538 flatfacing = DoRotation(DoRotation(DoRotation(skeleton.joints[howmany].position, 0, 0, tilt), tilt2, 0, 0), 0, yaw, 0) * scale + coords;
540 Sprite::MakeSprite(flamesprite, flatfacing, flatvelocity, 1, 1, 1, 2, 1);
545 emit_sound_at(firestartsound, coords);
547 emit_stream_at(stream_firesound, coords);
555 * idle animation for this creature (depending on status)
557 int Person::getIdle()
559 if (Dialog::inDialog() && (howactive == typeactive) && (creature == rabbittype))
561 if (hasvictim && (victim != this->shared_from_this())/*||(id==0&&attackkeydown)*/)
562 if (/*(id==0&&attackkeydown)||*/(!victim->dead && victim->aitype != passivetype &&
563 victim->aitype != searchtype && aitype != passivetype && aitype != searchtype &&
564 victim->id < Person::players.size())) {
565 if ((aitype == playercontrolled && stunned <= 0 && weaponactive == -1) || pause) {
566 if (creature == rabbittype)
567 return fightidleanim;
568 if (creature == wolftype)
571 if (aitype == playercontrolled && stunned <= 0 && weaponactive != -1) {
572 if (weapons[weaponids[weaponactive]].getType() == knife)
573 return knifefightidleanim;
574 if (weapons[weaponids[weaponactive]].getType() == sword && victim->weaponactive != -1)
575 return swordfightidlebothanim;
576 if (weapons[weaponids[weaponactive]].getType() == sword)
577 return swordfightidleanim;
578 if (weapons[weaponids[weaponactive]].getType() == staff)
579 return swordfightidleanim;
581 if (aitype != playercontrolled && stunned <= 0 && creature != wolftype && !pause)
582 return fightsidestep;
584 if ((damage > permanentdamage || damage > damagetolerance * .8 || deathbleeding > 0) && creature != wolftype)
586 if (howactive == typesitting) return sitanim;
587 if (howactive == typesittingwall) return sitwallanim;
588 if (howactive == typesleeping) return sleepanim;
589 if (howactive == typedead1) return dead1anim;
590 if (howactive == typedead2) return dead2anim;
591 if (howactive == typedead3) return dead3anim;
592 if (howactive == typedead4) return dead4anim;
593 if (creature == rabbittype) return bounceidleanim;
594 if (creature == wolftype) return wolfidle;
599 * crouch animation for this creature
601 int Person::getCrouch()
603 if (creature == rabbittype)
605 if (creature == wolftype)
606 return wolfcrouchanim;
611 * running animation for this creature (can be upright or all fours)
615 if (creature == rabbittype && (!superruntoggle || weaponactive != -1))
617 if (creature == wolftype && (!superruntoggle))
620 if (creature == rabbittype && (superruntoggle && weaponactive == -1))
621 return rabbitrunninganim;
622 if (creature == wolftype && (superruntoggle))
623 return wolfrunninganim;
629 int Person::getStop()
631 if (creature == rabbittype)
633 if (creature == wolftype)
640 int Person::getLanding()
642 if (creature == rabbittype)
644 if (creature == wolftype)
651 int Person::getLandhard()
653 if (creature == rabbittype)
655 if (creature == wolftype)
656 return wolflandhardanim;
663 * Person::DoAnimations
666 SolidHitBonus(int playerid)
668 if (bonustime < 1.5 && bonus >= solidhit && bonus <= megacombo)
669 award_bonus(playerid, bonus == megacombo ? bonus : bonus + 1);
671 award_bonus(playerid, solidhit);
675 * spawns blood effects
677 void Person::DoBlood(float howmuch, int which)
679 // FIXME: should abstract out inputs
680 static int bleedxint, bleedyint;
682 if (bloodtoggle && !Tutorial::active) {
683 if (bleeding <= 0 && spurt) {
685 for (int i = 0; i < 3; i++) {
686 // emit blood particles
689 bloodvel -= DoRotation(skeleton.forward * 10 * scale, ((float)(Random() % 100)) / 4, ((float)(Random() % 100)) / 4, 0);
690 bloodvel += DoRotation(jointVel(head), ((float)(Random() % 100)) / 4, yaw + ((float)(Random() % 100)) / 4, 0) * scale;
691 Sprite::MakeSprite(bloodsprite, jointPos(head) * scale + coords, bloodvel, 1, 1, 1, .05, 1);
692 Sprite::MakeSprite(bloodflamesprite, jointPos(head) * scale + coords, bloodvel, 1, 1, 1, .3, 1);
695 bloodvel = DoRotation(bloodvel, ((float)(Random() % 100)) / 4, yaw + ((float)(Random() % 100)) / 4, 0) * scale;
696 bloodvel += DoRotation(velocity, ((float)(Random() % 100)) / 4, ((float)(Random() % 100)) / 4, 0) * scale;
697 Sprite::MakeSprite(bloodsprite, DoRotation((jointPos(head) + jointPos(neck)) / 2, 0, yaw, 0)*scale + coords, bloodvel, 1, 1, 1, .05, 1);
698 Sprite::MakeSprite(bloodflamesprite, DoRotation((jointPos(head) + jointPos(neck)) / 2, 0, yaw, 0)*scale + coords, bloodvel, 1, 1, 1, .3, 1);
701 if (Random() % 2 == 0) // 50% chance
702 for (int i = 0; i < 3; i++) {
703 if (Random() % 2 != 0) {
704 // emit teeth particles
707 bloodvel -= DoRotation(skeleton.forward * 10 * scale, ((float)(Random() % 100)) / 4, ((float)(Random() % 100)) / 4, 0);
708 bloodvel += DoRotation(jointVel(head), ((float)(Random() % 100)) / 4, yaw + ((float)(Random() % 100)) / 4, 0) * scale;
711 bloodvel = DoRotation(bloodvel, ((float)(Random() % 100)) / 4, yaw + ((float)(Random() % 100)) / 4, 0) * scale;
712 bloodvel += DoRotation(velocity, ((float)(Random() % 100)) / 4, ((float)(Random() % 100)) / 4, 0) * scale;
716 Sprite::MakeSprite(splintersprite, jointPos(head) * scale + coords, bloodvel, 1, 1, 1, .05, 1);
718 Sprite::MakeSprite(splintersprite, DoRotation((jointPos(head) + jointPos(neck)) / 2, 0, yaw, 0)*scale + coords, bloodvel, 1, 1, 1, .05, 1);
720 Sprite::setLastSpriteSpecial(3); // sets it to teeth
725 // FIXME: manipulating attributes
726 bleeding = howmuch + (float)abs(Random() % 100) / 200 - .25;
729 if (creature == rabbittype)
730 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) {
731 bleedxint = abs(Random() % 512);
732 bleedyint = abs(Random() % 512);
734 if (creature == wolftype)
735 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) {
736 bleedxint = abs(Random() % 512);
737 bleedyint = abs(Random() % 512);
741 bleedy /= realtexdetail;
742 bleedx /= realtexdetail;
743 direction = abs(Random() % 2) * 2 - 1;
752 * spawns big blood effects and ???
753 * modifies character's skin texture
755 void Person::DoBloodBig(float howmuch, int which)
757 static int bleedxint, bleedyint, i, j;
759 if (howmuch && id == 0)
762 if (!Tutorial::active || id == 0)
763 if (aitype != playercontrolled && howmuch > 0) {
767 if (creature == wolftype) {
768 int i = abs(Random() % 2);
770 whichsound = snarlsound;
772 whichsound = snarl2sound;
774 if (creature == rabbittype) {
775 int i = abs(Random() % 2);
777 whichsound = rabbitpainsound;
778 if (i == 1 && howmuch >= 2)
779 whichsound = rabbitpain1sound;
782 if (whichsound != -1) {
783 emit_sound_at(whichsound, coords);
788 if (id == 0 && howmuch > 0) {
792 if (bloodtoggle && decals && !Tutorial::active) {
793 if (bleeding <= 0 && spurt) {
795 for (int i = 0; i < 3; i++) {
796 // emit blood particles
797 // FIXME: copypaste from above
800 bloodvel -= DoRotation(skeleton.forward * 10 * scale, ((float)(Random() % 100)) / 4, ((float)(Random() % 100)) / 4, 0);
801 bloodvel += DoRotation(jointVel(head), ((float)(Random() % 100)) / 4, yaw + ((float)(Random() % 100)) / 4, 0) * scale;
802 Sprite::MakeSprite(bloodsprite, jointPos(head) * scale + coords, bloodvel, 1, 1, 1, .05, 1);
803 Sprite::MakeSprite(bloodflamesprite, jointPos(head) * scale + coords, bloodvel, 1, 1, 1, .3, 1);
806 bloodvel = DoRotation(bloodvel, ((float)(Random() % 100)) / 4, yaw + ((float)(Random() % 100)) / 4, 0) * scale;
807 bloodvel += DoRotation(velocity, ((float)(Random() % 100)) / 4, ((float)(Random() % 100)) / 4, 0) * scale;
808 Sprite::MakeSprite(bloodsprite, DoRotation((jointPos(head) + jointPos(neck)) / 2, 0, yaw, 0)*scale + coords, bloodvel, 1, 1, 1, .05, 1);
809 Sprite::MakeSprite(bloodflamesprite, DoRotation((jointPos(head) + jointPos(neck)) / 2, 0, yaw, 0)*scale + coords, bloodvel, 1, 1, 1, .3, 1);
814 // weird texture manipulation code follows.
815 // looks like this is painting blood onto the character's skin texture
816 // FIXME: surely there's a better way
818 int offsetx = 0, offsety = 0;
820 offsety = Random() % 40;
821 offsetx = abs(Random() % 60);
823 if (which == 190 || which == 185) {
824 offsety = Random() % 40;
825 offsetx = abs(Random() % 100) - 20;
828 offsety = Random() % 10;
829 offsetx = Random() % 10;
832 offsety = Random() % 20;
833 offsetx = Random() % 20;
835 if (which == 220 || which == 215) {
845 if (creature == rabbittype)
846 for (i = 0; i < 512; i++) {
847 for (j = 0; j < 512; j++) {
848 if (bloodText[i * 512 * 3 + j * 3 + 0] <= which + 4 && bloodText[i * 512 * 3 + j * 3 + 0] >= which - 4) {
849 if (i < startx) startx = i;
850 if (j < starty) starty = j;
851 if (i > endx) endx = i;
852 if (j > endy) endy = j;
856 if (creature == wolftype)
857 for (i = 0; i < 512; i++) {
858 for (j = 0; j < 512; j++) {
859 if (wolfbloodText[i * 512 * 3 + j * 3 + 0] <= which + 4 && wolfbloodText[i * 512 * 3 + j * 3 + 0] >= which - 4) {
860 if (i < startx) startx = i;
861 if (j < starty) starty = j;
862 if (i > endx) endx = i;
863 if (j > endy) endy = j;
873 if (startx < 0) startx = 0;
874 if (starty < 0) starty = 0;
875 if (endx > 512 - 1) endx = 512 - 1;
876 if (endy > 512 - 1) endy = 512 - 1;
877 if (endx < startx) endx = startx;
878 if (endy < starty) endy = starty;
880 startx /= realtexdetail;
881 starty /= realtexdetail;
882 endx /= realtexdetail;
883 endy /= realtexdetail;
885 int texdetailint = realtexdetail;
887 if (creature == rabbittype)
888 for (i = startx; i < endx; i++) {
889 for (j = starty; j < endy; j++) {
890 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) {
891 color = Random() % 85 + 170;
892 where = i * skeleton.skinsize * 3 + j * 3;
893 if (skeleton.skinText[where + 0] > color / 2)
894 skeleton.skinText[where + 0] = color / 2;
895 skeleton.skinText[where + 1] = 0;
896 skeleton.skinText[where + 2] = 0;
900 if (creature == wolftype)
901 for (i = startx; i < endx; i++) {
902 for (j = starty; j < endy; j++) {
903 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) {
904 color = Random() % 85 + 170;
905 where = i * skeleton.skinsize * 3 + j * 3;
906 if (skeleton.skinText[where + 0] > color / 2)
907 skeleton.skinText[where + 0] = color / 2;
908 skeleton.skinText[where + 1] = 0;
909 skeleton.skinText[where + 2] = 0;
913 skeleton.drawmodel.textureptr.bind();
918 if (creature == rabbittype)
919 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) {
920 bleedxint = abs(Random() % 512);
921 bleedyint = abs(Random() % 512);
923 if (creature == wolftype)
924 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) {
925 bleedxint = abs(Random() % 512);
926 bleedyint = abs(Random() % 512);
928 bleedy = bleedxint + offsetx;
929 bleedx = bleedyint + offsety;
930 bleedy /= realtexdetail;
931 bleedx /= realtexdetail;
936 if (bleedx > skeleton.skinsize - 1)
937 bleedx = skeleton.skinsize - 1;
938 if (bleedy > skeleton.skinsize - 1)
939 bleedy = skeleton.skinsize - 1;
940 direction = abs(Random() % 2) * 2 - 1;
943 bleeding = howmuch + (float)abs(Random() % 100) / 200 - .25;
944 deathbleeding += bleeding;
945 bloodloss += bleeding * 3;
947 if (!Tutorial::active && aitype != playercontrolled && bloodloss > damagetolerance * 2 / 3 && bloodloss < damagetolerance && creature == rabbittype) {
948 if (abs(Random() % 2) == 0) {
949 aitype = gethelptype;
952 aitype = attacktypecutoff;
960 * similar to DoBloodBig
962 bool Person::DoBloodBigWhere(float howmuch, int which, XYZ where)
966 static XYZ startpoint, endpoint, colpoint, movepoint;
967 static float rotationpoint;
969 static XYZ p1, p2, p3, p0;
972 float coordsx, coordsy;
975 if (bloodtoggle && decals && !Tutorial::active) {
978 where = DoRotation(where, 0, -yaw, 0);
986 // ray testing for a tri in the character model
987 whichtri = skeleton.drawmodel.LineCheck(&startpoint, &endpoint, &colpoint, &movepoint, &rotationpoint);
988 if (whichtri != -1) {
989 // low level geometry math
991 p1 = skeleton.drawmodel.vertex[skeleton.drawmodel.Triangles[whichtri].vertex[0]];
992 p2 = skeleton.drawmodel.vertex[skeleton.drawmodel.Triangles[whichtri].vertex[1]];
993 p3 = skeleton.drawmodel.vertex[skeleton.drawmodel.Triangles[whichtri].vertex[2]];
995 bary.x = distsq(&p0, &p1);
996 bary.y = distsq(&p0, &p2);
997 bary.z = distsq(&p0, &p3);
999 total = bary.x + bary.y + bary.z;
1004 bary.x = 1 - bary.x;
1005 bary.y = 1 - bary.y;
1006 bary.z = 1 - bary.z;
1008 total = bary.x + bary.y + bary.z;
1014 gxx.x = skeleton.drawmodel.Triangles[whichtri].gx[0];
1015 gxx.y = skeleton.drawmodel.Triangles[whichtri].gx[1];
1016 gxx.z = skeleton.drawmodel.Triangles[whichtri].gx[2];
1017 gyy.x = skeleton.drawmodel.Triangles[whichtri].gy[0];
1018 gyy.y = skeleton.drawmodel.Triangles[whichtri].gy[1];
1019 gyy.z = skeleton.drawmodel.Triangles[whichtri].gy[2];
1020 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;
1021 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;
1023 if (bleeding <= 0 && spurt) {
1025 for (int i = 0; i < 3; i++) {
1026 // emit blood particles
1027 // FIXME: more copypaste code
1029 if (skeleton.free) {
1030 bloodvel -= DoRotation(skeleton.forward * 10 * scale, ((float)(Random() % 100)) / 4, ((float)(Random() % 100)) / 4, 0);
1031 bloodvel += DoRotation(jointVel(head), ((float)(Random() % 100)) / 4, yaw + ((float)(Random() % 100)) / 4, 0) * scale;
1032 Sprite::MakeSprite(bloodsprite, jointPos(head) * scale + coords, bloodvel, 1, 1, 1, .05, 1);
1033 Sprite::MakeSprite(bloodflamesprite, jointPos(head) * scale + coords, bloodvel, 1, 1, 1, .3, 1);
1036 bloodvel = DoRotation(bloodvel, ((float)(Random() % 100)) / 4, yaw + ((float)(Random() % 100)) / 4, 0) * scale;
1037 bloodvel += DoRotation(velocity, ((float)(Random() % 100)) / 4, ((float)(Random() % 100)) / 4, 0) * scale;
1038 Sprite::MakeSprite(bloodsprite, DoRotation((jointPos(head) + jointPos(neck)) / 2, 0, yaw, 0)*scale + coords, bloodvel, 1, 1, 1, .05, 1);
1039 Sprite::MakeSprite(bloodflamesprite, DoRotation((jointPos(head) + jointPos(neck)) / 2, 0, yaw, 0)*scale + coords, bloodvel, 1, 1, 1, .3, 1);
1044 // texture manipulation follows
1046 int offsetx = 0, offsety = 0;
1047 offsetx = (1 + coordsy) * 512 - 291;
1048 offsety = coordsx * 512 - 437;
1055 if (creature == rabbittype)
1056 for (i = 0; i < 512; i++) {
1057 for (j = 0; j < 512; j++) {
1058 if (bloodText[i * 512 * 3 + j * 3 + 0] <= which + 4 && bloodText[i * 512 * 3 + j * 3 + 0] >= which - 4) {
1059 if (i < startx) startx = i;
1060 if (j < starty) starty = j;
1061 if (i > endx) endx = i;
1062 if (j > endy) endy = j;
1066 if (creature == wolftype)
1067 for (i = 0; i < 512; i++) {
1068 for (j = 0; j < 512; j++) {
1069 if (wolfbloodText[i * 512 * 3 + j * 3 + 0] <= which + 4 && wolfbloodText[i * 512 * 3 + j * 3 + 0] >= which - 4) {
1070 if (i < startx) startx = i;
1071 if (j < starty) starty = j;
1072 if (i > endx) endx = i;
1073 if (j > endy) endy = j;
1082 if (startx < 0) startx = 0;
1083 if (starty < 0) starty = 0;
1084 if (endx > 512 - 1) endx = 512 - 1;
1085 if (endy > 512 - 1) endy = 512 - 1;
1086 if (endx < startx) endx = startx;
1087 if (endy < starty) endy = starty;
1089 startx /= realtexdetail;
1090 starty /= realtexdetail;
1091 endx /= realtexdetail;
1092 endy /= realtexdetail;
1094 int texdetailint = realtexdetail;
1096 if (creature == rabbittype)
1097 for (i = startx; i < endx; i++) {
1098 for (j = starty; j < endy; j++) {
1099 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) {
1100 color = Random() % 85 + 170;
1101 where = i * skeleton.skinsize * 3 + j * 3;
1102 if (skeleton.skinText[where + 0] > color / 2)
1103 skeleton.skinText[where + 0] = color / 2;
1104 skeleton.skinText[where + 1] = 0;
1105 skeleton.skinText[where + 2] = 0;
1106 } 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) {
1107 color = Random() % 85 + 170;
1108 where = i * skeleton.skinsize * 3 + j * 3;
1109 if (skeleton.skinText[where + 0] > color / 2)
1110 skeleton.skinText[where + 0] = color / 2;
1111 skeleton.skinText[where + 1] = 0;
1112 skeleton.skinText[where + 2] = 0;
1116 if (creature == wolftype)
1117 for (i = startx; i < endx; i++) {
1118 for (j = starty; j < endy; j++) {
1119 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) {
1120 color = Random() % 85 + 170;
1121 where = i * skeleton.skinsize * 3 + j * 3;
1122 if (skeleton.skinText[where + 0] > color / 2)
1123 skeleton.skinText[where + 0] = color / 2;
1124 skeleton.skinText[where + 1] = 0;
1125 skeleton.skinText[where + 2] = 0;
1126 } 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) {
1127 color = Random() % 85 + 170;
1128 where = i * skeleton.skinsize * 3 + j * 3;
1129 if (skeleton.skinText[where + 0] > color / 2)
1130 skeleton.skinText[where + 0] = color / 2;
1131 skeleton.skinText[where + 1] = 0;
1132 skeleton.skinText[where + 2] = 0;
1136 skeleton.drawmodel.textureptr.bind();
1139 bleedy = (1 + coordsy) * 512;
1140 bleedx = coordsx * 512;
1141 bleedy /= realtexdetail;
1142 bleedx /= realtexdetail;
1147 if (bleedx > skeleton.skinsize - 1)
1148 bleedx = skeleton.skinsize - 1;
1149 if (bleedy > skeleton.skinsize - 1)
1150 bleedy = skeleton.skinsize - 1;
1151 direction = abs(Random() % 2) * 2 - 1;
1156 bleeding = howmuch + (float)abs(Random() % 100) / 200 - .25;
1157 deathbleeding += bleeding;
1158 bloodloss += bleeding * 3;
1160 if (!Tutorial::active && aitype != playercontrolled && bloodloss > damagetolerance * 2 / 3 && bloodloss < damagetolerance && creature == rabbittype) {
1161 if (abs(Random() % 2) == 0) {
1162 aitype = gethelptype;
1165 aitype = attacktypecutoff;
1176 * guessing this performs a reversal
1178 void Person::Reverse()
1180 if (!((victim->aitype == playercontrolled
1182 || staggerdelay <= 0)
1183 && victim->animTarget != jumpupanim
1184 && victim->animTarget != jumpdownanim
1185 && (!Tutorial::active || cananger)
1189 if (normaldotproduct (victim->facing, victim->coords - coords) > 0
1190 && (victim->id != 0 || difficulty >= 2)
1191 && (creature != wolftype || victim->creature == wolftype))
1194 if (animTarget == sweepanim) {
1195 animTarget = sweepreversedanim;
1196 animCurrent = sweepreversedanim;
1197 victim->animCurrent = sweepreversalanim;
1198 victim->animTarget = sweepreversalanim;
1200 if (animTarget == spinkickanim) {
1201 animTarget = spinkickreversedanim;
1202 animCurrent = spinkickreversedanim;
1203 victim->animCurrent = spinkickreversalanim;
1204 victim->animTarget = spinkickreversalanim;
1206 if (animTarget == upunchanim || animTarget == rabbittacklinganim) {
1207 if (animTarget == rabbittacklinganim) {
1210 victim->frameCurrent = 6;
1211 victim->frameTarget = 7;
1213 animTarget = upunchreversedanim;
1214 animCurrent = upunchreversedanim;
1215 victim->animCurrent = upunchreversalanim;
1216 victim->animTarget = upunchreversalanim;
1218 if (animTarget == staffhitanim && distsq(&victim->coords, &coords) < 2 && ((victim->id == 0 && victim->crouchkeydown) || Random() % 4 == 0)) {
1219 if (victim->weaponactive != -1) {
1220 victim->throwtogglekeydown = 1;
1221 XYZ tempVelocity = victim->velocity * .2;
1222 if (tempVelocity.x == 0)
1223 tempVelocity.x = .1;
1224 weapons[victim->weaponids[0]].drop(tempVelocity, tempVelocity, false);
1225 victim->num_weapons--;
1226 if (victim->num_weapons) {
1227 victim->weaponids[0] = victim->weaponids[victim->num_weapons];
1228 if (victim->weaponstuck == victim->num_weapons)
1229 victim->weaponstuck = 0;
1232 victim->weaponactive = -1;
1233 for (unsigned j = 0; j < Person::players.size(); j++) {
1234 Person::players[j]->wentforweapon = 0;
1238 animTarget = staffhitreversedanim;
1239 animCurrent = staffhitreversedanim;
1240 victim->animCurrent = staffhitreversalanim;
1241 victim->animTarget = staffhitreversalanim;
1243 if (animTarget == staffspinhitanim && distsq(&victim->coords, &coords) < 2 && ((victim->id == 0 && victim->crouchkeydown) || Random() % 2 == 0)) {
1244 if (victim->weaponactive != -1) {
1245 victim->throwtogglekeydown = 1;
1246 XYZ tempVelocity = victim->velocity * .2;
1247 if (tempVelocity.x == 0)
1248 tempVelocity.x = .1;
1249 weapons[victim->weaponids[0]].drop(tempVelocity, tempVelocity, false);
1250 victim->num_weapons--;
1251 if (victim->num_weapons) {
1252 victim->weaponids[0] = victim->weaponids[victim->num_weapons];
1253 if (victim->weaponstuck == victim->num_weapons)
1254 victim->weaponstuck = 0;
1257 victim->weaponactive = -1;
1258 for (unsigned j = 0; j < Person::players.size(); j++) {
1259 Person::players[j]->wentforweapon = 0;
1262 animTarget = staffspinhitreversedanim;
1263 animCurrent = staffspinhitreversedanim;
1264 victim->animCurrent = staffspinhitreversalanim;
1265 victim->animTarget = staffspinhitreversalanim;
1267 if (animTarget == swordslashanim && distsq(&victim->coords, &coords) < 2 && ((victim->id == 0 && victim->crouchkeydown) || Random() % 4 == 0)) {
1268 if (victim->weaponactive != -1) {
1269 victim->throwtogglekeydown = 1;
1270 XYZ tempVelocity = victim->velocity * .2;
1271 if (tempVelocity.x == 0)
1272 tempVelocity.x = .1;
1273 weapons[victim->weaponids[0]].drop(tempVelocity, tempVelocity, false);
1274 victim->num_weapons--;
1275 if (victim->num_weapons) {
1276 victim->weaponids[0] = victim->weaponids[victim->num_weapons];
1277 if (victim->weaponstuck == victim->num_weapons)
1278 victim->weaponstuck = 0;
1281 victim->weaponactive = -1;
1282 for (unsigned j = 0; j < Person::players.size(); j++) {
1283 Person::players[j]->wentforweapon = 0;
1286 animTarget = swordslashreversedanim;
1287 animCurrent = swordslashreversedanim;
1288 victim->animCurrent = swordslashreversalanim;
1289 victim->animTarget = swordslashreversalanim;
1291 if (animTarget == knifeslashstartanim && distsq(&victim->coords, &coords) < 2 && (victim->id == 0 || Random() % 4 == 0)) {
1292 if (victim->weaponactive != -1) {
1293 victim->throwtogglekeydown = 1;
1294 XYZ tempVelocity = victim->velocity * .2;
1295 if (tempVelocity.x == 0)
1296 tempVelocity.x = .1;
1297 weapons[victim->weaponids[0]].drop(tempVelocity, tempVelocity, false);
1298 victim->num_weapons--;
1299 if (victim->num_weapons) {
1300 victim->weaponids[0] = victim->weaponids[victim->num_weapons];
1301 if (victim->weaponstuck == victim->num_weapons)
1302 victim->weaponstuck = 0;
1305 victim->weaponactive = -1;
1306 for (unsigned j = 0; j < Person::players.size(); j++) {
1307 Person::players[j]->wentforweapon = 0;
1310 animTarget = knifeslashreversedanim;
1311 animCurrent = knifeslashreversedanim;
1312 victim->animCurrent = knifeslashreversalanim;
1313 victim->animTarget = knifeslashreversalanim;
1315 if (animTarget != knifeslashstartanim && animTarget != staffhitanim && animTarget != staffspinhitanim && animTarget != winduppunchanim && animTarget != wolfslapanim && animTarget != swordslashanim) {
1316 victim->targettilt2 = targettilt2;
1317 victim->frameCurrent = frameCurrent;
1318 victim->frameTarget = frameTarget;
1319 victim->target = target;
1320 victim->velocity = 0;
1321 victim->oldcoords = victim->coords;
1322 victim->coords = coords;
1323 victim->targetyaw = targetyaw;
1324 victim->yaw = targetyaw;
1325 victim->victim = this->shared_from_this();
1327 if (animTarget == winduppunchanim) {
1328 animTarget = winduppunchblockedanim;
1329 victim->animTarget = blockhighleftanim;
1330 victim->frameTarget = 1;
1331 victim->target = .5;
1332 victim->victim = this->shared_from_this();
1333 victim->targetyaw = targetyaw + 180;
1335 if (animTarget == wolfslapanim) {
1336 animTarget = winduppunchblockedanim;
1337 victim->animTarget = blockhighleftanim;
1338 victim->frameTarget = 1;
1339 victim->target = .5;
1340 victim->victim = this->shared_from_this();
1341 victim->targetyaw = targetyaw + 180;
1343 if ((animTarget == swordslashanim || animTarget == staffhitanim || animTarget == staffspinhitanim) && victim->weaponactive != -1) {
1344 animTarget = swordslashparriedanim;
1345 parriedrecently = .4;
1346 victim->parriedrecently = 0;
1347 victim->animTarget = swordslashparryanim;
1348 victim->frameTarget = 1;
1349 victim->target = .5;
1350 victim->victim = this->shared_from_this();
1351 victim->targetyaw = targetyaw + 180;
1353 if (abs(Random() % 20) == 0 || weapons[victim->weaponids[victim->weaponactive]].getType() == knife) {
1354 if (victim->weaponactive != -1) {
1355 if (weapons[victim->weaponids[0]].getType() == staff || weapons[weaponids[0]].getType() == staff) {
1356 if (weapons[victim->weaponids[0]].getType() == staff)
1357 weapons[victim->weaponids[0]].damage += .2 + float(abs(Random() % 100) - 50) / 250;
1358 if (weapons[weaponids[0]].getType() == staff)
1359 weapons[weaponids[0]].damage += .2 + float(abs(Random() % 100) - 50) / 250;
1360 emit_sound_at(swordstaffsound, victim->coords);
1362 emit_sound_at(metalhitsound, victim->coords);
1366 victim->Puff(righthand);
1368 victim->frameTarget = 0;
1369 victim->animTarget = staggerbackhighanim;
1370 victim->targetyaw = targetyaw + 180;
1372 aim = DoRotation(facing, 0, 90, 0) * 21;
1374 weapons[victim->weaponids[0]].drop(aim * -.2, aim);
1375 victim->num_weapons--;
1376 if (victim->num_weapons) {
1377 victim->weaponids[0] = victim->weaponids[num_weapons];
1378 if (victim->weaponstuck == victim->num_weapons)
1379 victim->weaponstuck = 0;
1381 victim->weaponactive = -1;
1382 for (unsigned i = 0; i < Person::players.size(); i++) {
1383 Person::players[i]->wentforweapon = 0;
1387 if (abs(Random() % 20) == 0) {
1388 if (weaponactive != -1) {
1389 if (weapons[victim->weaponids[0]].getType() == staff || weapons[weaponids[0]].getType() == staff) {
1390 if (weapons[victim->weaponids[0]].getType() == staff)
1391 weapons[victim->weaponids[0]].damage += .2 + float(abs(Random() % 100) - 50) / 250;
1392 if (weapons[weaponids[0]].getType() == staff)
1393 weapons[weaponids[0]].damage += .2 + float(abs(Random() % 100) - 50) / 250;
1395 emit_sound_at(swordstaffsound, coords);
1397 emit_sound_at(metalhitsound, coords);
1405 animTarget = staggerbackhighanim;
1406 targetyaw = targetyaw + 180;
1408 aim = DoRotation(facing, 0, 90, 0) * 21;
1410 weapons[victim->weaponids[0]].drop(aim * -.2, aim);
1413 weaponids[0] = weaponids[num_weapons];
1414 if (weaponstuck == num_weapons)
1418 for (unsigned i = 0; i < Person::players.size(); i++) {
1419 Person::players[i]->wentforweapon = 0;
1426 if (animTarget == knifeslashstartanim || animTarget == swordslashanim || animTarget == staffhitanim || animTarget == staffspinhitanim) {
1427 if ((animTarget != staffhitanim && animTarget != staffspinhitanim) || distsq(&coords, &victim->coords) > .2) {
1428 victim->animTarget = dodgebackanim;
1429 victim->frameTarget = 0;
1433 rotatetarget = coords - victim->coords;
1434 Normalise(&rotatetarget);
1435 victim->targetyaw = -asin(0 - rotatetarget.x);
1436 victim->targetyaw *= 360 / 6.28;
1437 if (rotatetarget.z < 0)
1438 victim->targetyaw = 180 - victim->targetyaw;
1440 victim->targettilt2 = -asin(rotatetarget.y) * 360 / 6.28; //*-70;
1442 victim->lastattack3 = victim->lastattack2;
1443 victim->lastattack2 = victim->lastattack;
1444 victim->lastattack = victim->animTarget;
1446 victim->animTarget = sweepanim;
1447 victim->frameTarget = 0;
1451 rotatetarget = coords - victim->coords;
1452 Normalise(&rotatetarget);
1453 victim->targetyaw = -asin(0 - rotatetarget.x);
1454 victim->targetyaw *= 360 / 6.28;
1455 if (rotatetarget.z < 0)
1456 victim->targetyaw = 180 - victim->targetyaw;
1458 victim->targettilt2 = -asin(rotatetarget.y) * 360 / 6.28; //*-70;
1460 victim->lastattack3 = victim->lastattack2;
1461 victim->lastattack2 = victim->lastattack;
1462 victim->lastattack = victim->animTarget;
1467 victim->velocity = 0;
1469 if (aitype != playercontrolled) {
1471 if (escapednum < 2) {
1472 int chances = ((difficulty == 2) ? 3 : ((difficulty == 1) ? 5 : 10));
1473 if ((Random() % chances) == 0) {
1479 if (victim->id == 0 && Animation::animations[victim->animTarget].attack == reversal)
1486 void Person::DoDamage(float howmuch)
1488 // subtract health (temporary?)
1489 if (!Tutorial::active)
1490 damage += howmuch / power;
1493 damagedealt += howmuch / power;
1495 damagetaken += howmuch / power;
1498 if (id == 0 && (bonus == solidhit || bonus == twoxcombo || bonus == threexcombo || bonus == fourxcombo || bonus == megacombo))
1501 if (!Tutorial::active)
1502 permanentdamage += howmuch / 2 / power;
1503 if (!Tutorial::active)
1504 superpermanentdamage += howmuch / 4 / power;
1506 if (permanentdamage > damagetolerance / 2 && permanentdamage - howmuch < damagetolerance / 2 && Random() % 2)
1508 if ((permanentdamage > damagetolerance * .8 && Random() % 2 && !deathbleeding) || spurt)
1512 camerashake += howmuch / 100;
1513 if (id == 0 && ((howmuch > 50 && damage > damagetolerance / 2)))
1514 blackout = damage / damagetolerance;
1519 if (aitype == passivetype && damage < damagetolerance && ((!Tutorial::active || cananger) && hostile))
1520 aitype = attacktypecutoff;
1521 if (!Tutorial::active && aitype != playercontrolled && damage < damagetolerance && damage > damagetolerance * 2 / 3 && creature == rabbittype) {
1522 if (abs(Random() % 2) == 0) {
1523 aitype = gethelptype;
1526 aitype = attacktypecutoff;
1530 if (howmuch > damagetolerance * 50 && skeleton.free != 2) {
1533 for (unsigned i = 0; i < skeleton.joints.size(); i++) {
1534 if (skeleton.free) {
1535 flatvelocity2 = skeleton.joints[i].velocity;
1536 flatfacing2 = skeleton.joints[i].position * scale + coords;
1538 flatvelocity2 = velocity;
1539 flatfacing2 = DoRotation(DoRotation(DoRotation(skeleton.joints[i].position, 0, 0, tilt), tilt2, 0, 0), 0, yaw, 0) * scale + coords;
1541 flatvelocity2.x += (float)(abs(Random() % 100) - 50) / 10;
1542 flatvelocity2.y += (float)(abs(Random() % 100) - 50) / 10;
1543 flatvelocity2.z += (float)(abs(Random() % 100) - 50) / 10;
1544 Sprite::MakeSprite(bloodflamesprite, flatfacing2, flatvelocity2, 1, 1, 1, 3, 1);
1545 Sprite::MakeSprite(bloodsprite, flatfacing2, flatvelocity2, 1, 1, 1, .4, 1);
1546 Sprite::MakeSprite(cloudsprite, flatfacing2, flatvelocity2 * 0, .6, 0, 0, 1, .5);
1549 emit_sound_at(splattersound, coords);
1554 if (!dead && creature == wolftype) {
1555 award_bonus(0, Wolfbonus);
1562 if (!Tutorial::active || id == 0)
1563 if (speechdelay <= 0 && !dead && aitype != playercontrolled) {
1564 int whichsound = -1;
1566 if (creature == wolftype) {
1567 int i = abs(Random() % 2);
1569 whichsound = snarlsound;
1571 whichsound = snarl2sound;
1573 if (creature == rabbittype) {
1574 int i = abs(Random() % 2);
1576 whichsound = rabbitpainsound;
1577 if (i == 1 && damage > damagetolerance)
1578 whichsound = rabbitpain1sound;
1581 if (whichsound != -1) {
1582 emit_sound_at(whichsound, coords);
1583 addEnvSound(coords);
1590 * calculate/animate head facing direction?
1592 void Person::DoHead()
1594 static XYZ rotatearound;
1596 static float lookspeed = 500;
1598 if (!freeze && !winfreeze) {
1601 targetheadyaw = (float)((int)((0 - yaw - targetheadyaw + 180) * 100) % 36000) / 100;
1602 targetheadpitch = (float)((int)(targetheadpitch * 100) % 36000) / 100;
1604 while (targetheadyaw > 180)targetheadyaw -= 360;
1605 while (targetheadyaw < -180)targetheadyaw += 360;
1607 if (targetheadyaw > 160)
1608 targetheadpitch = targetheadpitch * -1;
1609 if (targetheadyaw < -160)
1610 targetheadpitch = targetheadpitch * -1;
1611 if (targetheadyaw > 160)
1612 targetheadyaw = targetheadyaw - 180;
1613 if (targetheadyaw < -160)
1614 targetheadyaw = targetheadyaw + 180;
1616 if (targetheadpitch > 120)
1617 targetheadpitch = 120;
1618 if (targetheadpitch < -120)
1619 targetheadpitch = -120;
1620 if (targetheadyaw > 120)
1621 targetheadyaw = 120;
1622 if (targetheadyaw < -120)
1623 targetheadyaw = -120;
1626 targetheadpitch = 0;
1628 if (targetheadyaw > 80)
1630 if (targetheadyaw < -80)
1631 targetheadyaw = -80;
1632 if (targetheadpitch > 50)
1633 targetheadpitch = 50;
1634 if (targetheadpitch < -50)
1635 targetheadpitch = -50;
1638 if (abs(headyaw - targetheadyaw) < multiplier * lookspeed)
1639 headyaw = targetheadyaw;
1640 else if (headyaw > targetheadyaw) {
1641 headyaw -= multiplier * lookspeed;
1642 } else if (headyaw < targetheadyaw) {
1643 headyaw += multiplier * lookspeed;
1646 if (abs(headpitch - targetheadpitch) < multiplier * lookspeed / 2)
1647 headpitch = targetheadpitch;
1648 else if (headpitch > targetheadpitch) {
1649 headpitch -= multiplier * lookspeed / 2;
1650 } else if (headpitch < targetheadpitch) {
1651 headpitch += multiplier * lookspeed / 2;
1654 rotatearound = jointPos(neck);
1655 jointPos(head) = rotatearound + DoRotation(jointPos(head) - rotatearound, headpitch, 0, 0);
1659 if (animTarget != bounceidleanim && animTarget != fightidleanim && animTarget != wolfidle && animTarget != knifefightidleanim && animTarget != drawrightanim && animTarget != drawleftanim && animTarget != walkanim) {
1660 facing = DoRotation(facing, headpitch * .4, 0, 0);
1661 facing = DoRotation(facing, 0, headyaw * .4, 0);
1664 if (animTarget == bounceidleanim || animTarget == fightidleanim || animTarget == wolfidle || animTarget == knifefightidleanim || animTarget == drawrightanim || animTarget == drawleftanim) {
1665 facing = DoRotation(facing, headpitch * .8, 0, 0);
1666 facing = DoRotation(facing, 0, headyaw * .8, 0);
1669 if (animTarget == walkanim) {
1670 facing = DoRotation(facing, headpitch * .6, 0, 0);
1671 facing = DoRotation(facing, 0, headyaw * .6, 0);
1674 skeleton.specialforward[0] = facing;
1675 //skeleton.specialforward[0]=DoRotation(facing,0,yaw,0);
1676 for (unsigned i = 0; i < skeleton.muscles.size(); i++) {
1677 if (skeleton.muscles[i].visible && (skeleton.muscles[i].parent1->label == head || skeleton.muscles[i].parent2->label == head)) {
1678 skeleton.FindRotationMuscle(i, animTarget);
1685 * ragdolls character?
1687 void Person::RagDoll(bool checkcollision)
1692 if (!skeleton.free) {
1695 if (id == 0 && isFlip())
1702 facing = DoRotation(facing, 0, yaw, 0);
1704 skeleton.freetime = 0;
1706 skeleton.longdead = 0;
1709 skeleton.broken = 0;
1710 skeleton.spinny = 1;
1712 skeleton.freefall = 1;
1714 if (!isnormal(velocity.x)) velocity.x = 0;
1715 if (!isnormal(velocity.y)) velocity.y = 0;
1716 if (!isnormal(velocity.z)) velocity.z = 0;
1717 if (!isnormal(yaw)) yaw = 0;
1718 if (!isnormal(coords.x)) coords = 0;
1719 if (!isnormal(tilt)) tilt = 0;
1720 if (!isnormal(tilt2)) tilt2 = 0;
1722 for (unsigned i = 0; i < skeleton.joints.size(); i++) {
1723 skeleton.joints[i].delay = 0;
1724 skeleton.joints[i].locked = 0;
1725 skeleton.joints[i].position = DoRotation(DoRotation(DoRotation(skeleton.joints[i].position, 0, 0, tilt), tilt2, 0, 0), 0, yaw, 0);
1726 if (!isnormal(skeleton.joints[i].position.x)) skeleton.joints[i].position = DoRotation(skeleton.joints[i].position, 0, yaw, 0);
1727 if (!isnormal(skeleton.joints[i].position.x)) skeleton.joints[i].position = coords;
1728 skeleton.joints[i].position.y += .1;
1729 skeleton.joints[i].oldposition = skeleton.joints[i].position;
1730 skeleton.joints[i].realoldposition = skeleton.joints[i].position * scale + coords;
1733 for (unsigned i = 0; i < skeleton.joints.size(); i++) {
1734 skeleton.joints[i].velocity = 0;
1735 skeleton.joints[i].velchange = 0;
1737 skeleton.DoConstraints(&coords, &scale);
1738 if (Animation::animations[animCurrent].height == lowheight || Animation::animations[animTarget].height == lowheight) {
1739 skeleton.DoConstraints(&coords, &scale);
1740 skeleton.DoConstraints(&coords, &scale);
1741 skeleton.DoConstraints(&coords, &scale);
1742 skeleton.DoConstraints(&coords, &scale);
1745 speed = targetFrame().speed * 2;
1746 if (currentFrame().speed > targetFrame().speed) {
1747 speed = currentFrame().speed * 2;
1750 speed = transspeed * 2;
1754 for (unsigned i = 0; i < skeleton.joints.size(); i++) {
1755 if ((Animation::animations[animCurrent].attack != reversed || animCurrent == swordslashreversedanim) && animCurrent != rabbitkickanim && !isLanding() && !wasLanding() && Animation::animations[animCurrent].height == Animation::animations[animTarget].height)
1756 skeleton.joints[i].velocity = velocity / scale + facing * 5 + DoRotation(DoRotation(DoRotation((targetFrame().joints[i].position - currentFrame().joints[i].position) * speed, 0, 0, tilt), tilt2, 0, 0), 0, yaw, 0);
1758 skeleton.joints[i].velocity = velocity / scale + facing * 5;
1759 change.x = (float)(Random() % 100) / 100;
1760 change.y = (float)(Random() % 100) / 100;
1761 change.z = (float)(Random() % 100) / 100;
1762 skeleton.joints[i].velocity += change;
1763 skeleton.joints[fabs(Random() % skeleton.joints.size())].velocity -= change;
1765 change.x = (float)(Random() % 100) / 100;
1766 change.y = (float)(Random() % 100) / 100;
1767 change.z = (float)(Random() % 100) / 100;
1768 skeleton.joints[i].velchange += change;
1769 skeleton.joints[fabs(Random() % skeleton.joints.size())].velchange -= change;
1772 if (checkcollision) {
1775 if (!skeleton.joints.empty()) {
1778 for (unsigned j = 0; j < skeleton.joints.size(); j++) {
1779 average += skeleton.joints[j].position;
1781 average /= skeleton.joints.size();
1782 coords += average * scale;
1783 for (unsigned j = 0; j < skeleton.joints.size(); j++) {
1784 skeleton.joints[j].position -= average;
1788 whichpatchx = coords.x / (terrain.size / subdivision * terrain.scale);
1789 whichpatchz = coords.z / (terrain.size / subdivision * terrain.scale);
1790 if (terrain.patchobjectnum[whichpatchx][whichpatchz])
1791 for (l = 0; l < terrain.patchobjectnum[whichpatchx][whichpatchz]; l++) {
1792 i = terrain.patchobjects[whichpatchx][whichpatchz][l];
1795 if (SphereCheck(&lowpoint, 3, &colpoint, &Object::objects[i]->position, &Object::objects[i]->yaw, &Object::objects[i]->model) != -1) {
1796 coords.x = lowpoint.x;
1797 coords.z = lowpoint.z;
1806 for (unsigned i = 0; i < skeleton.joints.size(); i++) {
1807 velocity += skeleton.joints[i].velocity * scale;
1809 velocity /= skeleton.joints.size();
1812 if (Random() % 2 == 0) {
1813 if (weaponactive != -1 && animTarget != rabbitkickanim && num_weapons > 0) {
1814 weapons[weaponids[0]].drop(jointVel(righthand) * scale * -.3, jointVel(righthand) * scale);
1815 weapons[weaponids[0]].velocity.x += .01;
1818 weaponids[0] = weaponids[num_weapons];
1819 if (weaponstuck == num_weapons)
1823 for (unsigned i = 0; i < Person::players.size(); i++) {
1824 Person::players[i]->wentforweapon = 0;
1829 animTarget = bounceidleanim;
1830 animCurrent = bounceidleanim;
1840 void Person::FootLand(bodypart whichfoot, float opacity)
1842 if ((whichfoot != leftfoot) && (whichfoot != rightfoot)) {
1843 cerr << "FootLand called on wrong bodypart" << endl;
1846 static XYZ terrainlight;
1847 static XYZ footvel, footpoint;
1848 if (opacity >= 1 || skiddelay <= 0) {
1851 footpoint = DoRotation(jointPos(whichfoot), 0, yaw, 0) * scale + coords;
1852 if (distsq(&footpoint, &viewer))
1853 Sprite::MakeSprite(cloudsprite, footpoint, footvel, 1, 1, 1, .5, .2 * opacity);
1854 } else if (onterrain && terrain.getOpacity(coords.x, coords.z) < .2) {
1855 footvel = velocity / 5;
1858 footpoint = DoRotation(jointPos(whichfoot), 0, yaw, 0) * scale + coords;
1859 footpoint.y = terrain.getHeight(footpoint.x, footpoint.z);
1860 terrainlight = terrain.getLighting(footpoint.x, footpoint.z);
1861 if (distsq(&footpoint, &viewer) < viewdistance * viewdistance / 4) {
1862 if (environment == snowyenvironment) {
1863 Sprite::MakeSprite(cloudsprite, footpoint, footvel * .6, terrainlight.x, terrainlight.y, terrainlight.z, .5, .7 * opacity);
1865 terrain.MakeDecal(footprintdecal, footpoint, .2, 1 * opacity, yaw);
1867 } else if (environment == grassyenvironment) {
1868 Sprite::MakeSprite(cloudsprite, footpoint, footvel * .6, terrainlight.x * 90 / 255, terrainlight.y * 70 / 255, terrainlight.z * 8 / 255, .5, .5 * opacity);
1869 } else if (environment == desertenvironment) {
1870 Sprite::MakeSprite(cloudsprite, footpoint, footvel * .6, terrainlight.x * 190 / 255, terrainlight.y * 170 / 255, terrainlight.z * 108 / 255, .5, .7 * opacity);
1872 terrain.MakeDecal(footprintdecal, footpoint, .2, .25 * opacity, yaw);
1876 } else if (isLanding() || (animTarget == jumpupanim) || isLandhard()) {
1877 footvel = velocity / 5;
1880 footpoint = DoRotation(jointPos(whichfoot), 0, yaw, 0) * scale + coords;
1881 if (distsq(&footpoint, &viewer) < viewdistance * viewdistance / 4) {
1882 Sprite::MakeSprite(cloudsprite, footpoint, footvel * .6, 1, 1, 1, .5, .2 * opacity);
1889 * make a puff effect at a body part (dust effect?)
1891 void Person::Puff(int whichlabel)
1893 static XYZ footvel, footpoint;
1896 footpoint = DoRotation(jointPos(whichlabel), 0, yaw, 0) * scale + coords;
1897 Sprite::MakeSprite(cloudimpactsprite, footpoint, footvel, 1, 1, 1, .9, .3);
1901 * I think I added this in an attempt to clean up code
1903 void Person::setAnimation(int animation)
1905 animTarget = animation;
1914 void Person::DoAnimations()
1916 if (!skeleton.free) {
1917 static float oldtarget;
1919 if (isIdle() && animCurrent != getIdle())
1920 normalsupdatedelay = 0;
1922 if (animTarget == tempanim || animCurrent == tempanim) {
1923 Animation::animations[tempanim] = tempanimation;
1925 if (animTarget == jumpupanim || animTarget == jumpdownanim || isFlip()) {
1931 vel[0] = velocity.x;
1932 vel[1] = velocity.y;
1933 vel[2] = velocity.z;
1936 OPENAL_3D_SetAttributes(channels[whooshsound], gLoc, vel);
1937 OPENAL_SetVolume(channels[whooshsound], 64 * findLength(&velocity) / 5);
1939 if (((velocity.y < -15) || (crouchkeydown && velocity.y < -8)) && abs(velocity.y) * 4 > fast_sqrt(velocity.x * velocity.x * velocity.z * velocity.z))
1941 if (!crouchkeydown && velocity.y >= -15)
1944 if ((animCurrent == jumpupanim || animTarget == jumpdownanim)/*&&velocity.y<40*/ && !isFlip() && (!isLanding() && !isLandhard()) && ((crouchkeydown && !crouchtogglekeydown))) {
1949 targfacing = DoRotation(targfacing, 0, targetyaw, 0);
1951 if (normaldotproduct(targfacing, velocity) >= -.3)
1952 animTarget = flipanim;
1954 animTarget = backflipanim;
1955 crouchtogglekeydown = 1;
1963 if (Animation::animations[animTarget].attack != reversed)
1965 if (!crouchkeydown || (isLanding() || isLandhard()) || (wasLanding() || wasLandhard())) {
1966 crouchtogglekeydown = 0;
1967 if (aitype == playercontrolled)
1970 if (!crouchtogglekeydown && Animation::animations[animTarget].attack == reversed && aitype == playercontrolled && (escapednum < 2 || reversaltrain))
1973 crouchtogglekeydown = 1;
1977 if (Animation::animations[animTarget].attack || animCurrent == getupfrombackanim || animCurrent == getupfromfrontanim) {
1979 normalsupdatedelay = 0;
1983 if (animTarget == rollanim && frameTarget == 3 && onfire) {
1985 emit_sound_at(fireendsound, coords);
1986 pause_sound(stream_firesound);
1990 if (animTarget == rabbittacklinganim && frameTarget == 1) {
1991 if (victim->aitype == attacktypecutoff && victim->stunned <= 0 && victim->surprised <= 0 && victim->id != 0)
1993 if (animTarget == rabbittacklinganim && frameTarget == 1 && !victim->isCrouch() && victim->animTarget != backhandspringanim) {
1994 if (normaldotproduct(victim->facing, facing) > 0)
1995 victim->animTarget = rabbittackledbackanim;
1997 victim->animTarget = rabbittackledfrontanim;
1998 victim->frameTarget = 2;
2001 victim->targetyaw = yaw;
2002 if (victim->aitype == gethelptype)
2003 victim->DoDamage(victim->damagetolerance - victim->damage);
2004 //victim->DoDamage(30);
2005 if (creature == wolftype) {
2007 emit_sound_at(clawslicesound, victim->coords);
2009 victim->DoBloodBig(1 / victim->armorhead, 210);
2011 award_bonus(id, TackleBonus,
2012 victim->aitype == gethelptype ? 50 : 0);
2016 if (!drawtogglekeydown && drawkeydown && (weaponactive == -1 || num_weapons == 1) && (targetFrame().label || (animTarget != animCurrent && animCurrent == rollanim)) && num_weapons > 0 && creature != wolftype) {
2017 if (weapons[weaponids[0]].getType() == knife) {
2018 if (weaponactive == -1)
2020 else if (weaponactive == 0)
2023 if (weaponactive == -1) {
2024 emit_sound_at(knifesheathesound, coords);
2026 if (weaponactive != -1) {
2027 emit_sound_at(knifedrawsound, coords, 128);
2030 drawtogglekeydown = 1;
2033 if (!Tutorial::active || id == 0)
2034 if ((targetFrame().label && (targetFrame().label < 5 || targetFrame().label == 8))) {
2035 int whichsound = -1;
2037 if (terrain.getOpacity(coords.x, coords.z) < .2) {
2038 if (targetFrame().label == 1)
2039 whichsound = footstepsound;
2041 whichsound = footstepsound2;
2042 if (targetFrame().label == 1)
2043 FootLand(leftfoot, 1);
2044 if (targetFrame().label == 2)
2045 FootLand(rightfoot, 1);
2046 if (targetFrame().label == 3 && isRun()) {
2047 FootLand(rightfoot, 1);
2048 FootLand(leftfoot, 1);
2052 if (terrain.getOpacity(coords.x, coords.z) >= .2) {
2053 if (targetFrame().label == 1)
2054 whichsound = footstepsound3;
2056 whichsound = footstepsound4;
2060 if (targetFrame().label == 1)
2061 whichsound = footstepsound3;
2063 whichsound = footstepsound4;
2065 if (targetFrame().label == 4 && (weaponactive == -1 || (animTarget != knifeslashstartanim && animTarget != knifethrowanim && animTarget != crouchstabanim && animTarget != swordgroundstabanim && animTarget != knifefollowanim))) {
2066 if (Animation::animations[animTarget].attack != neutral) {
2067 unsigned r = abs(Random() % 3);
2069 whichsound = lowwhooshsound;
2071 whichsound = midwhooshsound;
2073 whichsound = highwhooshsound;
2075 if (Animation::animations[animTarget].attack == neutral) {
2076 whichsound = movewhooshsound;
2078 } else if (targetFrame().label == 4) {
2079 whichsound = knifeswishsound;
2081 if (targetFrame().label == 8 && !Tutorial::active) {
2082 whichsound = landsound2;
2085 if (whichsound != -1) {
2086 emit_sound_at(whichsound, coords, 256.);
2089 if (whichsound == footstepsound || whichsound == footstepsound2 || whichsound == footstepsound3 || whichsound == footstepsound4) {
2090 if (animTarget == wolfrunninganim || animTarget == rabbitrunninganim) {
2091 addEnvSound(coords, 15);
2093 addEnvSound(coords, 6);
2098 if (targetFrame().label == 3) {
2100 emit_sound_at(whichsound, coords, 128.);
2106 if (!Tutorial::active || id == 0)
2107 if (speechdelay <= 0)
2108 if (animTarget != crouchstabanim && animTarget != swordgroundstabanim && animTarget != staffgroundsmashanim)
2109 if ((targetFrame().label && (targetFrame().label < 5 || targetFrame().label == 8))) {
2110 int whichsound = -1;
2111 if (targetFrame().label == 4 && aitype != playercontrolled) {
2112 if (Animation::animations[animTarget].attack != neutral) {
2113 unsigned r = abs(Random() % 4);
2114 if (creature == rabbittype) {
2115 if (r == 0) whichsound = rabbitattacksound;
2116 if (r == 1) whichsound = rabbitattack2sound;
2117 if (r == 2) whichsound = rabbitattack3sound;
2118 if (r == 3) whichsound = rabbitattack4sound;
2120 if (creature == wolftype) {
2121 if (r == 0) whichsound = barksound;
2122 if (r == 1) whichsound = bark2sound;
2123 if (r == 2) whichsound = bark3sound;
2124 if (r == 3) whichsound = barkgrowlsound;
2130 if (whichsound != -1) {
2131 emit_sound_at(whichsound, coords);
2137 if ((!wasLanding() && !wasLandhard()) && animCurrent != getIdle() && (isLanding() || isLandhard())) {
2138 FootLand(leftfoot, 1);
2139 FootLand(rightfoot, 1);
2143 currentoffset = targetoffset;
2144 frameTarget = frameCurrent;
2145 animCurrent = animTarget;
2148 if (animTarget == removeknifeanim && Animation::animations[animTarget].frames[frameCurrent].label == 5) {
2149 for (unsigned i = 0; i < weapons.size(); i++) {
2150 if (weapons[i].owner == -1)
2151 if (distsqflat(&coords, &weapons[i].position) < 4 && weaponactive == -1) {
2152 if (distsq(&coords, &weapons[i].position) >= 1) {
2153 if (weapons[i].getType() != staff) {
2154 emit_sound_at(knifedrawsound, coords, 128.);
2163 if (animTarget == crouchremoveknifeanim && Animation::animations[animTarget].frames[frameCurrent].label == 5) {
2164 for (unsigned i = 0; i < weapons.size(); i++) {
2165 bool willwork = true;
2166 if (weapons[i].owner != -1)
2167 if (Person::players[weapons[i].owner]->weaponstuck != -1)
2168 if (Person::players[weapons[i].owner]->weaponids[Person::players[weapons[i].owner]->weaponstuck] == int(i))
2169 if (Person::players[weapons[i].owner]->num_weapons > 1)
2171 if ((weapons[i].owner == -1) || (hasvictim && (weapons[i].owner == int(victim->id)) && victim->skeleton.free))
2172 if (willwork && distsqflat(&coords, &weapons[i].position) < 3 && weaponactive == -1) {
2173 if (distsq(&coords, &weapons[i].position) < 1 || hasvictim) {
2174 bool fleshstuck = false;
2175 if (weapons[i].owner != -1)
2176 if (victim->weaponstuck != -1) {
2177 if (victim->weaponids[victim->weaponstuck] == int(i)) {
2182 emit_sound_at(fleshstabremovesound, coords, 128.);
2184 if (weapons[i].getType() != staff) {
2185 emit_sound_at(knifedrawsound, coords, 128.);
2188 if (weapons[i].owner != -1) {
2189 victim = Person::players[weapons[i].owner];
2190 if (victim->num_weapons == 1)
2191 victim->num_weapons = 0;
2193 victim->num_weapons = 1;
2195 //victim->weaponactive=-1;
2196 victim->skeleton.longdead = 0;
2197 victim->skeleton.free = 1;
2198 victim->skeleton.broken = 0;
2200 for (unsigned j = 0; j < victim->skeleton.joints.size(); j++) {
2201 victim->skeleton.joints[j].velchange = 0;
2202 victim->skeleton.joints[j].locked = 0;
2208 Normalise(&relative);
2209 XYZ footvel, footpoint;
2211 footpoint = weapons[i].position;
2212 if (victim->weaponstuck != -1) {
2213 if (victim->weaponids[victim->weaponstuck] == int(i)) {
2215 Sprite::MakeSprite(cloudimpactsprite, footpoint, footvel, 1, 0, 0, .8, .3);
2216 weapons[i].bloody = 2;
2217 weapons[i].blooddrip = 5;
2218 victim->weaponstuck = -1;
2221 if (victim->num_weapons > 0) {
2222 if (victim->weaponstuck != 0 && victim->weaponstuck != -1)
2223 victim->weaponstuck = 0;
2224 if (victim->weaponids[0] == int(i))
2225 victim->weaponids[0] = victim->weaponids[victim->num_weapons];
2228 victim->jointVel(abdomen) += relative * 6;
2229 victim->jointVel(neck) += relative * 6;
2230 victim->jointVel(rightshoulder) += relative * 6;
2231 victim->jointVel(leftshoulder) += relative * 6;
2239 if (animCurrent == drawleftanim && Animation::animations[animTarget].frames[frameCurrent].label == 5) {
2240 if (weaponactive == -1)
2242 else if (weaponactive == 0) {
2244 if (num_weapons == 2) {
2246 buffer = weaponids[0];
2247 weaponids[0] = weaponids[1];
2248 weaponids[1] = buffer;
2251 if (weaponactive == -1) {
2252 emit_sound_at(knifesheathesound, coords, 128.);
2254 if (weaponactive != -1) {
2255 emit_sound_at(knifedrawsound, coords, 128.);
2260 if ((animCurrent == walljumprightkickanim && animTarget == walljumprightkickanim) || (animCurrent == walljumpleftkickanim && animTarget == walljumpleftkickanim)) {
2261 XYZ rotatetarget = DoRotation(skeleton.forward, 0, yaw, 0);
2262 Normalise(&rotatetarget);
2263 targetyaw = -asin(0 - rotatetarget.x);
2264 targetyaw *= 360 / 6.28;
2265 if (rotatetarget.z < 0)
2266 targetyaw = 180 - targetyaw;
2268 if (animTarget == walljumprightkickanim)
2270 if (animTarget == walljumpleftkickanim)
2276 if ((animTarget == rabbitrunninganim || animTarget == wolfrunninganim) && frameTarget == 3 && (jumpkeydown || attackkeydown || id != 0))
2279 if (distsq(&victim->coords, &/*Person::players[i]->*/coords) < 5 && victim->aitype == gethelptype && (attackkeydown) && !victim->skeleton.free && victim->isRun() && victim->runninghowlong >= 1)
2284 if ((animTarget == rabbitrunninganim || animTarget == wolfrunninganim) && id == 0) {
2285 animTarget = rabbittackleanim;
2287 emit_sound_at(jumpsound, coords);
2295 targetloc = velocity;
2296 Normalise(&targetloc);
2297 targetloc += coords;
2298 for (unsigned i = 0; i < Person::players.size(); i++) {
2300 if (distsq(&targetloc, &Person::players[i]->coords) < closestdist || closestdist == 0) {
2301 closestdist = distsq(&targetloc, &Person::players[i]->coords);
2305 if (closestid != -1)
2306 if (closestdist < 5 && !Person::players[closestid]->dead && Animation::animations[Person::players[closestid]->animTarget].height != lowheight && Person::players[closestid]->animTarget != backhandspringanim) {
2308 victim = Person::players[closestid];
2309 coords = victim->coords;
2310 animCurrent = rabbittacklinganim;
2311 animTarget = rabbittacklinganim;
2315 if (coords.z != victim->coords.z || coords.x != victim->coords.x) {
2316 rotatetarget = coords - victim->coords;
2317 Normalise(&rotatetarget);
2318 targetyaw = -asin(0 - rotatetarget.x);
2319 targetyaw *= 360 / 6.28;
2320 if (rotatetarget.z < 0)
2321 targetyaw = 180 - targetyaw;
2323 if (animTarget != rabbitrunninganim) {
2324 emit_sound_at(jumpsound, coords, 128.);
2330 float damagemult = 1 * power;
2331 if (creature == wolftype)
2332 damagemult = 2.5 * power;
2334 damagemult /= victim->damagetolerance / 200;
2336 if ((Animation::animations[animTarget].attack == normalattack || animTarget == walljumprightkickanim || animTarget == walljumpleftkickanim) && (!feint) && (victim->skeleton.free != 2 || animTarget == killanim || animTarget == dropkickanim || animTarget == crouchstabanim || animTarget == swordgroundstabanim || animTarget == staffgroundsmashanim)) {
2337 if (animTarget == spinkickanim && Animation::animations[animTarget].frames[frameCurrent].label == 5) {
2338 if (distsq(&coords, &victim->coords) < (scale * 5) * (scale * 5) * 3 && 3 && Animation::animations[victim->animTarget].height != lowheight) {
2342 if (Random() % 2 || creature == wolftype) {
2345 if (creature == wolftype)
2348 if (!Tutorial::active) {
2349 emit_sound_at(heavyimpactsound, victim->coords, 128.);
2351 if (creature == wolftype) {
2352 emit_sound_at(clawslicesound, victim->coords, 128.);
2354 victim->DoBloodBig(2 / victim->armorhead, 175);
2358 relative = victim->coords - coords;
2360 Normalise(&relative);
2361 relative = DoRotation(relative, 0, -90, 0);
2362 for (unsigned i = 0; i < victim->skeleton.joints.size(); i++) {
2363 victim->skeleton.joints[i].velocity += relative * damagemult * 40;
2365 victim->jointVel(head) += relative * damagemult * 200;
2367 victim->DoDamage(damagemult * 100 / victim->protectionhead);
2373 if (animTarget == wolfslapanim && Animation::animations[animTarget].frames[frameCurrent].label == 5) {
2374 if (distsq(&coords, &victim->coords) < (scale * 5) * (scale * 5) * 3 && 3 && Animation::animations[victim->animTarget].height != lowheight) {
2378 if (Random() % 2 || creature == wolftype) {
2380 if (creature == wolftype)
2383 emit_sound_at(whooshhitsound, victim->coords);
2384 if (creature == wolftype) {
2385 emit_sound_at(clawslicesound, victim->coords, 128.);
2387 victim->DoBloodBig(2, 175);
2391 relative = victim->coords - coords;
2393 Normalise(&relative);
2395 Normalise(&relative);
2396 relative = DoRotation(relative, 0, 90, 0);
2397 for (unsigned i = 0; i < victim->skeleton.joints.size(); i++) {
2398 victim->skeleton.joints[i].velocity += relative * damagemult * 20;
2400 victim->jointVel(head) += relative * damagemult * 100;
2402 victim->DoDamage(damagemult * 50 / victim->protectionhead);
2406 if (animTarget == walljumprightkickanim && Animation::animations[animTarget].frames[frameCurrent].label == 5) {
2407 if (distsq(&coords, &victim->coords) < (scale * 5) * (scale * 5) * 3 && Animation::animations[victim->animTarget].height != lowheight) {
2413 if (!Tutorial::active) {
2414 emit_sound_at(heavyimpactsound, victim->coords, 160.);
2416 if (creature == wolftype) {
2417 emit_sound_at(clawslicesound, victim->coords, 128.);
2419 victim->DoBloodBig(2 / victim->armorhead, 175);
2425 Normalise(&relative);
2426 relative = DoRotation(relative, 0, -90, 0);
2427 for (unsigned i = 0; i < victim->skeleton.joints.size(); i++) {
2428 victim->skeleton.joints[i].velocity += relative * damagemult * 40;
2430 victim->jointVel(head) += relative * damagemult * 200;
2432 victim->DoDamage(damagemult * 150 / victim->protectionhead);
2434 if (victim->damage > victim->damagetolerance)
2435 award_bonus(id, style);
2441 if (animTarget == walljumpleftkickanim && Animation::animations[animTarget].frames[frameCurrent].label == 5) {
2442 if (distsq(&coords, &victim->coords) < (scale * 5) * (scale * 5) * 3 && Animation::animations[victim->animTarget].height != lowheight) {
2448 if (!Tutorial::active) {
2449 emit_sound_at(heavyimpactsound, victim->coords, 160.);
2451 if (creature == wolftype) {
2452 emit_sound_at(clawslicesound, victim->coords, 128.);
2454 victim->DoBloodBig(2 / victim->armorhead, 175);
2460 Normalise(&relative);
2461 relative = DoRotation(relative, 0, 90, 0);
2462 for (unsigned i = 0; i < victim->skeleton.joints.size(); i++) {
2463 victim->skeleton.joints[i].velocity += relative * damagemult * 40;
2465 victim->jointVel(head) += relative * damagemult * 200;
2467 victim->DoDamage(damagemult * 150 / victim->protectionhead);
2469 if (victim->damage > victim->damagetolerance)
2470 award_bonus(id, style);
2476 if (animTarget == blockhighleftstrikeanim && Animation::animations[animTarget].frames[frameCurrent].label == 5) {
2477 if (distsq(&coords, &victim->coords) < (scale * 5) * (scale * 5) * 3 && Animation::animations[victim->animTarget].height != lowheight) {
2485 emit_sound_at(whooshhitsound, victim->coords);
2488 relative = victim->coords - coords;
2490 Normalise(&relative);
2491 for (unsigned i = 0; i < victim->skeleton.joints.size(); i++) {
2492 victim->skeleton.joints[i].velocity += relative * damagemult * 30;
2494 victim->jointVel(head) += relative * damagemult * 100;
2496 victim->DoDamage(damagemult * 50 / victim->protectionhead);
2500 if (animTarget == killanim && Animation::animations[animTarget].frames[frameCurrent].label == 8) {
2501 if (distsq(&coords, &victim->coords) < (scale * 5) * (scale * 5) * 3 && victim->dead) {
2505 emit_sound_at(whooshhitsound, victim->coords, 128.);
2507 victim->skeleton.longdead = 0;
2508 victim->skeleton.free = 1;
2509 victim->skeleton.broken = 0;
2510 victim->skeleton.spinny = 1;
2512 for (unsigned i = 0; i < victim->skeleton.joints.size(); i++) {
2513 victim->skeleton.joints[i].velchange = 0;
2514 victim->skeleton.joints[i].delay = 0;
2515 victim->skeleton.joints[i].locked = 0;
2516 //victim->skeleton.joints[i].velocity=0;
2522 Normalise(&relative);
2523 for (unsigned i = 0; i < victim->skeleton.joints.size(); i++) {
2524 victim->skeleton.joints[i].velocity.y = relative.y * 10;
2525 victim->skeleton.joints[i].position.y += relative.y * .3;
2526 victim->skeleton.joints[i].oldposition.y += relative.y * .3;
2527 victim->skeleton.joints[i].realoldposition.y += relative.y * .3;
2529 victim->Puff(abdomen);
2530 victim->jointVel(abdomen).y = relative.y * 400;
2534 if (animTarget == killanim && Animation::animations[animTarget].frames[frameCurrent].label == 5) {
2535 if (distsq(&coords, &victim->coords) < (scale * 5) * (scale * 5) * 9 && victim->dead) {
2539 if (!Tutorial::active) {
2540 emit_sound_at(heavyimpactsound, coords, 128.);
2543 relative = victim->coords - coords;
2545 Normalise(&relative);
2546 for (unsigned i = 0; i < victim->skeleton.joints.size(); i++) {
2547 victim->skeleton.joints[i].velocity += relative * damagemult * 90;
2549 victim->Puff(abdomen);
2550 if (victim->dead != 2 && victim->permanentdamage > victim->damagetolerance - 250 && autoslomo) {
2554 victim->DoDamage(damagemult * 500 / victim->protectionhigh);
2555 victim->jointVel(abdomen) += relative * damagemult * 300;
2559 if (animTarget == dropkickanim && Animation::animations[animTarget].frames[frameCurrent].label == 7) {
2560 if (distsq(&coords, &victim->coords) < (scale * 5) * (scale * 5) * 9 && victim->skeleton.free) {
2564 if (!Tutorial::active) {
2565 emit_sound_at(thudsound, coords);
2568 victim->skeleton.longdead = 0;
2569 victim->skeleton.free = 1;
2570 victim->skeleton.broken = 0;
2571 victim->skeleton.spinny = 1;
2573 for (unsigned i = 0; i < victim->skeleton.joints.size(); i++) {
2574 victim->skeleton.joints[i].velchange = 0;
2575 //victim->skeleton.joints[i].delay=0;
2576 victim->skeleton.joints[i].locked = 0;
2579 relative = victim->coords - coords;
2580 Normalise(&relative);
2582 Normalise(&relative);
2583 for (unsigned i = 0; i < victim->skeleton.joints.size(); i++) {
2584 victim->skeleton.joints[i].velocity += relative * damagemult * 20;
2589 victim->Puff(abdomen);
2590 victim->DoDamage(damagemult * 20 / victim->protectionhigh);
2591 victim->jointVel(abdomen) += relative * damagemult * 200;
2600 if ((animTarget == crouchstabanim || animTarget == swordgroundstabanim) && Animation::animations[animTarget].frames[frameCurrent].label == 5) {
2603 if (!victim->skeleton.free)
2607 terrain.MakeDecal(blooddecalfast, (weapons[weaponids[weaponactive]].tippoint * .8 + weapons[weaponids[weaponactive]].position * .2), .08, .6, Random() % 360);
2608 emit_sound_at(knifesheathesound, coords, 128.);
2611 if (victim && hasvictim) {
2612 if (distsq(&coords, &victim->coords) < (scale * 5) * (scale * 5) * 3) {
2614 XYZ where, startpoint, endpoint, movepoint, colpoint;
2615 float rotationpoint;
2617 if (weapons[weaponids[weaponactive]].getType() == knife) {
2618 where = (weapons[weaponids[weaponactive]].tippoint * .6 + weapons[weaponids[weaponactive]].position * .4);
2619 where -= victim->coords;
2620 if (!victim->skeleton.free)
2621 where = DoRotation(where, 0, -victim->yaw, 0);
2624 startpoint.y += 100;
2628 if (weapons[weaponids[weaponactive]].getType() == sword) {
2629 where = weapons[weaponids[weaponactive]].position;
2630 where -= victim->coords;
2631 if (!victim->skeleton.free)
2632 where = DoRotation(where, 0, -victim->yaw, 0);
2634 where = weapons[weaponids[weaponactive]].tippoint;
2635 where -= victim->coords;
2636 if (!victim->skeleton.free)
2637 where = DoRotation(where, 0, -victim->yaw, 0);
2640 if (weapons[weaponids[weaponactive]].getType() == staff) {
2641 where = weapons[weaponids[weaponactive]].position;
2642 where -= victim->coords;
2643 if (!victim->skeleton.free)
2644 where = DoRotation(where, 0, -victim->yaw, 0);
2646 where = weapons[weaponids[weaponactive]].tippoint;
2647 where -= victim->coords;
2648 if (!victim->skeleton.free)
2649 where = DoRotation(where, 0, -victim->yaw, 0);
2654 whichtri = victim->skeleton.drawmodel.LineCheck(&startpoint, &endpoint, &colpoint, &movepoint, &rotationpoint);
2656 if (whichtri != -1) {
2657 if (victim->dead != 2) {
2658 victim->DoDamage(abs((victim->damagetolerance - victim->permanentdamage) * 2));
2660 award_bonus(id, FinishedBonus);
2663 weapons[weaponids[weaponactive]].bloody = 2;
2665 victim->skeleton.longdead = 0;
2666 victim->skeleton.free = 1;
2667 victim->skeleton.broken = 0;
2669 for (unsigned i = 0; i < victim->skeleton.joints.size(); i++) {
2670 victim->skeleton.joints[i].velchange = 0;
2671 victim->skeleton.joints[i].locked = 0;
2672 //victim->skeleton.joints[i].velocity=0;
2674 emit_sound_at(fleshstabsound, coords, 128);
2677 if (whichtri != -1 || weapons[weaponids[weaponactive]].bloody) {
2678 weapons[weaponids[weaponactive]].blooddrip += 5;
2679 weapons[weaponids[weaponactive]].blooddripdelay = 0;
2681 if (whichtri == -1) {
2683 emit_sound_at(knifesheathesound, coords, 128.);
2689 if ((animTarget == crouchstabanim || animTarget == swordgroundstabanim) && Animation::animations[animTarget].frames[frameCurrent].label == 6) {
2691 emit_sound_at(knifedrawsound, coords, 128);
2694 if (victim && hasvictim) {
2695 XYZ footvel, footpoint;
2697 emit_sound_at(fleshstabremovesound, coords, 128.);
2700 footpoint = (weapons[weaponids[weaponactive]].tippoint * .8 + weapons[weaponids[weaponactive]].position * .2);
2702 if (weapons[weaponids[weaponactive]].getType() == sword) {
2703 XYZ where, startpoint, endpoint, movepoint;
2704 float rotationpoint;
2707 where = weapons[weaponids[weaponactive]].position;
2708 where -= victim->coords;
2709 if (!victim->skeleton.free)
2710 where = DoRotation(where, 0, -victim->yaw, 0);
2712 where = weapons[weaponids[weaponactive]].tippoint;
2713 where -= victim->coords;
2714 if (!victim->skeleton.free)
2715 where = DoRotation(where, 0, -victim->yaw, 0);
2720 whichtri = victim->skeleton.drawmodel.LineCheck(&startpoint, &endpoint, &footpoint, &movepoint, &rotationpoint);
2721 footpoint += victim->coords;
2723 if (whichtri == -1) {
2724 footpoint = (weapons[weaponids[weaponactive]].tippoint * .8 + weapons[weaponids[weaponactive]].position * .2);
2727 if (weapons[weaponids[weaponactive]].getType() == staff) {
2728 XYZ where, startpoint, endpoint, movepoint;
2729 float rotationpoint;
2732 where = weapons[weaponids[weaponactive]].position;
2733 where -= victim->coords;
2734 if (!victim->skeleton.free)
2735 where = DoRotation(where, 0, -victim->yaw, 0);
2737 where = weapons[weaponids[weaponactive]].tippoint;
2738 where -= victim->coords;
2739 if (!victim->skeleton.free)
2740 where = DoRotation(where, 0, -victim->yaw, 0);
2745 whichtri = victim->skeleton.drawmodel.LineCheck(&startpoint, &endpoint, &footpoint, &movepoint, &rotationpoint);
2746 footpoint += victim->coords;
2748 if (whichtri == -1) {
2749 footpoint = (weapons[weaponids[weaponactive]].tippoint * .8 + weapons[weaponids[weaponactive]].position * .2);
2752 hasvictim = victim->DoBloodBigWhere(2, 220, footpoint);
2754 if (distsq(&coords, &victim->coords) < (scale * 5) * (scale * 5) * 3) {
2755 victim->skeleton.longdead = 0;
2756 victim->skeleton.free = 1;
2757 victim->skeleton.broken = 0;
2759 for (unsigned i = 0; i < victim->skeleton.joints.size(); i++) {
2760 victim->skeleton.joints[i].velchange = 0;
2761 victim->skeleton.joints[i].locked = 0;
2762 //victim->skeleton.joints[i].velocity=0;
2768 Normalise(&relative);
2769 //victim->Puff(abdomen);
2771 Sprite::MakeSprite(cloudimpactsprite, footpoint, footvel, 1, 0, 0, .8, .3);
2773 if (victim->bloodloss < victim->damagetolerance) {
2774 victim->bloodloss += 1000;
2778 victim->jointVel(abdomen) += relative * damagemult * 20;
2782 if (!hasvictim && onterrain) {
2783 weapons[weaponids[weaponactive]].bloody = 0;
2784 weapons[weaponids[weaponactive]].blooddrip = 0;
2788 if (animTarget == upunchanim && Animation::animations[animTarget].frames[frameCurrent].label == 5) {
2789 if (distsq(&coords, &victim->coords) < (scale * 5) * (scale * 5) * 3) {
2797 if (!Tutorial::active) {
2798 emit_sound_at(heavyimpactsound, victim->coords, 128);
2803 relative = victim->coords - coords;
2805 Normalise(&relative);
2806 for (unsigned i = 0; i < victim->skeleton.joints.size(); i++) {
2807 victim->skeleton.joints[i].velocity = relative * 30;
2809 victim->jointVel(head) += relative * damagemult * 150;
2811 victim->frameTarget = 0;
2812 victim->animTarget = staggerbackhardanim;
2813 victim->targetyaw = targetyaw + 180;
2815 victim->stunned = 1;
2818 victim->Puff(abdomen);
2819 victim->DoDamage(damagemult * 60 / victim->protectionhigh);
2826 if (animTarget == winduppunchanim && Animation::animations[animTarget].frames[frameCurrent].label == 5) {
2827 if (distsq(&coords, &victim->coords) < (scale * 5) * (scale * 5) * 2) {
2831 if (victim->damage <= victim->damagetolerance - 60 && normaldotproduct(victim->facing, victim->coords - coords) < (scale * 5) * (scale * 5) * 0 && Animation::animations[victim->animTarget].height != lowheight) {
2832 if (!Tutorial::active) {
2833 emit_sound_at(thudsound, victim->coords);
2835 } else if (victim->damage <= victim->damagetolerance - 60 && normaldotproduct(victim->facing, victim->coords - coords) < (scale * 5) * (scale * 5) * 0 && Animation::animations[victim->animTarget].height == lowheight) {
2836 if (!Tutorial::active) {
2837 emit_sound_at(whooshhitsound, victim->coords);
2840 if (!Tutorial::active) {
2841 emit_sound_at(heavyimpactsound, victim->coords);
2845 if (victim->damage > victim->damagetolerance - 60 || normaldotproduct(victim->facing, victim->coords - coords) > 0 || Animation::animations[victim->animTarget].height == lowheight)
2848 relative = victim->coords - coords;
2850 Normalise(&relative);
2852 Normalise(&relative);
2853 for (unsigned i = 0; i < victim->skeleton.joints.size(); i++) {
2854 victim->skeleton.joints[i].velocity = relative * 5;
2856 victim->jointVel(abdomen) += relative * damagemult * 400;
2858 victim->frameTarget = 0;
2859 victim->animTarget = staggerbackhardanim;
2860 victim->targetyaw = targetyaw + 180;
2862 victim->stunned = 1;
2864 victim->Puff(abdomen);
2865 victim->DoDamage(damagemult * 60 / victim->protectionhigh);
2871 if (animTarget == blockhighleftanim && Animation::animations[animTarget].frames[frameCurrent].label == 5) {
2872 if (distsq(&coords, &victim->coords) < (scale * 5) * (scale * 5) * 4) {
2873 if (victim->id == 0)
2875 emit_sound_at(landsound2, victim->coords);
2881 if (animTarget == swordslashparryanim && Animation::animations[animTarget].frames[frameCurrent].label == 5) {
2882 if (distsq(&coords, &victim->coords) < (scale * 5) * (scale * 5) * 4) {
2883 if (victim->id == 0)
2886 if (weaponactive != -1) {
2887 if (weapons[victim->weaponids[0]].getType() == staff || weapons[weaponids[0]].getType() == staff) {
2888 if (weapons[victim->weaponids[0]].getType() == staff)
2889 weapons[victim->weaponids[0]].damage += .2 + float(abs(Random() % 100) - 50) / 250;
2890 if (weapons[weaponids[0]].getType() == staff)
2891 weapons[weaponids[0]].damage += .2 + float(abs(Random() % 100) - 50) / 250;
2893 emit_sound_at(swordstaffsound, victim->coords);
2895 emit_sound_at(metalhitsound, victim->coords);
2903 if (animTarget == knifethrowanim && Animation::animations[animTarget].frames[frameCurrent].label == 5) {
2904 if (weaponactive != -1) {
2907 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);
2909 weapons[weaponids[0]].thrown(aim * 50);
2912 weaponids[0] = weaponids[num_weapons];
2918 if (animTarget == knifeslashstartanim && Animation::animations[animTarget].frames[frameCurrent].label == 5) {
2920 if (distsq(&coords, &victim->coords) < (scale * 5) * (scale * 5) * 4.5 &&/*Animation::animations[victim->animTarget].height!=lowheight&&*/victim->animTarget != dodgebackanim && victim->animTarget != rollanim) {
2922 if (!Tutorial::active)
2923 victim->DoBloodBig(1.5 / victim->armorhigh, 225);
2925 award_bonus(id, Slicebonus);
2926 if (!Tutorial::active) {
2927 emit_sound_at(knifeslicesound, victim->coords);
2929 //victim->jointVel(abdomen)+=relative*damagemult*200;
2930 if (Animation::animations[victim->animTarget].attack && (victim->aitype != playercontrolled || victim->animTarget == knifeslashstartanim) && (victim->creature == rabbittype || victim->deathbleeding <= 0)) {
2931 if (victim->id != 0 || difficulty == 2) {
2932 victim->frameTarget = 0;
2933 victim->animTarget = staggerbackhardanim;
2934 victim->targetyaw = targetyaw + 180;
2938 victim->lowreversaldelay = 0;
2939 victim->highreversaldelay = 0;
2940 if (aitype != playercontrolled)
2941 weaponmissdelay = .6;
2943 if (!Tutorial::active)
2944 if (bloodtoggle && !weapons[weaponids[weaponactive]].bloody)
2945 weapons[weaponids[weaponactive]].bloody = 1;
2946 if (!Tutorial::active)
2947 weapons[weaponids[weaponactive]].blooddrip += 3;
2949 XYZ footvel, footpoint;
2951 if (skeleton.free) {
2952 footpoint = (victim->jointPos(abdomen) + victim->jointPos(neck)) / 2 * victim->scale + victim->coords;
2954 footpoint = DoRotation((victim->jointPos(abdomen) + victim->jointPos(neck)) / 2, 0, victim->yaw, 0) * victim->scale + victim->coords;
2956 if (!Tutorial::active) {
2958 Sprite::MakeSprite(cloudimpactsprite, footpoint, footvel, 1, 0, 0, .6, .3);
2959 footvel = DoRotation(facing, 0, 90, 0) * .8;
2961 Sprite::MakeSprite(bloodsprite, footpoint, DoRotation(footvel * 7, (float)(Random() % 20), (float)(Random() % 20), 0), 1, 1, 1, .05, .9);
2962 Sprite::MakeSprite(bloodsprite, footpoint, DoRotation(footvel * 3, (float)(Random() % 20), (float)(Random() % 20), 0), 1, 1, 1, .05, .9);
2963 Sprite::MakeSprite(bloodflamesprite, footpoint, footvel * 5, 1, 1, 1, .2, 1);
2964 Sprite::MakeSprite(bloodflamesprite, footpoint, footvel * 2, 1, 1, 1, .2, 1);
2966 if (Tutorial::active) {
2967 Sprite::MakeSprite(cloudimpactsprite, footpoint, footvel, 1, 1, 1, .6, .3);
2969 victim->DoDamage(damagemult * 0);
2972 if (animTarget == swordslashanim && Animation::animations[animTarget].frames[frameCurrent].label == 5 && victim->animTarget != rollanim) {
2973 if (distsq(&coords, &victim->coords) < (scale * 5) * (scale * 5) * 6.5 && victim->animTarget != dodgebackanim) {
2974 if (victim->weaponactive == -1 || normaldotproduct(victim->facing, victim->coords - coords) > 0 || (Random() % 2 == 0)) {
2975 award_bonus(id, Slashbonus);
2977 if (!Tutorial::active) {
2978 if (normaldotproduct(victim->facing, victim->coords - coords) < 0)
2979 victim->DoBloodBig(2 / victim->armorhigh, 190);
2981 victim->DoBloodBig(2 / victim->armorhigh, 185);
2982 victim->deathbleeding = 1;
2983 emit_sound_at(swordslicesound, victim->coords);
2985 //victim->jointVel(abdomen)+=relative*damagemult*200;
2986 if (!Tutorial::active) {
2987 victim->frameTarget = 0;
2988 victim->animTarget = staggerbackhardanim;
2989 victim->targetyaw = targetyaw + 180;
2993 if (!Tutorial::active) {
2994 if (bloodtoggle && !weapons[weaponids[weaponactive]].bloody)
2995 weapons[weaponids[weaponactive]].bloody = 1;
2996 weapons[weaponids[weaponactive]].blooddrip += 3;
2998 float bloodlossamount;
2999 bloodlossamount = 200 + abs((float)(Random() % 40)) - 20;
3000 victim->bloodloss += bloodlossamount / victim->armorhigh;
3001 //victim->bloodloss+=100*(6.5-distsq(&coords,&victim->coords));
3002 victim->DoDamage(damagemult * 0);
3004 XYZ footvel, footpoint;
3006 if (skeleton.free) {
3007 footpoint = (victim->jointPos(abdomen) + victim->jointPos(neck)) / 2 * victim->scale + victim->coords;
3009 footpoint = DoRotation((victim->jointPos(abdomen) + victim->jointPos(neck)) / 2, 0, victim->yaw, 0) * victim->scale + victim->coords;
3012 Sprite::MakeSprite(cloudimpactsprite, footpoint, footvel, 1, 0, 0, .9, .3);
3013 footvel = DoRotation(facing, 0, 90, 0) * .8;
3015 Sprite::MakeSprite(bloodsprite, footpoint, DoRotation(footvel * 7, (float)(Random() % 20), (float)(Random() % 20), 0), 1, 1, 1, .05, .9);
3016 Sprite::MakeSprite(bloodsprite, footpoint, DoRotation(footvel * 3, (float)(Random() % 20), (float)(Random() % 20), 0), 1, 1, 1, .05, .9);
3017 Sprite::MakeSprite(bloodflamesprite, footpoint, footvel * 5, 1, 1, 1, .3, 1);
3018 Sprite::MakeSprite(bloodflamesprite, footpoint, footvel * 2, 1, 1, 1, .3, 1);
3021 if (victim->weaponactive != -1) {
3022 if (weapons[victim->weaponids[0]].getType() == staff || weapons[weaponids[0]].getType() == staff) {
3023 if (weapons[victim->weaponids[0]].getType() == staff)
3024 weapons[victim->weaponids[0]].damage += .2 + float(abs(Random() % 100) - 50) / 250;
3025 if (weapons[weaponids[0]].getType() == staff)
3026 weapons[weaponids[0]].damage += .2 + float(abs(Random() % 100) - 50) / 250;
3028 emit_sound_at(swordstaffsound, victim->coords);
3030 emit_sound_at(metalhitsound, victim->coords);
3036 victim->Puff(righthand);
3038 victim->frameTarget = 0;
3039 victim->animTarget = staggerbackhighanim;
3040 victim->targetyaw = targetyaw + 180;
3042 aim = DoRotation(facing, 0, 90, 0) * 21;
3044 weapons[victim->weaponids[0]].drop(aim * -.2, aim);
3045 victim->num_weapons--;
3046 if (victim->num_weapons) {
3047 victim->weaponids[0] = victim->weaponids[num_weapons];
3048 if (victim->weaponstuck == victim->num_weapons)
3049 victim->weaponstuck = 0;
3051 victim->weaponactive = -1;
3052 for (unsigned i = 0; i < Person::players.size(); i++) {
3053 Person::players[i]->wentforweapon = 0;
3060 if (animTarget == staffhitanim && Animation::animations[animTarget].frames[frameCurrent].label == 5 && victim->animTarget != rollanim) {
3061 if (distsq(&coords, &victim->coords) < (scale * 5) * (scale * 5) * 6.5 && victim->animTarget != dodgebackanim && victim->animTarget != sweepanim) {
3062 if (!Tutorial::active) {
3063 weapons[weaponids[0]].damage += .4 + float(abs(Random() % 100) - 50) / 250;
3067 if (Random() % 2 || creature == wolftype) {
3070 emit_sound_at(staffheadsound, victim->coords);
3074 relative = victim->coords - coords;
3076 Normalise(&relative);
3077 relative = DoRotation(relative, 0, 90, 0);
3079 Normalise(&relative);
3080 for (unsigned i = 0; i < victim->skeleton.joints.size(); i++) {
3081 victim->skeleton.joints[i].velocity += relative * damagemult * 60;
3083 victim->jointVel(head) += relative * damagemult * 230;
3084 victim->jointVel(neck) += relative * damagemult * 230;
3086 if (!Tutorial::active) {
3087 victim->DoDamage(damagemult * 120 / victim->protectionhigh);
3089 award_bonus(id, solidhit, 30);
3094 if (animTarget == staffspinhitanim && Animation::animations[animTarget].frames[frameCurrent].label == 5 && victim->animTarget != rollanim) {
3095 if (distsq(&coords, &victim->coords) < (scale * 5) * (scale * 5) * 6.5 && victim->animTarget != dodgebackanim && victim->animTarget != sweepanim) {
3096 if (!Tutorial::active) {
3097 weapons[weaponids[0]].damage += .6 + float(abs(Random() % 100) - 50) / 250;
3101 if (Random() % 2 || creature == wolftype) {
3104 emit_sound_at(staffheadsound, victim->coords);
3108 relative = victim->coords - coords;
3110 Normalise(&relative);
3111 relative = DoRotation(relative, 0, -90, 0);
3112 for (unsigned i = 0; i < victim->skeleton.joints.size(); i++) {
3113 victim->skeleton.joints[i].velocity += relative * damagemult * 40;
3115 victim->jointVel(head) += relative * damagemult * 220;
3116 victim->jointVel(neck) += relative * damagemult * 220;
3118 if (!Tutorial::active) {
3119 victim->DoDamage(damagemult * 350 / victim->protectionhead);
3121 award_bonus(id, solidhit, 60);
3126 if (animTarget == staffgroundsmashanim && Animation::animations[animTarget].frames[frameCurrent].label == 5) {
3127 if (distsq(&coords, &victim->coords) < (scale * 5) * (scale * 5) * 6.5) {
3129 if (!Tutorial::active) {
3131 weapons[weaponids[0]].damage += .4 + float(abs(Random() % 100) - 50) / 500;
3134 if (Random() % 2 || creature == wolftype) {
3137 emit_sound_at(staffbodysound, victim->coords);
3139 victim->skeleton.longdead = 0;
3140 victim->skeleton.free = 1;
3141 victim->skeleton.broken = 0;
3143 for (unsigned i = 0; i < victim->skeleton.joints.size(); i++) {
3144 victim->skeleton.joints[i].velchange = 0;
3145 victim->skeleton.joints[i].locked = 0;
3146 //victim->skeleton.joints[i].velocity=0;
3153 Normalise(&relative);
3154 if (!victim->dead) {
3155 for (unsigned i = 0; i < victim->skeleton.joints.size(); i++) {
3156 victim->skeleton.joints[i].velocity = relative * damagemult * 40;
3158 victim->jointVel(abdomen) += relative * damagemult * 40;
3161 for (unsigned i = 0; i < victim->skeleton.joints.size(); i++) {
3162 victim->skeleton.joints[i].velocity = relative * damagemult * abs(Random() % 20);
3165 victim->Puff(abdomen);
3166 if (!Tutorial::active) {
3167 victim->DoDamage(damagemult * 100 / victim->protectionhigh);
3169 if (!victim->dead) {
3170 award_bonus(id, solidhit, 40);
3176 if (animTarget == lowkickanim && Animation::animations[animTarget].frames[frameCurrent].label == 5) {
3177 if (distsq(&coords, &victim->coords) < (scale * 5) * (scale * 5) * 3 && Animation::animations[victim->animTarget].height != highheight) {
3182 relative = victim->coords - coords;
3184 Normalise(&relative);
3188 if (Animation::animations[victim->animTarget].height == lowheight) {
3194 for (unsigned i = 0; i < victim->skeleton.joints.size(); i++) {
3195 victim->skeleton.joints[i].velocity += relative * damagemult * 40;
3197 victim->jointVel(head) += relative * damagemult * 200;
3198 if (!Tutorial::active) {
3199 emit_sound_at(heavyimpactsound, victim->coords, 128.);
3202 victim->DoDamage(damagemult * 100 / victim->protectionhead);
3203 if (victim->howactive == typesleeping)
3204 victim->DoDamage(damagemult * 150 / victim->protectionhead);
3205 if (creature == wolftype) {
3206 emit_sound_at(clawslicesound, victim->coords, 128.);
3208 victim->DoBloodBig(2 / victim->armorhead, 175);
3211 if (victim->damage >= victim->damagetolerance)
3213 for (unsigned i = 0; i < victim->skeleton.joints.size(); i++) {
3214 victim->skeleton.joints[i].velocity += relative * damagemult * 10;
3216 victim->jointVel(abdomen) += relative * damagemult * 200;
3217 victim->frameTarget = 0;
3218 victim->animTarget = staggerbackhighanim;
3219 victim->targetyaw = targetyaw + 180;
3221 if (!Tutorial::active) {
3222 emit_sound_at(landsound2, victim->coords, 128.);
3224 victim->Puff(abdomen);
3225 victim->DoDamage(damagemult * 30 / victim->protectionhigh);
3226 if (creature == wolftype) {
3227 emit_sound_at(clawslicesound, victim->coords, 128.);
3229 victim->DoBloodBig(2 / victim->armorhigh, 170);
3236 if (animTarget == sweepanim && Animation::animations[animTarget].frames[frameCurrent].label == 5) {
3237 if ((victim->animTarget != jumpupanim) &&
3238 (distsq(&coords, &victim->coords) < (scale * 5) * (scale * 5) * 3) &&
3239 (victim != this->shared_from_this())) {
3243 if (!Tutorial::active) {
3244 emit_sound_at(landsound2, victim->coords, 128.);
3247 relative = victim->coords - coords;
3249 Normalise(&relative);
3251 if (Animation::animations[victim->animTarget].height == middleheight || Animation::animations[victim->animCurrent].height == middleheight || victim->damage >= victim->damagetolerance - 40) {
3254 for (unsigned i = 0; i < victim->skeleton.joints.size(); i++) {
3255 victim->skeleton.joints[i].velocity += relative * damagemult * 15;
3257 relative = DoRotation(relative, 0, -90, 0);
3259 for (unsigned i = 0; i < victim->skeleton.joints.size(); i++) {
3260 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)
3261 victim->skeleton.joints[i].velocity = relative * 80;
3263 victim->Puff(rightankle);
3264 victim->Puff(leftankle);
3265 victim->DoDamage(damagemult * 40 / victim->protectionlow);
3267 if (victim->damage >= victim->damagetolerance)
3269 for (unsigned i = 0; i < victim->skeleton.joints.size(); i++) {
3270 victim->skeleton.joints[i].velocity += relative * damagemult * 10;
3272 relative = DoRotation(relative, 0, -90, 0);
3273 for (unsigned i = 0; i < victim->skeleton.joints.size(); i++) {
3274 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)
3275 victim->skeleton.joints[i].velocity += relative * damagemult * 80;
3277 victim->jointVel(abdomen) += relative * damagemult * 200;
3278 victim->frameTarget = 0;
3279 victim->animTarget = staggerbackhighanim;
3280 victim->targetyaw = targetyaw + 180;
3282 if (!Tutorial::active) {
3283 emit_sound_at(landsound2, victim->coords, 128.);
3285 victim->Puff(abdomen);
3286 victim->DoDamage(damagemult * 30 / victim->protectionlow);
3294 if (Animation::animations[animTarget].attack == reversal && (!victim->feint || (victim->lastattack == victim->lastattack2 && victim->lastattack2 == victim->lastattack3 && Random() % 2) || animTarget == knifefollowanim)) {
3295 if (animTarget == spinkickreversalanim && Animation::animations[animTarget].frames[frameCurrent].label == 7) {
3303 if (!Tutorial::active) {
3304 emit_sound_at(heavyimpactsound, victim->coords, 128.);
3306 if (creature == wolftype) {
3307 emit_sound_at(clawslicesound, victim->coords, 128);
3309 victim->DoBloodBig(2 / victim->armorhigh, 170);
3313 relative = victim->coords - oldcoords;
3315 Normalise(&relative);
3316 for (unsigned i = 0; i < victim->skeleton.joints.size(); i++) {
3317 victim->skeleton.joints[i].velocity += relative * damagemult * 40;
3319 victim->jointVel(abdomen) += relative * damagemult * 200;
3320 victim->Puff(abdomen);
3321 victim->DoDamage(damagemult * 150 / victim->protectionhigh);
3323 award_bonus(id, Reversal);
3326 if ((animTarget == swordslashreversalanim || animTarget == knifeslashreversalanim || animTarget == staffhitreversalanim || animTarget == staffspinhitreversalanim) && Animation::animations[animTarget].frames[frameCurrent].label == 5) {
3327 if (victim->weaponactive != -1 && victim->num_weapons > 0) {
3328 if (weapons[victim->weaponids[victim->weaponactive]].owner == int(victim->id)) {
3329 takeWeapon(victim->weaponids[victim->weaponactive]);
3330 victim->num_weapons--;
3331 if (victim->num_weapons > 0) {
3332 victim->weaponids[victim->weaponactive] = victim->weaponids[victim->num_weapons];
3334 victim->weaponactive = -1;
3339 if (animTarget == staffhitreversalanim && Animation::animations[animTarget].frames[frameCurrent].label == 5) {
3347 emit_sound_at(whooshhitsound, victim->coords, 128.);
3350 relative = victim->coords - oldcoords;
3352 Normalise(&relative);
3353 for (unsigned i = 0; i < victim->skeleton.joints.size(); i++) {
3354 victim->skeleton.joints[i].velocity += relative * damagemult * 30;
3356 victim->jointVel(abdomen) += relative * damagemult * 200;
3358 victim->DoDamage(damagemult * 70 / victim->protectionhigh);
3361 if (animTarget == staffspinhitreversalanim && Animation::animations[animTarget].frames[frameCurrent].label == 7) {
3370 award_bonus(id, staffreversebonus);
3372 if (!Tutorial::active) {
3373 emit_sound_at(heavyimpactsound, victim->coords, 128.);
3376 award_bonus(id, staffreversebonus); // Huh, again?
3379 relative = victim->coords - oldcoords;
3381 Normalise(&relative);
3382 for (unsigned i = 0; i < victim->skeleton.joints.size(); i++) {
3383 victim->skeleton.joints[i].velocity += relative * damagemult * 30;
3385 victim->jointVel(abdomen) += relative * damagemult * 200;
3387 victim->DoDamage(damagemult * 70 / victim->protectionhigh);
3390 if (animTarget == upunchreversalanim && Animation::animations[animTarget].frames[frameCurrent].label == 7) {
3396 Normalise(&relative);
3398 for (unsigned i = 0; i < victim->skeleton.joints.size(); i++) {
3399 victim->skeleton.joints[i].velocity += relative * damagemult * 70;
3401 victim->jointVel(lefthand) *= .1;
3402 victim->jointVel(leftwrist) *= .2;
3403 victim->jointVel(leftelbow) *= .5;
3404 victim->jointVel(leftshoulder) *= .7;
3405 victim->jointVel(righthand) *= .1;
3406 victim->jointVel(rightwrist) *= .2;
3407 victim->jointVel(rightelbow) *= .5;
3408 victim->jointVel(rightshoulder) *= .7;
3410 victim->Puff(abdomen);
3411 victim->DoDamage(damagemult * 90 / victim->protectionhigh);
3413 award_bonus(id, Reversal);
3417 if (weaponactive != -1 || creature == wolftype)
3419 if (creature == rabbittype && weaponactive != -1)
3420 if (weapons[weaponids[0]].getType() == staff)
3423 if (weaponactive != -1) {
3424 victim->DoBloodBig(2 / victim->armorhigh, 225);
3425 emit_sound_at(knifeslicesound, victim->coords);
3426 if (bloodtoggle && !weapons[weaponids[weaponactive]].bloody)
3427 weapons[weaponids[weaponactive]].bloody = 1;
3428 weapons[weaponids[weaponactive]].blooddrip += 3;
3430 if (weaponactive == -1 && creature == wolftype) {
3431 emit_sound_at(clawslicesound, victim->coords, 128.);
3433 victim->DoBloodBig(2 / victim->armorhigh, 175);
3440 if (animTarget == swordslashreversalanim && Animation::animations[animTarget].frames[frameCurrent].label == 7) {
3446 Normalise(&relative);
3448 for (unsigned i = 0; i < victim->skeleton.joints.size(); i++) {
3449 victim->skeleton.joints[i].velocity += relative * damagemult * 70;
3451 victim->jointVel(lefthand) *= .1 - 1;
3452 victim->jointVel(leftwrist) *= .2 - 1;
3453 victim->jointVel(leftelbow) *= .5 - 1;
3454 victim->jointVel(leftshoulder) *= .7 - 1;
3455 victim->jointVel(righthand) *= .1 - 1;
3456 victim->jointVel(rightwrist) *= .2 - 1;
3457 victim->jointVel(rightelbow) *= .5 - 1;
3458 victim->jointVel(rightshoulder) *= .7 - 1;
3460 award_bonus(id, swordreversebonus);
3463 if (hasvictim && animTarget == knifeslashreversalanim && Animation::animations[animTarget].frames[frameCurrent].label == 7) {
3471 if (!Tutorial::active) {
3472 emit_sound_at(heavyimpactsound, victim->coords, 128.);
3476 relative = victim->coords - oldcoords;
3478 Normalise(&relative);
3479 relative = DoRotation(relative, 0, -90, 0);
3480 for (unsigned i = 0; i < victim->skeleton.joints.size(); i++) {
3481 victim->skeleton.joints[i].velocity += relative * damagemult * 40;
3483 victim->jointVel(abdomen) += relative * damagemult * 200;
3484 victim->Puff(abdomen);
3485 victim->DoDamage(damagemult * 30 / victim->protectionhigh);
3487 award_bonus(id, Reversal);
3490 if (hasvictim && animTarget == sneakattackanim && Animation::animations[animTarget].frames[frameCurrent].label == 7) {
3493 victim->skeleton.spinny = 0;
3495 relative = facing * -1;
3497 Normalise(&relative);
3498 if (victim->id == 0)
3500 for (unsigned i = 0; i < victim->skeleton.joints.size(); i++) {
3501 victim->skeleton.joints[i].velocity += relative * damagemult * 40;
3503 victim->damage = victim->damagetolerance;
3504 victim->permanentdamage = victim->damagetolerance - 1;
3507 if (weaponactive != -1 || creature == wolftype)
3509 if (creature == rabbittype && weaponactive != -1)
3510 if (weapons[weaponids[0]].getType() == staff)
3513 if (weaponactive != -1) {
3514 victim->DoBloodBig(200, 225);
3515 emit_sound_at(knifeslicesound, victim->coords);
3517 weapons[weaponids[weaponactive]].bloody = 2;
3518 weapons[weaponids[weaponactive]].blooddrip += 5;
3521 if (creature == wolftype && weaponactive == -1) {
3522 emit_sound_at(clawslicesound, victim->coords, 128.);
3524 victim->DoBloodBig(2, 175);
3527 award_bonus(id, spinecrusher);
3530 if (hasvictim && (animTarget == knifefollowanim || animTarget == knifesneakattackanim) && Animation::animations[animTarget].frames[frameCurrent].label == 5) {
3531 if (weaponactive != -1 && victim->bloodloss < victim->damagetolerance) {
3533 if (animTarget == knifefollowanim)
3534 victim->DoBloodBig(200, 210);
3535 if (animTarget == knifesneakattackanim) {
3536 XYZ footvel, footpoint;
3538 footpoint = weapons[weaponids[0]].tippoint;
3540 Sprite::MakeSprite(cloudimpactsprite, footpoint, footvel, 1, 0, 0, .9, .3);
3541 footvel = (weapons[weaponids[0]].tippoint - weapons[weaponids[0]].position);
3542 Sprite::MakeSprite(bloodsprite, footpoint, DoRotation(footvel * 7, (float)(Random() % 20), (float)(Random() % 20), 0), 1, 1, 1, .05, .9);
3543 Sprite::MakeSprite(bloodsprite, footpoint, DoRotation(footvel * 3, (float)(Random() % 20), (float)(Random() % 20), 0), 1, 1, 1, .05, .9);
3544 Sprite::MakeSprite(bloodflamesprite, footpoint, footvel * 5, 1, 1, 1, .3, 1);
3545 Sprite::MakeSprite(bloodflamesprite, footpoint, footvel * 2, 1, 1, 1, .3, 1);
3546 victim->DoBloodBig(200, 195);
3547 award_bonus(id, tracheotomy);
3549 if (animTarget == knifefollowanim) {
3550 award_bonus(id, Stabbonus);
3551 XYZ footvel, footpoint;
3553 footpoint = weapons[weaponids[0]].tippoint;
3555 Sprite::MakeSprite(cloudimpactsprite, footpoint, footvel, 1, 0, 0, .9, .3);
3556 footvel = (weapons[weaponids[0]].tippoint - weapons[weaponids[0]].position) * -1;
3557 Sprite::MakeSprite(bloodsprite, footpoint, DoRotation(footvel * 7, (float)(Random() % 20), (float)(Random() % 20), 0), 1, 1, 1, .05, .9);
3558 Sprite::MakeSprite(bloodsprite, footpoint, DoRotation(footvel * 3, (float)(Random() % 20), (float)(Random() % 20), 0), 1, 1, 1, .05, .9);
3559 Sprite::MakeSprite(bloodflamesprite, footpoint, footvel * 5, 1, 1, 1, .2, 1);
3560 Sprite::MakeSprite(bloodflamesprite, footpoint, footvel * 2, 1, 1, 1, .2, 1);
3563 victim->bloodloss += 10000;
3564 victim->velocity = 0;
3565 emit_sound_at(fleshstabsound, victim->coords);
3567 weapons[weaponids[weaponactive]].bloody = 2;
3568 weapons[weaponids[weaponactive]].blooddrip += 5;
3572 if (hasvictim && (animTarget == knifefollowanim || animTarget == knifesneakattackanim) && Animation::animations[animTarget].frames[frameCurrent].label == 6) {
3574 victim->velocity = 0;
3575 for (unsigned i = 0; i < victim->skeleton.joints.size(); i++) {
3576 victim->skeleton.joints[i].velocity = 0;
3578 if (animTarget == knifefollowanim) {
3580 for (unsigned i = 0; i < victim->skeleton.joints.size(); i++) {
3581 victim->skeleton.joints[i].velocity = 0;
3584 if (weaponactive != -1 && Animation::animations[victim->animTarget].attack != reversal) {
3585 emit_sound_at(fleshstabremovesound, victim->coords);
3587 weapons[weaponids[weaponactive]].bloody = 2;
3588 weapons[weaponids[weaponactive]].blooddrip += 5;
3590 XYZ footvel, footpoint;
3592 footpoint = weapons[weaponids[0]].tippoint;
3594 Sprite::MakeSprite(cloudimpactsprite, footpoint, footvel, 1, 0, 0, .9, .3);
3595 footvel = (weapons[weaponids[0]].tippoint - weapons[weaponids[0]].position) * -1;
3596 Sprite::MakeSprite(bloodsprite, footpoint, DoRotation(footvel * 7, (float)(Random() % 20), (float)(Random() % 20), 0), 1, 1, 1, .05, .9);
3597 Sprite::MakeSprite(bloodsprite, footpoint, DoRotation(footvel * 3, (float)(Random() % 20), (float)(Random() % 20), 0), 1, 1, 1, .05, .9);
3598 Sprite::MakeSprite(bloodflamesprite, footpoint, footvel * 5, 1, 1, 1, .3, 1);
3599 Sprite::MakeSprite(bloodflamesprite, footpoint, footvel * 2, 1, 1, 1, .3, 1);
3603 if (hasvictim && (animTarget == swordsneakattackanim) && Animation::animations[animTarget].frames[frameCurrent].label == 5) {
3604 if (weaponactive != -1 && victim->bloodloss < victim->damagetolerance) {
3605 award_bonus(id, backstab);
3609 XYZ footvel, footpoint;
3611 footpoint = (weapons[weaponids[0]].tippoint + weapons[weaponids[0]].position) / 2;
3613 Sprite::MakeSprite(cloudimpactsprite, footpoint, footvel, 1, 0, 0, .9, .3);
3614 footvel = (weapons[weaponids[0]].tippoint - weapons[weaponids[0]].position);
3615 Sprite::MakeSprite(bloodsprite, footpoint, DoRotation(footvel * 7, (float)(Random() % 20), (float)(Random() % 20), 0), 1, 1, 1, .05, .9);
3616 Sprite::MakeSprite(bloodsprite, footpoint, DoRotation(footvel * 3, (float)(Random() % 20), (float)(Random() % 20), 0), 1, 1, 1, .05, .9);
3617 Sprite::MakeSprite(bloodflamesprite, footpoint, DoRotation(footvel * 5, (float)(Random() % 20), (float)(Random() % 20), 0), 1, 1, 1, .3, 1);
3618 Sprite::MakeSprite(bloodflamesprite, footpoint, DoRotation(footvel * 3, (float)(Random() % 20), (float)(Random() % 20), 0), 1, 1, 1, .3, 1);
3619 victim->DoBloodBig(200, 180);
3620 victim->DoBloodBig(200, 215);
3621 victim->bloodloss += 10000;
3622 victim->velocity = 0;
3623 emit_sound_at(fleshstabsound, victim->coords);
3625 weapons[weaponids[weaponactive]].bloody = 2;
3626 weapons[weaponids[weaponactive]].blooddrip += 5;
3630 if (hasvictim && animTarget == swordsneakattackanim && Animation::animations[animTarget].frames[frameCurrent].label == 6) {
3632 victim->velocity = 0;
3633 for (unsigned i = 0; i < victim->skeleton.joints.size(); i++) {
3634 victim->skeleton.joints[i].velocity = 0;
3636 if (weaponactive != -1) {
3637 emit_sound_at(fleshstabremovesound, victim->coords);
3639 weapons[weaponids[weaponactive]].bloody = 2;
3640 weapons[weaponids[weaponactive]].blooddrip += 5;
3642 XYZ footvel, footpoint;
3644 footpoint = weapons[weaponids[0]].tippoint;
3646 Sprite::MakeSprite(cloudimpactsprite, footpoint, footvel, 1, 0, 0, .9, .3);
3647 footvel = (weapons[weaponids[0]].tippoint - weapons[weaponids[0]].position) * -1;
3648 Sprite::MakeSprite(bloodsprite, footpoint, DoRotation(footvel * 7, (float)(Random() % 20), (float)(Random() % 20), 0), 1, 1, 1, .05, .9);
3649 Sprite::MakeSprite(bloodsprite, footpoint, DoRotation(footvel * 3, (float)(Random() % 20), (float)(Random() % 20), 0), 1, 1, 1, .05, .9);
3650 Sprite::MakeSprite(bloodflamesprite, footpoint, footvel * 5, 1, 1, 1, .3, 1);
3651 Sprite::MakeSprite(bloodflamesprite, footpoint, footvel * 2, 1, 1, 1, .3, 1);
3655 if (animTarget == sweepreversalanim && Animation::animations[animTarget].frames[frameCurrent].label == 7) {
3663 if (weaponactive == -1) {
3664 if (!Tutorial::active) {
3665 emit_sound_at(heavyimpactsound, victim->coords, 128.);
3670 if (weaponactive != -1 || creature == wolftype)
3672 if (creature == rabbittype && weaponactive != -1)
3673 if (weapons[weaponids[0]].getType() == staff)
3676 if (weaponactive != -1) {
3677 victim->DoBloodBig(2 / victim->armorhead, 225);
3678 emit_sound_at(knifeslicesound, victim->coords);
3679 if (bloodtoggle && !weapons[weaponids[weaponactive]].bloody)
3680 weapons[weaponids[weaponactive]].bloody = 1;
3681 weapons[weaponids[weaponactive]].blooddrip += 3;
3683 if (weaponactive == -1 && creature == wolftype) {
3684 emit_sound_at(clawslicesound, victim->coords, 128.);
3686 victim->DoBloodBig(2 / victim->armorhead, 175);
3690 award_bonus(id, Reversal);
3695 relative = facing * -1;
3697 Normalise(&relative);
3698 relative = DoRotation(relative, 0, 90, 0);
3700 Normalise(&relative);
3701 for (unsigned i = 0; i < victim->skeleton.joints.size(); i++) {
3702 victim->skeleton.joints[i].velocity += relative * damagemult * 20;
3704 victim->jointVel(head) += relative * damagemult * 200;
3705 if (victim->damage < victim->damagetolerance - 100)
3706 victim->velocity = relative * 200;
3707 victim->DoDamage(damagemult * 100 / victim->protectionhead);
3708 victim->velocity = 0;
3711 if (animTarget == sweepreversalanim && ((Animation::animations[animTarget].frames[frameCurrent].label == 9 && victim->damage < victim->damagetolerance) || (Animation::animations[animTarget].frames[frameCurrent].label == 7 && victim->damage > victim->damagetolerance))) {
3715 relative = facing * -1;
3717 Normalise(&relative);
3718 relative = DoRotation(relative, 0, 90, 0);
3720 Normalise(&relative);
3721 for (unsigned i = 0; i < victim->skeleton.joints.size(); i++) {
3722 victim->skeleton.joints[i].velocity += relative * damagemult * 20;
3724 victim->jointVel(head) += relative * damagemult * 200;
3727 if (hasvictim && (animTarget == spinkickreversalanim || animTarget == sweepreversalanim || animTarget == rabbitkickreversalanim || animTarget == upunchreversalanim || animTarget == jumpreversalanim || animTarget == swordslashreversalanim || animTarget == knifeslashreversalanim || animTarget == rabbittacklereversal || animTarget == wolftacklereversal || animTarget == staffhitreversalanim || animTarget == staffspinhitreversalanim))
3728 if (victim->damage > victim->damagetolerance && bonus != reverseko) {
3729 award_bonus(id, reverseko);
3735 if (frameTarget > int(Animation::animations[animCurrent].frames.size()) - 1) {
3738 animTarget = getIdle();
3739 FootLand(leftfoot, 1);
3740 FootLand(rightfoot, 1);
3742 if (animCurrent == rabbittackleanim || animCurrent == rabbittacklinganim) {
3743 animTarget = rollanim;
3745 emit_sound_at(movewhooshsound, coords, 128.);
3747 if (animCurrent == staggerbackhighanim) {
3748 animTarget = getIdle();
3750 if (animCurrent == staggerbackhardanim) {
3751 animTarget = getIdle();
3753 if (animCurrent == removeknifeanim) {
3754 animTarget = getIdle();
3756 if (animCurrent == crouchremoveknifeanim) {
3757 animTarget = getCrouch();
3759 if (animCurrent == backhandspringanim) {
3760 animTarget = getIdle();
3762 if (animCurrent == dodgebackanim) {
3763 animTarget = getIdle();
3765 if (animCurrent == drawleftanim) {
3766 animTarget = getIdle();
3768 if (animCurrent == drawrightanim || animCurrent == crouchdrawrightanim) {
3769 animTarget = getIdle();
3770 if (animCurrent == crouchdrawrightanim) {
3771 animTarget = getCrouch();
3773 if (weaponactive == -1)
3775 else if (weaponactive == 0) {
3777 if (num_weapons == 2) {
3779 buffer = weaponids[0];
3780 weaponids[0] = weaponids[1];
3781 weaponids[1] = buffer;
3785 if (weaponactive == -1) {
3786 emit_sound_at(knifesheathesound, coords, 128.);
3788 if (weaponactive != -1) {
3789 emit_sound_at(knifedrawsound, coords, 128.);
3792 if (animCurrent == rollanim) {
3793 animTarget = getCrouch();
3794 FootLand(leftfoot, 1);
3795 FootLand(rightfoot, 1);
3798 if (animTarget == walljumprightkickanim) {
3801 if (animTarget == walljumpleftkickanim) {
3804 animTarget = jumpdownanim;
3806 if (animCurrent == climbanim) {
3807 animTarget = getCrouch();
3809 coords += facing * .1;
3810 if (!isnormal(coords.x))
3821 if (animTarget == rabbitkickreversalanim) {
3822 animTarget = getCrouch();
3825 if (animTarget == jumpreversalanim) {
3826 animTarget = getCrouch();
3829 if (animTarget == walljumprightanim || animTarget == walljumpbackanim || animTarget == walljumpfrontanim) {
3830 if (attackkeydown && animTarget != walljumpfrontanim) {
3832 float closestdist = -1;
3834 if (Person::players.size() > 1)
3835 for (unsigned i = 0; i < Person::players.size(); i++) {
3836 if (id != i && Person::players[i]->coords.y < coords.y && !Person::players[i]->skeleton.free) {
3837 distance = distsq(&Person::players[i]->coords, &coords);
3838 if (closestdist == -1 || distance < closestdist) {
3839 closestdist = distance;
3844 if (closestdist > 0 && closest >= 0 && closestdist < 16) {
3845 victim = Person::players[closest];
3846 animTarget = walljumprightkickanim;
3848 XYZ rotatetarget = victim->coords - coords;
3849 Normalise(&rotatetarget);
3850 yaw = -asin(0 - rotatetarget.x);
3852 if (rotatetarget.z < 0)
3854 targettilt2 = -asin(rotatetarget.y) * 360 / 6.28;
3855 velocity = (victim->coords - coords) * 4;
3860 if (animTarget == walljumpbackanim) {
3861 animTarget = backflipanim;
3863 velocity = facing * -8;
3866 resume_stream(whooshsound);
3868 if (animTarget == walljumprightanim) {
3869 animTarget = rightflipanim;
3873 velocity = DoRotation(facing, 0, 30, 0) * -8;
3876 if (animTarget == walljumpfrontanim) {
3877 animTarget = frontflipanim;
3881 velocity = facing * 8;
3885 resume_stream(whooshsound);
3887 if (animTarget == walljumpleftanim) {
3888 if (attackkeydown) {
3890 float closestdist = -1;
3892 if (Person::players.size() > 1)
3893 for (unsigned i = 0; i < Person::players.size(); i++) {
3894 if (id != i && Person::players[i]->coords.y < coords.y && !Person::players[i]->skeleton.free) {
3895 distance = distsq(&Person::players[i]->coords, &coords);
3896 if (closestdist == -1 || distance < closestdist) {
3897 closestdist = distance;
3902 if (closestdist > 0 && closest >= 0 && closestdist < 16) {
3903 victim = Person::players[closest];
3904 animTarget = walljumpleftkickanim;
3906 XYZ rotatetarget = victim->coords - coords;
3907 Normalise(&rotatetarget);
3908 yaw = -asin(0 - rotatetarget.x);
3910 if (rotatetarget.z < 0)
3912 targettilt2 = -asin(rotatetarget.y) * 360 / 6.28;
3913 velocity = (victim->coords - coords) * 4;
3918 if (animTarget != walljumpleftkickanim) {
3919 animTarget = leftflipanim;
3923 velocity = DoRotation(facing, 0, -30, 0) * -8;
3927 resume_stream(whooshsound);
3929 if (animTarget == sneakattackanim) {
3930 animCurrent = getCrouch();
3931 animTarget = getCrouch();
3938 transspeed = 1000000;
3939 targetheadyaw += 180;
3940 coords -= facing * .7;
3942 coords.y = terrain.getHeight(coords.x, coords.z);
3946 if (animTarget == knifesneakattackanim || animTarget == swordsneakattackanim) {
3947 animTarget = getIdle();
3950 coords.y = terrain.getHeight(coords.x, coords.z);
3954 if (animCurrent == knifefollowanim) {
3955 animTarget = getIdle();
3958 if (Animation::animations[animTarget].attack == reversal && animCurrent != sneakattackanim && animCurrent != knifesneakattackanim && animCurrent != swordsneakattackanim && animCurrent != knifefollowanim) {
3959 float ycoords = oldcoords.y;
3960 animTarget = getStop();
3965 transspeed = 1000000;
3966 targetheadyaw += 180;
3967 if (!isnormal(coords.x))
3969 if (animCurrent == spinkickreversalanim || animCurrent == swordslashreversalanim)
3970 oldcoords = coords + facing * .5;
3971 else if (animCurrent == sweepreversalanim)
3972 oldcoords = coords + facing * 1.1;
3973 else if (animCurrent == upunchreversalanim) {
3974 oldcoords = coords + facing * 1.5;
3977 targetheadyaw += 180;
3980 } else if (animCurrent == knifeslashreversalanim) {
3981 oldcoords = coords + facing * .5;
3984 targetheadyaw += 90;
3987 } else if (animCurrent == staffspinhitreversalanim) {
3990 targetheadyaw += 180;
3995 oldcoords.y = terrain.getHeight(oldcoords.x, oldcoords.z);
3997 oldcoords.y = ycoords;
3998 currentoffset = coords - oldcoords;
4004 if (animCurrent == knifesneakattackedanim || animCurrent == swordsneakattackedanim) {
4009 if (Animation::animations[animTarget].attack == reversed) {
4011 if (animTarget == sweepreversedanim)
4013 animTarget = backhandspringanim;
4015 emit_sound_at(landsound, coords, 128);
4017 if (animCurrent == upunchreversedanim || animCurrent == swordslashreversedanim) {
4018 animTarget = rollanim;
4021 coords += (DoRotation(jointPos(leftfoot), 0, yaw, 0) + DoRotation(jointPos(rightfoot), 0, yaw, 0)) / 2 * scale;
4022 coords.y = oldcoords.y;
4024 if (animCurrent == knifeslashreversedanim) {
4025 animTarget = rollanim;
4030 coords += (DoRotation(jointPos(leftfoot), 0, yaw, 0) + DoRotation(jointPos(rightfoot), 0, yaw, 0)) / 2 * scale;
4031 coords.y = oldcoords.y;
4035 animTarget = jumpdownanim;
4038 animTarget = getIdle();
4040 animTarget = getIdle();
4041 if (animCurrent == spinkickanim || animCurrent == getupfrombackanim || animCurrent == getupfromfrontanim || animCurrent == lowkickanim) {
4042 animTarget = getIdle();
4044 coords += (DoRotation(jointPos(leftfoot), 0, yaw, 0) + DoRotation(jointPos(rightfoot), 0, yaw, 0)) / 2 * scale;
4045 coords.y = oldcoords.y;
4046 //coords+=DoRotation(Animation::animations[animCurrent].offset,0,yaw,0)*scale;
4047 targetoffset.y = coords.y;
4049 targetoffset.y = terrain.getHeight(coords.x, coords.z);
4050 currentoffset = DoRotation(Animation::animations[animCurrent].offset * -1, 0, yaw, 0) * scale;
4051 currentoffset.y -= (coords.y - targetoffset.y);
4052 coords.y = targetoffset.y;
4054 normalsupdatedelay = 0;
4056 if (animCurrent == upunchanim) {
4057 animTarget = getStop();
4058 normalsupdatedelay = 0;
4061 if (animCurrent == rabbitkickanim && animTarget != backflipanim) {
4065 if (num_weapons > 0)
4066 if (weapons[0].getType() == staff)
4072 rabbitkickragdoll = 1;
4074 if (animCurrent == rabbitkickreversedanim) {
4080 skeleton.spinny = 0;
4081 SolidHitBonus(!id); // FIXME: tricky id
4085 animTarget = rollanim;
4088 pause_sound(whooshsound);
4092 if (animCurrent == rabbittackledbackanim || animCurrent == rabbittackledfrontanim) {
4096 skeleton.spinny = 0;
4098 if (animCurrent == jumpreversedanim) {
4104 skeleton.spinny = 0;
4105 SolidHitBonus(!id); // FIXME: tricky id
4109 animTarget = rollanim;
4110 coords += facing * 2;
4112 pause_sound(whooshsound);
4117 if (Animation::animations[animCurrent].attack == normalattack && !victim->skeleton.free && victim->animTarget != staggerbackhighanim && victim->animTarget != staggerbackhardanim && animTarget != winduppunchblockedanim && animTarget != blockhighleftanim && animTarget != swordslashparryanim && animTarget != swordslashparriedanim && animTarget != crouchstabanim && animTarget != swordgroundstabanim) {
4118 animTarget = getupfromfrontanim;
4120 } else if (Animation::animations[animCurrent].attack == normalattack) {
4121 animTarget = getIdle();
4124 if (animCurrent == blockhighleftanim && aitype != playercontrolled) {
4125 animTarget = blockhighleftstrikeanim;
4127 if (animCurrent == knifeslashstartanim || animCurrent == knifethrowanim || animCurrent == swordslashanim || animCurrent == staffhitanim || animCurrent == staffgroundsmashanim || animCurrent == staffspinhitanim) {
4128 animTarget = getIdle();
4131 if (animCurrent == spinkickanim && victim->skeleton.free) {
4132 if (creature == rabbittype)
4133 animTarget = fightidleanim;
4138 if (isIdle() && !wasIdle())
4139 normalsupdatedelay = 0;
4141 if (animCurrent == jumpupanim && velocity.y < 0 && !isFlip()) {
4142 animTarget = jumpdownanim;
4145 if (!skeleton.free) {
4147 if (!transspeed && Animation::animations[animTarget].attack != 2 && Animation::animations[animTarget].attack != 3) {
4148 if (!isRun() || !wasRun()) {
4149 if (targetFrame().speed > currentFrame().speed)
4150 target += multiplier * targetFrame().speed * speed * 2;
4151 if (targetFrame().speed <= currentFrame().speed)
4152 target += multiplier * currentFrame().speed * speed * 2;
4154 if (isRun() && wasRun()) {
4156 tempspeed = velspeed;
4157 if (tempspeed < 10 * speedmult)
4158 tempspeed = 10 * speedmult;
4159 /* FIXME - mixed of target and current here, is that intended? */
4160 target += multiplier * Animation::animations[animTarget].frames[frameCurrent].speed * speed * 1.7 * tempspeed / (speed * 45 * scale);
4162 } else if (transspeed)
4163 target += multiplier * transspeed * speed * 2;
4165 if (!isRun() || !wasRun()) {
4166 if (targetFrame().speed > currentFrame().speed)
4167 target += multiplier * targetFrame().speed * 2;
4168 if (targetFrame().speed <= currentFrame().speed)
4169 target += multiplier * currentFrame().speed * 2;
4173 if (animCurrent != animTarget)
4174 target = (target + oldtarget) / 2;
4177 frameCurrent = frameTarget;
4181 rot = targetrot * target;
4182 yaw += rot - oldrot;
4188 if (frameCurrent >= int(Animation::animations[animCurrent].frames.size())) {
4189 frameCurrent = Animation::animations[animCurrent].frames.size() - 1;
4191 if (animCurrent != oldanimCurrent || animTarget != oldanimTarget || ((frameCurrent != oldframeCurrent || frameTarget != oldframeTarget) && !calcrot)) {
4193 for (unsigned i = 0; i < skeleton.joints.size(); i++) {
4194 skeleton.joints[i].position = currentFrame().joints[i].position;
4197 skeleton.FindForwards();
4199 for (unsigned i = 0; i < skeleton.muscles.size(); i++) {
4200 if (skeleton.muscles[i].visible) {
4201 skeleton.FindRotationMuscle(i, animTarget);
4204 for (unsigned i = 0; i < skeleton.muscles.size(); i++) {
4205 if (skeleton.muscles[i].visible) {
4206 if (isnormal((float)((int)(skeleton.muscles[i].rotate1 * 100) % 36000) / 100))
4207 skeleton.muscles[i].oldrotate1 = (float)((int)(skeleton.muscles[i].rotate1 * 100) % 36000) / 100;
4208 if (isnormal((float)((int)(skeleton.muscles[i].rotate2 * 100) % 36000) / 100))
4209 skeleton.muscles[i].oldrotate2 = (float)((int)(skeleton.muscles[i].rotate2 * 100) % 36000) / 100;
4210 if (isnormal((float)((int)(skeleton.muscles[i].rotate3 * 100) % 36000) / 100))
4211 skeleton.muscles[i].oldrotate3 = (float)((int)(skeleton.muscles[i].rotate3 * 100) % 36000) / 100;
4216 for (unsigned i = 0; i < skeleton.joints.size(); i++) {
4217 skeleton.joints[i].position = targetFrame().joints[i].position;
4220 skeleton.FindForwards();
4222 for (unsigned i = 0; i < skeleton.muscles.size(); i++) {
4223 if (skeleton.muscles[i].visible) {
4224 skeleton.FindRotationMuscle(i, animTarget);
4227 for (unsigned i = 0; i < skeleton.muscles.size(); i++) {
4228 if (skeleton.muscles[i].visible) {
4229 if (isnormal((float)((int)(skeleton.muscles[i].rotate1 * 100) % 36000) / 100))
4230 skeleton.muscles[i].newrotate1 = (float)((int)(skeleton.muscles[i].rotate1 * 100) % 36000) / 100;
4231 if (isnormal((float)((int)(skeleton.muscles[i].rotate2 * 100) % 36000) / 100))
4232 skeleton.muscles[i].newrotate2 = (float)((int)(skeleton.muscles[i].rotate2 * 100) % 36000) / 100;
4233 if (isnormal((float)((int)(skeleton.muscles[i].rotate3 * 100) % 36000) / 100))
4234 skeleton.muscles[i].newrotate3 = (float)((int)(skeleton.muscles[i].rotate3 * 100) % 36000) / 100;
4235 if (skeleton.muscles[i].newrotate3 > skeleton.muscles[i].oldrotate3 + 180) skeleton.muscles[i].newrotate3 -= 360;
4236 if (skeleton.muscles[i].newrotate3 < skeleton.muscles[i].oldrotate3 - 180) skeleton.muscles[i].newrotate3 += 360;
4237 if (skeleton.muscles[i].newrotate2 > skeleton.muscles[i].oldrotate2 + 180) skeleton.muscles[i].newrotate2 -= 360;
4238 if (skeleton.muscles[i].newrotate2 < skeleton.muscles[i].oldrotate2 - 180) skeleton.muscles[i].newrotate2 += 360;
4239 if (skeleton.muscles[i].newrotate1 > skeleton.muscles[i].oldrotate1 + 180) skeleton.muscles[i].newrotate1 -= 360;
4240 if (skeleton.muscles[i].newrotate1 < skeleton.muscles[i].oldrotate1 - 180) skeleton.muscles[i].newrotate1 += 360;
4245 oldanimCurrent = animCurrent;
4246 oldanimTarget = animTarget;
4247 oldframeTarget = frameTarget;
4248 oldframeCurrent = frameCurrent;
4250 for (unsigned i = 0; i < skeleton.joints.size(); i++) {
4251 skeleton.joints[i].velocity = (currentFrame().joints[i].position * (1 - target) + targetFrame().joints[i].position * (target) - skeleton.joints[i].position) / multiplier;
4252 skeleton.joints[i].position = currentFrame().joints[i].position * (1 - target) + targetFrame().joints[i].position * (target);
4254 offset = currentoffset * (1 - target) + targetoffset * target;
4255 for (unsigned i = 0; i < skeleton.muscles.size(); i++) {
4256 if (skeleton.muscles[i].visible) {
4257 skeleton.muscles[i].rotate1 = skeleton.muscles[i].oldrotate1 * (1 - target) + skeleton.muscles[i].newrotate1 * (target);
4258 skeleton.muscles[i].rotate2 = skeleton.muscles[i].oldrotate2 * (1 - target) + skeleton.muscles[i].newrotate2 * (target);
4259 skeleton.muscles[i].rotate3 = skeleton.muscles[i].oldrotate3 * (1 - target) + skeleton.muscles[i].newrotate3 * (target);
4264 if (isLanding() && landhard) {
4267 animTarget = getLandhard();
4280 void Person::DoStuff()
4282 static XYZ terrainnormal;
4283 static XYZ flatfacing;
4284 static XYZ flatvelocity;
4285 static float flatvelspeed;
4287 static int bloodsize;
4288 static int startx, starty, endx, endy;
4289 static GLubyte color;
4290 static XYZ bloodvel;
4292 onfiredelay -= multiplier;
4293 if (onfiredelay < 0 && onfire) {
4294 if (Random() % 2 == 0) {
4300 crouchkeydowntime += multiplier;
4302 crouchkeydowntime = 0;
4303 jumpkeydowntime += multiplier;
4304 if (!jumpkeydown && skeleton.free)
4305 jumpkeydowntime = 0;
4307 if (hostile || damage > 0 || bloodloss > 0)
4310 if (isIdle() || isRun())
4313 if (num_weapons == 1 && weaponactive != -1)
4317 blooddimamount -= multiplier * .3;
4318 speechdelay -= multiplier;
4319 texupdatedelay -= multiplier;
4320 interestdelay -= multiplier;
4321 flamedelay -= multiplier;
4322 parriedrecently -= multiplier;
4324 victim = this->shared_from_this();
4329 speed = 1.1 * speedmult;
4331 speed = 1.0 * speedmult;
4333 rabbitkickragdoll = 0;
4337 if (id != 0 && (creature == rabbittype || difficulty != 2))
4339 if (id != 0 && creature == wolftype && difficulty == 2) {
4341 if (aitype != passivetype) {
4343 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) {
4349 if (animTarget == wolfrunninganim && !superruntoggle) {
4350 animTarget = getRun();
4354 if (weaponactive == -1 && num_weapons > 0) {
4355 if (weapons[weaponids[0]].getType() == staff) {
4361 burnt += multiplier;
4365 OPENAL_SetVolume(channels[stream_firesound], 256 + 256 * findLength(&velocity) / 3);
4367 if (animTarget == jumpupanim || animTarget == jumpdownanim || isFlip()) {
4373 vel[0] = velocity.x;
4374 vel[1] = velocity.y;
4375 vel[2] = velocity.z;
4378 OPENAL_3D_SetAttributes(channels[whooshsound], gLoc, vel);
4379 OPENAL_SetVolume(channels[whooshsound], 64 * findLength(&velocity) / 5);
4383 while (flamedelay < 0 && onfire) {
4385 int howmany = fabs(Random() % (skeleton.joints.size()));
4386 if (skeleton.free) {
4387 flatvelocity = skeleton.joints[howmany].velocity * scale / 2;
4388 flatfacing = skeleton.joints[howmany].position * scale + coords;
4390 flatfacing = DoRotation(DoRotation(DoRotation(skeleton.joints[howmany].position, 0, 0, tilt), tilt2, 0, 0), 0, yaw, 0) * scale + coords;
4391 flatvelocity = (coords - oldcoords) / multiplier / 2;
4393 Sprite::MakeSprite(flamesprite, flatfacing, flatvelocity, 1, 1, 1, .6 + (float)abs(Random() % 100) / 200 - .25, 1);
4396 while (flamedelay < 0 && !onfire && Tutorial::active && id != 0) {
4398 int howmany = fabs(Random() % (skeleton.joints.size()));
4399 if (skeleton.free) {
4400 flatvelocity = skeleton.joints[howmany].velocity * scale / 2;
4401 flatfacing = skeleton.joints[howmany].position * scale + coords;
4403 flatvelocity = (coords - oldcoords) / multiplier / 2;
4404 flatfacing = DoRotation(DoRotation(DoRotation(skeleton.joints[howmany].position, 0, 0, tilt), tilt2, 0, 0), 0, yaw, 0) * scale + coords;
4406 Sprite::MakeSprite(breathsprite, flatfacing, flatvelocity, 1, 1, 1, .6 + (float)abs(Random() % 100) / 200 - .25, .3);
4410 bleeding -= multiplier * .3;
4411 if (bloodtoggle == 2) {
4412 skeleton.drawmodel.textureptr.bind();
4413 if ((bleeding <= 0) && (detail != 2))
4418 if (neckspurtamount > 0) {
4419 neckspurtamount -= multiplier;
4420 neckspurtdelay -= multiplier * 3;
4421 neckspurtparticledelay -= multiplier * 3;
4422 if (neckspurtparticledelay < 0 && neckspurtdelay > 2) {
4425 if (skeleton.free) {
4426 bloodvel -= DoRotation(skeleton.forward * 10 * scale, ((float)(Random() % 100)) / 40, ((float)(Random() % 100)) / 40, 0);
4427 bloodvel += DoRotation(jointVel(head), ((float)(Random() % 100)) / 40, yaw + ((float)(Random() % 100)) / 40, 0) * scale;
4428 Sprite::MakeSprite(bloodsprite, (jointPos(neck) + (jointPos(neck) - jointPos(head)) / 5)*scale + coords, bloodvel, 1, 1, 1, .05, .9);
4430 bloodvel.z = 5 * neckspurtamount;
4431 bloodvel = DoRotation(bloodvel, ((float)(Random() % 100)) / 40, yaw + ((float)(Random() % 100)) / 40, 0) * scale;
4432 bloodvel += DoRotation(velocity, ((float)(Random() % 100)) / 40, ((float)(Random() % 100)) / 40, 0) * scale;
4433 Sprite::MakeSprite(bloodsprite, DoRotation(jointPos(neck) + (jointPos(neck) - jointPos(head)) / 5, 0, yaw, 0)*scale + coords, bloodvel, 1, 1, 1, .05, .9);
4435 neckspurtparticledelay = .05;
4437 if (neckspurtdelay < 0) {
4442 if (deathbleeding > 0 && dead != 2) {
4443 if (deathbleeding < 5)
4444 bleeddelay -= deathbleeding * multiplier / 4;
4446 bleeddelay -= 5 * multiplier / 4;
4447 if (bleeddelay < 0 && bloodtoggle) {
4452 if (skeleton.free) {
4453 bloodvel += DoRotation(jointVel(abdomen), ((float)(Random() % 100)) / 4, yaw + ((float)(Random() % 100)) / 4, 0) * scale;
4454 Sprite::MakeSprite(bloodsprite, jointPos(abdomen) * scale + coords, bloodvel, 1, 1, 1, .05, 1);
4456 bloodvel += DoRotation(velocity, ((float)(Random() % 100)) / 4, ((float)(Random() % 100)) / 4, 0) * scale;
4457 Sprite::MakeSprite(bloodsprite, DoRotation((jointPos(abdomen) + jointPos(abdomen)) / 2, 0, yaw, 0)*scale + coords, bloodvel, 1, 1, 1, .05, 1);
4461 bloodloss += deathbleeding * multiplier * 80;
4462 deathbleeding -= multiplier * 1.6;
4463 if (deathbleeding < 0)
4465 if (bloodloss > damagetolerance && Animation::animations[animTarget].attack == neutral) {
4466 if (weaponactive != -1) {
4467 weapons[weaponids[0]].drop(velocity * scale * -.3, velocity * scale);
4468 weapons[weaponids[0]].velocity.x += .01;
4471 weaponids[0] = weaponids[num_weapons];
4472 if (weaponstuck == num_weapons)
4476 for (unsigned i = 0; i < Person::players.size(); i++) {
4477 Person::players[i]->wentforweapon = 0;
4485 if (!dead && creature == wolftype) {
4486 award_bonus(0, Wolfbonus);
4489 if (animTarget == knifefollowedanim && !skeleton.free) {
4490 for (unsigned i = 0; i < skeleton.joints.size(); i++) {
4491 skeleton.joints[i].velocity = 0;
4492 skeleton.joints[i].velocity.y = -2;
4495 if (id != 0 && unconscioustime > .1) {
4503 if (texupdatedelay < 0 && bleeding > 0 && bloodtoggle == 2 && distsq(&viewer, &coords) < 9) {
4504 texupdatedelay = .12;
4506 bloodsize = 5 - realtexdetail;
4510 startx = bleedy; //abs(Random()%(skeleton.skinsize-bloodsize-1));
4511 starty = bleedx; //abs(Random()%(skeleton.skinsize-bloodsize-1));
4512 endx = startx + bloodsize;
4513 endy = starty + bloodsize;
4523 if (endx > skeleton.skinsize - 1) {
4524 endx = skeleton.skinsize - 1;
4527 if (endy > skeleton.skinsize - 1) {
4528 endy = skeleton.skinsize - 1;
4536 for (i = startx; i < endx; i++) {
4537 for (int j = starty; j < endy; j++) {
4538 if (Random() % 2 == 0) {
4539 color = Random() % 85 + 170;
4540 if (skeleton.skinText[i * skeleton.skinsize * 3 + j * 3 + 0] > color / 2)
4541 skeleton.skinText[i * skeleton.skinsize * 3 + j * 3 + 0] = color / 2;
4542 skeleton.skinText[i * skeleton.skinsize * 3 + j * 3 + 1] = 0;
4543 skeleton.skinText[i * skeleton.skinsize * 3 + j * 3 + 2] = 0;
4548 skeleton.drawmodel.textureptr.bind();
4552 if (skeleton.free) {
4553 bleedx += 4 * direction / realtexdetail;
4555 bleedy += (abs(Random() % 3) - 1) * 2 / realtexdetail;
4557 bleedy += (abs(Random() % 3) - 1) * 4 / realtexdetail;
4559 bleedy -= 4 / realtexdetail;
4561 bleedx += (abs(Random() % 3) - 1) * 2 / realtexdetail;
4563 bleedx += (abs(Random() % 3) - 1) * 4 / realtexdetail;
4567 if (abs(righthandmorphness - targetrighthandmorphness) < multiplier * 4) {
4568 righthandmorphness = targetrighthandmorphness;
4569 righthandmorphstart = righthandmorphend;
4570 } else if (righthandmorphness > targetrighthandmorphness) {
4571 righthandmorphness -= multiplier * 4;
4572 } else if (righthandmorphness < targetrighthandmorphness) {
4573 righthandmorphness += multiplier * 4;
4576 if (abs(lefthandmorphness - targetlefthandmorphness) < multiplier * 4) {
4577 lefthandmorphness = targetlefthandmorphness;
4578 lefthandmorphstart = lefthandmorphend;
4579 } else if (lefthandmorphness > targetlefthandmorphness) {
4580 lefthandmorphness -= multiplier * 4;
4581 } else if (lefthandmorphness < targetlefthandmorphness) {
4582 lefthandmorphness += multiplier * 4;
4585 if (creature == rabbittype || targettailmorphness == 5 || targettailmorphness == 0) {
4586 if (abs(tailmorphness - targettailmorphness) < multiplier * 10) {
4587 tailmorphness = targettailmorphness;
4588 tailmorphstart = tailmorphend;
4589 } else if (tailmorphness > targettailmorphness) {
4590 tailmorphness -= multiplier * 10;
4591 } else if (tailmorphness < targettailmorphness) {
4592 tailmorphness += multiplier * 10;
4596 if (creature == wolftype) {
4597 if (abs(tailmorphness - targettailmorphness) < multiplier * 4) {
4598 tailmorphness = targettailmorphness;
4599 tailmorphstart = tailmorphend;
4600 } else if (tailmorphness > targettailmorphness) {
4601 tailmorphness -= multiplier * 2;
4602 } else if (tailmorphness < targettailmorphness) {
4603 tailmorphness += multiplier * 2;
4607 if (headmorphend == 3 || headmorphstart == 3) {
4608 if (abs(headmorphness - targetheadmorphness) < multiplier * 7) {
4609 headmorphness = targetheadmorphness;
4610 headmorphstart = headmorphend;
4611 } else if (headmorphness > targetheadmorphness) {
4612 headmorphness -= multiplier * 7;
4613 } else if (headmorphness < targetheadmorphness) {
4614 headmorphness += multiplier * 7;
4616 } else if (headmorphend == 5 || headmorphstart == 5) {
4617 if (abs(headmorphness - targetheadmorphness) < multiplier * 10) {
4618 headmorphness = targetheadmorphness;
4619 headmorphstart = headmorphend;
4620 } else if (headmorphness > targetheadmorphness) {
4621 headmorphness -= multiplier * 10;
4622 } else if (headmorphness < targetheadmorphness) {
4623 headmorphness += multiplier * 10;
4626 if (abs(headmorphness - targetheadmorphness) < multiplier * 4) {
4627 headmorphness = targetheadmorphness;
4628 headmorphstart = headmorphend;
4629 } else if (headmorphness > targetheadmorphness) {
4630 headmorphness -= multiplier * 4;
4631 } else if (headmorphness < targetheadmorphness) {
4632 headmorphness += multiplier * 4;
4636 if (abs(chestmorphness - targetchestmorphness) < multiplier) {
4637 chestmorphness = targetchestmorphness;
4638 chestmorphstart = chestmorphend;
4639 } else if (chestmorphness > targetchestmorphness) {
4640 chestmorphness -= multiplier;
4641 } else if (chestmorphness < targetchestmorphness) {
4642 chestmorphness += multiplier;
4645 if (dead != 2 && howactive <= typesleeping) {
4646 if (chestmorphstart == 0 && chestmorphend == 0) {
4648 targetchestmorphness = 1;
4651 if (chestmorphstart != 0 && chestmorphend != 0) {
4653 targetchestmorphness = 1;
4655 if (environment == snowyenvironment) {
4658 if (skeleton.free) {
4659 footvel = skeleton.specialforward[0] * -1;
4660 footpoint = ((jointPos(head) + jointPos(neck)) / 2) * scale + coords;
4662 footvel = DoRotation(skeleton.specialforward[0], 0, yaw, 0) * -1;
4663 footpoint = DoRotation((jointPos(head) + jointPos(neck)) / 2, 0, yaw, 0) * scale + coords;
4665 if (animTarget == sleepanim)
4666 footvel = DoRotation(footvel, 0, 90, 0);
4667 Sprite::MakeSprite(breathsprite, footpoint + footvel * .2, footvel * .4, 1, 1, 1, .4, .3);
4671 if (!dead && howactive < typesleeping) {
4672 blinkdelay -= multiplier * 2;
4673 if (headmorphstart == 0 && headmorphend == 0 && blinkdelay <= 0) {
4675 targetheadmorphness = 1;
4677 blinkdelay = (float)(abs(Random() % 40)) / 5;
4679 if (headmorphstart == 3 && headmorphend == 3) {
4681 targetheadmorphness = 1;
4686 twitchdelay -= multiplier * 1.5;
4687 if (animTarget != hurtidleanim) {
4688 if (headmorphstart == 0 && headmorphend == 0 && twitchdelay <= 0) {
4690 targetheadmorphness = 1;
4692 twitchdelay = (float)(abs(Random() % 40)) / 5;
4694 if (headmorphstart == 5 && headmorphend == 5) {
4696 targetheadmorphness = 1;
4700 if ((isIdle() || isCrouch()) && animTarget != hurtidleanim) {
4701 twitchdelay3 -= multiplier * 1;
4702 if (Random() % 2 == 0) {
4703 if (righthandmorphstart == 0 && righthandmorphend == 0 && twitchdelay3 <= 0) {
4704 righthandmorphness = 0;
4705 targetrighthandmorphness = 1;
4706 righthandmorphend = 1;
4707 if (Random() % 2 == 0)twitchdelay3 = (float)(abs(Random() % 40)) / 5;
4709 if (righthandmorphstart == 1 && righthandmorphend == 1) {
4710 righthandmorphness = 0;
4711 targetrighthandmorphness = 1;
4712 righthandmorphend = 0;
4715 if (Random() % 2 == 0) {
4716 if (lefthandmorphstart == 0 && lefthandmorphend == 0 && twitchdelay3 <= 0) {
4717 lefthandmorphness = 0;
4718 targetlefthandmorphness = 1;
4719 lefthandmorphend = 1;
4720 twitchdelay3 = (float)(abs(Random() % 40)) / 5;
4722 if (lefthandmorphstart == 1 && lefthandmorphend == 1) {
4723 lefthandmorphness = 0;
4724 targetlefthandmorphness = 1;
4725 lefthandmorphend = 0;
4731 if (creature == rabbittype) {
4732 if (howactive < typesleeping)
4733 twitchdelay2 -= multiplier * 1.5;
4735 twitchdelay2 -= multiplier * 0.5;
4736 if (howactive <= typesleeping) {
4737 if (tailmorphstart == 0 && tailmorphend == 0 && twitchdelay2 <= 0) {
4739 targettailmorphness = 1;
4741 twitchdelay2 = (float)(abs(Random() % 40)) / 5;
4743 if (tailmorphstart == 1 && tailmorphend == 1) {
4745 targettailmorphness = 1;
4748 if (tailmorphstart == 2 && tailmorphend == 2) {
4750 targettailmorphness = 1;
4757 if (creature == wolftype) {
4758 twitchdelay2 -= multiplier * 1.5;
4759 if (tailmorphend != 0)
4760 if ((isRun() || animTarget == jumpupanim || animTarget == jumpdownanim || animTarget == backflipanim) && !skeleton.free) {
4762 targettailmorphness = 1;
4766 if (tailmorphend != 5)
4767 if (animTarget == flipanim || animTarget == frontflipanim || animTarget == rollanim || skeleton.free) {
4769 targettailmorphness = 1;
4773 if (twitchdelay2 <= 0) {
4774 if (((tailmorphstart == 0 && tailmorphend == 0) || (tailmorphstart == 5 && tailmorphend == 5))) {
4776 targettailmorphness = 1;
4779 if (tailmorphstart == 1 && tailmorphend == 1) {
4781 targettailmorphness = 1;
4784 if (tailmorphstart == 2 && tailmorphend == 2) {
4786 targettailmorphness = 1;
4789 if (tailmorphstart == 3 && tailmorphend == 3) {
4791 targettailmorphness = 1;
4794 if (tailmorphstart == 4 && tailmorphend == 4) {
4796 targettailmorphness = 1;
4803 unconscioustime = 0;
4805 if (dead == 1 || howactive == typesleeping) {
4806 unconscioustime += multiplier;
4807 //If unconscious, close eyes and mouth
4808 if (righthandmorphend != 0)
4809 righthandmorphness = 0;
4810 righthandmorphend = 0;
4811 targetrighthandmorphness = 1;
4813 if (lefthandmorphend != 0)
4814 lefthandmorphness = 0;
4815 lefthandmorphend = 0;
4816 targetlefthandmorphness = 1;
4818 if (headmorphend != 3 && headmorphend != 5)
4821 targetheadmorphness = 1;
4825 if (howactive > typesleeping) {
4828 if (bloodtoggle && !bled) {
4829 terrain.MakeDecal(blooddecalslow, headpoint, .8, .5, 0);
4831 if (bloodtoggle && !bled)
4832 for (l = 0; l < terrain.patchobjectnum[whichpatchx][whichpatchz]; l++) {
4833 int j = terrain.patchobjects[whichpatchx][whichpatchz][l];
4834 XYZ point = DoRotation(headpoint - Object::objects[j]->position, 0, -Object::objects[j]->yaw, 0);
4838 Object::objects[j]->model.MakeDecal(blooddecalslow, &point, &size, &opacity, &yaw);
4843 if (dead == 2 || howactive > typesleeping) {
4844 //If dead, open mouth and hands
4845 if (righthandmorphend != 0)
4846 righthandmorphness = 0;
4847 righthandmorphend = 0;
4848 targetrighthandmorphness = 1;
4850 if (lefthandmorphend != 0)
4851 lefthandmorphness = 0;
4852 lefthandmorphend = 0;
4853 targetlefthandmorphness = 1;
4855 if (headmorphend != 2)
4858 targetheadmorphness = 1;
4861 if (stunned > 0 && !dead && headmorphend != 2) {
4862 if (headmorphend != 4)
4865 targetheadmorphness = 1;
4868 if (damage > damagetolerance && !dead) {
4871 unconscioustime = 0;
4873 if (creature == wolftype) {
4874 award_bonus(0, Wolfbonus);
4879 if (weaponactive != -1) {
4880 weapons[weaponids[0]].drop(velocity * scale * -.3, velocity * scale);
4881 weapons[weaponids[0]].velocity.x += .01;
4884 weaponids[0] = weaponids[num_weapons];
4885 if (weaponstuck == num_weapons)
4889 for (unsigned i = 0; i < Person::players.size(); i++) {
4890 Person::players[i]->wentforweapon = 0;
4896 if ((id == 0 || distsq(&coords, &viewer) < 50) && autoslomo) {
4905 damage -= multiplier * 13;
4907 permanentdamage -= multiplier * 4;
4908 if (isIdle() || isCrouch()) {
4910 permanentdamage -= multiplier * 4;
4914 if (permanentdamage < 0)
4915 permanentdamage = 0;
4916 if (superpermanentdamage < 0)
4917 superpermanentdamage = 0;
4918 if (permanentdamage < superpermanentdamage) {
4919 permanentdamage = superpermanentdamage;
4921 if (damage < permanentdamage) {
4922 damage = permanentdamage;
4924 if (dead == 1 && damage < damagetolerance) {
4928 for (unsigned i = 0; i < skeleton.joints.size(); i++) {
4929 skeleton.joints[i].velocity = 0;
4932 if (permanentdamage > damagetolerance && dead != 2) {
4935 if (weaponactive != -1) {
4936 weapons[weaponids[0]].drop(velocity * scale * -.3, velocity * scale);
4937 weapons[weaponids[0]].velocity.x += .01;
4940 weaponids[0] = weaponids[num_weapons];
4941 if (weaponstuck == num_weapons)
4945 for (unsigned i = 0; i < Person::players.size(); i++) {
4946 Person::players[i]->wentforweapon = 0;
4952 if (!dead && creature == wolftype) {
4953 award_bonus(0, Wolfbonus);
4956 if (unconscioustime < .1 && (bonus != spinecrusher || bonustime > 1) && (bonus != FinishedBonus || bonustime > 1) && bloodloss < damagetolerance)
4957 award_bonus(id, touchofdeath);
4958 if (id != 0 && unconscioustime > .1) {
4966 emit_sound_at(breaksound, coords);
4969 if (skeleton.free == 1) {
4971 pause_sound(whooshsound);
4974 //If knocked over, open hands and close mouth
4975 if (righthandmorphend != 0)
4976 righthandmorphness = 0;
4977 righthandmorphend = 0;
4978 targetrighthandmorphness = 1;
4980 if (lefthandmorphend != 0)
4981 lefthandmorphness = 0;
4982 lefthandmorphend = 0;
4983 targetlefthandmorphness = 1;
4985 if (headmorphend != 3 && headmorphend != 5 && headmorphstart != 3 && headmorphstart != 5) {
4986 if (headmorphend != 0)
4989 targetheadmorphness = 1;
4993 skeleton.DoGravity(&scale);
4995 damageamount = skeleton.DoConstraints(&coords, &scale) * 5;
4996 if (damage > damagetolerance - damageamount && !dead && (bonus != spinecrusher || bonustime > 1) && (bonus != style || bonustime > 1) && (bonus != cannon || bonustime > 1))
4997 award_bonus(id, deepimpact);
4998 DoDamage(damageamount / ((protectionhigh + protectionhead + protectionlow) / 3));
5002 if (!skeleton.joints.empty()) {
5003 for (unsigned j = 0; j < skeleton.joints.size(); j++) {
5004 average += skeleton.joints[j].position;
5006 average /= skeleton.joints.size();
5007 coords += average * scale;
5008 for (unsigned j = 0; j < skeleton.joints.size(); j++) {
5009 skeleton.joints[j].position -= average;
5011 average /= multiplier;
5015 for (unsigned i = 0; i < skeleton.joints.size(); i++) {
5016 velocity += skeleton.joints[i].velocity * scale;
5018 velocity /= skeleton.joints.size();
5020 if (!isnormal(velocity.x) && velocity.x) {
5024 if (findLength(&average) < 10 && dead && skeleton.free) {
5025 skeleton.longdead += (2000 - findLength(&average)) * multiplier + multiplier;
5026 if (skeleton.longdead > 2000) {
5027 if (skeleton.longdead > 6000) {
5029 pause_sound(whooshsound);
5034 if (dead == 2 && bloodloss < damagetolerance) {
5036 headpoint = (jointPos(head) + jointPos(neck)) / 2 * scale + coords;
5038 if (bloodtoggle && !bled) {
5039 terrain.MakeDecal(blooddecal, headpoint, .2 * 1.2, .5, 0);
5041 if (bloodtoggle && !bled)
5042 for (l = 0; l < terrain.patchobjectnum[whichpatchx][whichpatchz]; l++) {
5043 int j = terrain.patchobjects[whichpatchx][whichpatchz][l];
5044 XYZ point = DoRotation(headpoint - Object::objects[j]->position, 0, -Object::objects[j]->yaw, 0);
5045 float size = .2 * 1.2;
5048 Object::objects[j]->model.MakeDecal(blooddecal, &point, &size, &opacity, &yaw);
5052 if (dead == 2 && bloodloss >= damagetolerance) {
5054 headpoint = (jointPos(abdomen) + jointPos(neck)) / 2 * scale + coords;
5057 if (bloodtoggle && !bled) {
5058 terrain.MakeDecal(blooddecalslow, headpoint, .8, .5, 0);
5060 if (bloodtoggle && !bled)
5061 for (l = 0; l < terrain.patchobjectnum[whichpatchx][whichpatchz]; l++) {
5062 int j = terrain.patchobjects[whichpatchx][whichpatchz][l];
5063 XYZ point = DoRotation(headpoint - Object::objects[j]->position, 0, -Object::objects[j]->yaw, 0);
5067 Object::objects[j]->model.MakeDecal(blooddecalslow, &point, &size, &opacity, &yaw);
5074 if (!dead && crouchkeydown && skeleton.freetime > .5 && id == 0 && skeleton.free) {
5075 bool canrecover = 1;
5076 XYZ startpoint, endpoint, colpoint, colviewer, coltarget;
5077 startpoint = coords;
5080 if (terrain.lineTerrain(startpoint, endpoint, &colpoint) != -1)
5082 if (velocity.y < -30)
5084 for (i = 0; i < Object::objects.size(); i++) {
5085 if (Object::objects[i]->type != treeleavestype && Object::objects[i]->type != bushtype && Object::objects[i]->type != firetype) {
5086 colviewer = startpoint;
5087 coltarget = endpoint;
5088 if (Object::objects[i]->model.LineCheck(&colviewer, &coltarget, &colpoint, &Object::objects[i]->position, &Object::objects[i]->yaw) != -1)
5097 terrainnormal = jointPos(groin) - jointPos(abdomen);
5098 if (joint(groin).locked && joint(abdomen).locked) {
5099 terrainnormal = jointPos(groin) - jointPos(abdomen);
5100 middle = (jointPos(groin) + jointPos(abdomen)) / 2;
5102 if (joint(abdomen).locked && joint(neck).locked) {
5103 terrainnormal = jointPos(abdomen) - jointPos(neck);
5104 middle = (jointPos(neck) + jointPos(abdomen)) / 2;
5106 if (joint(groin).locked && joint(neck).locked) {
5107 terrainnormal = jointPos(groin) - jointPos(neck);
5108 middle = (jointPos(groin) + jointPos(neck)) / 2;
5110 Normalise(&terrainnormal);
5112 targetyaw = -asin(0 - terrainnormal.x);
5113 targetyaw *= 360 / 6.28;
5114 if (terrainnormal.z < 0)
5115 targetyaw = 180 - targetyaw;
5119 animTarget = flipanim;
5120 crouchtogglekeydown = 1;
5125 animCurrent = tempanim;
5129 for (unsigned i = 0; i < skeleton.joints.size(); i++) {
5130 tempanimation.frames[0].joints[i].position = skeleton.joints[i].position;
5131 tempanimation.frames[0].joints[i].position = DoRotation(tempanimation.frames[0].joints[i].position, 0, -yaw, 0);
5136 if (findLength(&average) < 10 && !dead && skeleton.free) {
5137 skeleton.longdead += (2000 - findLength(&average)) * multiplier + multiplier;
5138 if (skeleton.longdead > (damage + 500) * 1.5) {
5140 pause_sound(whooshsound);
5146 terrainnormal = jointPos(groin) - jointPos(abdomen);
5147 if (joint(groin).locked && joint(abdomen).locked) {
5148 terrainnormal = jointPos(groin) - jointPos(abdomen);
5149 middle = (jointPos(groin) + jointPos(abdomen)) / 2;
5151 if (joint(abdomen).locked && joint(neck).locked) {
5152 terrainnormal = jointPos(abdomen) - jointPos(neck);
5153 middle = (jointPos(neck) + jointPos(abdomen)) / 2;
5155 if (joint(groin).locked && joint(neck).locked) {
5156 terrainnormal = jointPos(groin) - jointPos(neck);
5157 middle = (jointPos(groin) + jointPos(neck)) / 2;
5159 Normalise(&terrainnormal);
5161 targetyaw = -asin(0 - terrainnormal.x);
5162 targetyaw *= 360 / 6.28;
5163 if (terrainnormal.z < 0)
5164 targetyaw = 180 - targetyaw;
5167 targettilt2 = asin(terrainnormal.y) * 180 / 3.14 * -1;
5170 if (skeleton.forward.y < 0) {
5171 animTarget = getupfrombackanim;
5175 if (skeleton.forward.y > -.3) {
5176 animTarget = getupfromfrontanim;
5184 if ((Random() % 8 == 0 && id != 0 && creature == rabbittype) || (Random() % 2 == 0 && id != 0 && creature == wolftype) || (id == 0 && crouchkeydown && (forwardkeydown || backkeydown || leftkeydown || rightkeydown))) {
5185 animTarget = rollanim;
5186 targetyaw = lookyaw;
5203 if ( !leftkeydown && !rightkeydown)
5210 if (abs(targettilt2) > 50)
5212 animCurrent = tempanim;
5215 tilt2 = targettilt2;
5217 if (middle.y > 0 && animTarget != rollanim)
5218 targetoffset.y = middle.y + 1;
5220 for (unsigned i = 0; i < skeleton.joints.size(); i++) {
5221 tempanimation.frames[0].joints[i].position = skeleton.joints[i].position;
5222 tempanimation.frames[0].joints[i].position = DoRotation(tempanimation.frames[0].joints[i].position, 0, -yaw, 0);
5229 if (num_weapons > 0)
5230 if (weapons[0].getType() == staff)
5232 if (!skeleton.freefall && freefall && ((jumpkeydown && jumpkeydowntime < .2) || (hasstaff && rabbitkickragdoll)) && !dead) {
5233 if (velocity.y > -30) {
5235 tempvelocity = velocity;
5236 Normalise(&tempvelocity);
5237 targetyaw = -asin(0 - tempvelocity.x);
5238 targetyaw *= 360 / 6.28;
5240 targetyaw = 180 - targetyaw;
5244 if (dotproduct(&skeleton.forward, &tempvelocity) < 0) {
5245 animTarget = rollanim;
5248 animTarget = backhandspringanim;
5254 emit_sound_at(movewhooshsound, coords, 128.);
5256 animCurrent = animTarget;
5257 frameCurrent = frameTarget - 1;
5269 if (skeleton.freefall == 0)
5274 if (aitype != passivetype || skeleton.free == 1)
5275 if (findLengthfast(&velocity) > .1)
5276 for (i = 0; i < Object::objects.size(); i++) {
5277 if (Object::objects[i]->type == firetype)
5278 if (distsqflat(&coords, &Object::objects[i]->position) < Object::objects[i]->scale*Object::objects[i]->scale * 12 && distsq(&coords, &Object::objects[i]->position) < Object::objects[i]->scale*Object::objects[i]->scale * 49) {
5280 if (!Object::objects[i]->onfire) {
5281 emit_sound_at(firestartsound, Object::objects[i]->position);
5283 Object::objects[i]->onfire = 1;
5286 if (Object::objects[i]->onfire) {
5291 if (Object::objects[i]->type == bushtype)
5292 if (distsqflat(&coords, &Object::objects[i]->position) < Object::objects[i]->scale*Object::objects[i]->scale * 12 && distsq(&coords, &Object::objects[i]->position) < Object::objects[i]->scale*Object::objects[i]->scale * 49) {
5294 if (!Object::objects[i]->onfire) {
5295 emit_sound_at(firestartsound, Object::objects[i]->position);
5297 Object::objects[i]->onfire = 1;
5301 if (Object::objects[i]->onfire) {
5305 if (Object::objects[i]->messedwith <= 0) {
5309 emit_sound_at(bushrustle, coords, 40 * findLength(&velocity));
5312 addEnvSound(coords, 4 * findLength(&velocity));
5316 if (environment == grassyenvironment)
5317 howmany = findLength(&velocity) * 4;
5318 if (environment == snowyenvironment)
5319 howmany = findLength(&velocity) * 2;
5321 if (environment != desertenvironment)
5322 for (int j = 0; j < howmany; j++) {
5323 tempvel.x = float(abs(Random() % 100) - 50) / 20;
5324 tempvel.y = float(abs(Random() % 100) - 50) / 20;
5325 tempvel.z = float(abs(Random() % 100) - 50) / 20;
5328 pos.x += float(abs(Random() % 100) - 50) / 200;
5329 pos.y += float(abs(Random() % 100) - 50) / 200;
5330 pos.z += float(abs(Random() % 100) - 50) / 200;
5331 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);
5332 Sprite::setLastSpriteSpecial(1);
5334 howmany = findLength(&velocity) * 4;
5336 if (environment == snowyenvironment)
5337 for (int j = 0; j < howmany; j++) {
5338 tempvel.x = float(abs(Random() % 100) - 50) / 20;
5339 tempvel.y = float(abs(Random() % 100) - 50) / 20;
5340 tempvel.z = float(abs(Random() % 100) - 50) / 20;
5343 pos.x += float(abs(Random() % 100) - 50) / 200;
5344 pos.y += float(abs(Random() % 100) - 50) / 200;
5345 pos.z += float(abs(Random() % 100) - 50) / 200;
5346 Sprite::MakeSprite(splintersprite, pos, tempvel * .3 + velocity * float(abs(Random() % 100)) / 100 / 2, 1, 1, 1, .1, 1);
5347 Sprite::setLastSpriteSpecial(2);
5350 Object::objects[i]->rotx += velocity.x * multiplier * 6;
5351 Object::objects[i]->roty += velocity.z * multiplier * 6;
5352 Object::objects[i]->messedwith = .5;
5355 if (Object::objects[i]->type == treeleavestype && environment != desertenvironment) {
5356 if (Object::objects[i]->pitch == 0)
5359 tempcoord = coords - Object::objects[i]->position;
5360 tempcoord = DoRotation(tempcoord, 0, -Object::objects[i]->yaw, 0);
5361 tempcoord = DoRotation(tempcoord, -Object::objects[i]->pitch, 0, 0);
5362 tempcoord += Object::objects[i]->position;
5364 if (distsqflat(&tempcoord, &Object::objects[i]->position) < Object::objects[i]->scale*Object::objects[i]->scale * 8 && distsq(&tempcoord, &Object::objects[i]->position) < Object::objects[i]->scale*Object::objects[i]->scale * 300 && tempcoord.y > Object::objects[i]->position.y + 3 * Object::objects[i]->scale) {
5365 if (Object::objects[i]->messedwith <= 0) {
5369 emit_sound_at(bushrustle, coords, 40 * findLength(&velocity));
5372 addEnvSound(coords, 4 * findLength(&velocity));
5376 if (environment == grassyenvironment)
5377 howmany = findLength(&velocity) * 4;
5378 if (environment == snowyenvironment)
5379 howmany = findLength(&velocity) * 2;
5381 if (environment != desertenvironment)
5382 for (int j = 0; j < howmany; j++) {
5383 tempvel.x = float(abs(Random() % 100) - 50) / 20;
5384 tempvel.y = float(abs(Random() % 100) - 50) / 20;
5385 tempvel.z = float(abs(Random() % 100) - 50) / 20;
5387 pos += velocity * .1;
5389 pos.x += float(abs(Random() % 100) - 50) / 150;
5390 pos.y += float(abs(Random() % 100) - 50) / 150;
5391 pos.z += float(abs(Random() % 100) - 50) / 150;
5392 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);
5393 Sprite::setLastSpriteSpecial(1);
5395 howmany = findLength(&velocity) * 4;
5397 if (environment == snowyenvironment)
5398 for (int j = 0; j < howmany; j++) {
5399 tempvel.x = float(abs(Random() % 100) - 50) / 20;
5400 tempvel.y = float(abs(Random() % 100) - 50) / 20;
5401 tempvel.z = float(abs(Random() % 100) - 50) / 20;
5403 pos += velocity * .1;
5405 pos.x += float(abs(Random() % 100) - 50) / 150;
5406 pos.y += float(abs(Random() % 100) - 50) / 150;
5407 pos.z += float(abs(Random() % 100) - 50) / 150;
5408 Sprite::MakeSprite(splintersprite, pos, tempvel * .3 + velocity * float(abs(Random() % 100)) / 100 / 2, 1, 1, 1, .1, 1);
5409 Sprite::setLastSpriteSpecial(2);
5412 Object::objects[i]->messedwith = .5;
5417 if (!skeleton.free) {
5420 if ((stunned > 0 || surprised > 0) && Person::players.size() > 2 && aitype != passivetype)
5423 if (aitype != passivetype && victim->skeleton.free && !victim->dead)
5425 if (Tutorial::active && id != 0)
5427 if (play && aitype != playercontrolled) {
5428 int whichsound = -1;
5429 i = abs(Random() % 4);
5430 if (speechdelay <= 0) {
5431 if (creature == rabbittype) {
5433 whichsound = rabbitchitter;
5435 whichsound = rabbitchitter2;
5437 if (creature == wolftype) {
5439 whichsound = growlsound;
5441 whichsound = growl2sound;
5446 if (whichsound != -1) {
5447 emit_sound_at(whichsound, coords);
5451 if (animTarget == staggerbackhighanim)
5453 if (animTarget == staggerbackhardanim)
5455 staggerdelay -= multiplier;
5456 if (animTarget != crouchstabanim && animTarget != swordgroundstabanim && animTarget != staffgroundsmashanim)
5458 if (velocity.y < -30 && animTarget == jumpdownanim)
5460 if (animCurrent != getIdle() && wasIdle() && animTarget != getIdle() && isIdle()) {
5461 animTarget = getIdle();
5465 weaponmissdelay -= multiplier;
5466 highreversaldelay -= multiplier;
5467 lowreversaldelay -= multiplier;
5468 lastcollide -= multiplier;
5469 skiddelay -= multiplier;
5470 if (!isnormal(velocity.x) && velocity.x) {
5473 if (!isnormal(targettilt) && targettilt) {
5476 if (!isnormal(targettilt2) && targettilt2) {
5479 if (!isnormal(targetyaw) && targetyaw) {
5483 if (animTarget == bounceidleanim || animTarget == wolfidle || animTarget == walkanim || animTarget == drawrightanim || animTarget == crouchdrawrightanim || animTarget == drawleftanim || animTarget == fightidleanim || animTarget == fightsidestep || animTarget == hanganim || isCrouch() || animTarget == backhandspringanim) {
5484 //open hands and close mouth
5485 if (righthandmorphend != 0 && righthandmorphness == targetrighthandmorphness) {
5486 righthandmorphness = 0;
5487 righthandmorphend = 0;
5488 targetrighthandmorphness = 1;
5491 if (lefthandmorphend != 0 && lefthandmorphness == targetlefthandmorphness) {
5492 lefthandmorphness = 0;
5493 lefthandmorphend = 0;
5494 targetlefthandmorphness = 1;
5497 if (headmorphend != 3 && headmorphend != 5 && headmorphstart != 3 && headmorphstart != 5 && headmorphend != 0 && headmorphness == targetheadmorphness) {
5500 targetheadmorphness = 1;
5504 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) {
5505 //open hands and mouth
5506 if (righthandmorphend != 0 && righthandmorphness == targetrighthandmorphness) {
5507 righthandmorphness = 0;
5508 righthandmorphend = 0;
5509 targetrighthandmorphness = 1;
5512 if (lefthandmorphend != 0 && lefthandmorphness == targetlefthandmorphness) {
5513 lefthandmorphness = 0;
5514 lefthandmorphend = 0;
5515 targetlefthandmorphness = 1;
5518 if (headmorphend != 1 && headmorphness == targetheadmorphness) {
5521 targetheadmorphness = 1;
5525 if (animTarget == jumpupanim || animTarget == crouchstabanim || animTarget == swordgroundstabanim || animTarget == swordfightidlebothanim || animTarget == blockhighleftanim) {
5526 //close hands and mouth
5527 if (righthandmorphend != 1 && righthandmorphness == targetrighthandmorphness) {
5528 righthandmorphness = 0;
5529 righthandmorphend = 1;
5530 targetrighthandmorphness = 1;
5533 if (lefthandmorphend != 1 && lefthandmorphness == targetlefthandmorphness) {
5534 lefthandmorphness = 0;
5535 lefthandmorphend = 1;
5536 targetlefthandmorphness = 1;
5539 if (headmorphend != 0 && headmorphness == targetheadmorphness) {
5542 targetheadmorphness = 1;
5546 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) {
5547 //close hands and yell
5548 if (righthandmorphend != 1 && righthandmorphness == targetrighthandmorphness) {
5549 righthandmorphness = 0;
5550 righthandmorphend = 1;
5551 targetrighthandmorphness = 1;
5554 if (lefthandmorphend != 1 && lefthandmorphness == targetlefthandmorphness) {
5555 lefthandmorphness = 0;
5556 lefthandmorphend = 1;
5557 targetlefthandmorphness = 1;
5560 if (headmorphend != 2 && headmorphness == targetheadmorphness) {
5563 targetheadmorphness = 1;
5570 if ((victim != this->shared_from_this()) && !victim->dead && (victim->aitype != passivetype) &&
5571 (victim->aitype != searchtype) && (aitype != passivetype) &&
5572 (aitype != searchtype) && (victim->id < Person::players.size())) {
5573 behind = (normaldotproduct(facing, coords - victim->coords) > 0);
5577 if (!dead && animTarget != hurtidleanim)
5578 if (behind || animTarget == killanim || animTarget == knifethrowanim || animTarget == knifefollowanim || animTarget == spinkickreversalanim || animTarget == rabbitkickreversedanim || animTarget == jumpreversedanim) {
5579 if (headmorphend != 4 || headmorphness == targetheadmorphness) {
5582 targetheadmorphness = 1;
5586 if (weaponactive != -1) {
5587 if (weapons[weaponids[weaponactive]].getType() != staff) {
5588 righthandmorphstart = 1;
5589 righthandmorphend = 1;
5591 if (weapons[weaponids[weaponactive]].getType() == staff) {
5592 righthandmorphstart = 2;
5593 righthandmorphend = 2;
5595 targetrighthandmorphness = 1;
5598 terrainnormal = terrain.getNormal(coords.x, coords.z);
5600 if (Animation::animations[animTarget].attack != reversal) {
5601 if (!isnormal(coords.x))
5609 flatfacing = DoRotation(flatfacing, 0, yaw, 0);
5610 facing = flatfacing;
5611 ReflectVector(&facing, terrainnormal);
5614 if (isRun() || animTarget == sneakanim || animTarget == rollanim || animTarget == walkanim) {
5616 targettilt2 = -facing.y * 20;
5621 if (!isRun() && !Animation::animations[animTarget].attack && animTarget != getupfromfrontanim && animTarget != getupfrombackanim && animTarget != sneakanim)
5623 if (animTarget == jumpupanim || animTarget == jumpdownanim || isFlip()) {
5624 flatvelocity = velocity;
5626 flatvelspeed = findLength(&flatvelocity);
5627 targettilt = flatvelspeed * fast_sqrt(abs(velocity.y) * .7) * normaldotproduct(DoRotation(flatfacing, 0, -90, 0), flatvelocity);
5628 targettilt2 = flatvelspeed * fast_sqrt(abs(velocity.y) * .7) * normaldotproduct(flatfacing, flatvelocity);
5633 if (targettilt > 25)
5635 if (targettilt < -25)
5639 if (targettilt2 > 45)
5641 if (targettilt2 < -45)
5643 if (abs(tilt2 - targettilt2) < multiplier * 400)
5644 tilt2 = targettilt2;
5645 else if (tilt2 > targettilt2) {
5646 tilt2 -= multiplier * 400;
5647 } else if (tilt2 < targettilt2) {
5648 tilt2 += multiplier * 400;
5650 if (!Animation::animations[animTarget].attack && animTarget != getupfrombackanim && animTarget != getupfromfrontanim) {
5657 if (!isnormal(targettilt) && targettilt) {
5660 if (!isnormal(targettilt2) && targettilt2) {
5665 if (animTarget == rabbittackleanim) {
5666 velocity += facing * multiplier * speed * 700 * scale;
5667 velspeed = findLength(&velocity);
5668 if (velspeed > speed * 65 * scale) {
5669 velocity /= velspeed;
5670 velspeed = speed * 65 * scale;
5671 velocity *= velspeed;
5673 velocity.y += gravity * multiplier * 20;
5674 ReflectVector(&velocity, terrain.getNormal(coords.x, coords.z));
5675 velspeed = findLength(&velocity);
5676 velocity = flatfacing * velspeed;
5678 if (animTarget != rabbitrunninganim && animTarget != wolfrunninganim) {
5679 if (isRun() || animTarget == rabbitkickanim) {
5680 velocity += facing * multiplier * speed * 700 * scale;
5681 velspeed = findLength(&velocity);
5682 if (velspeed > speed * 45 * scale) {
5683 velocity /= velspeed;
5684 velspeed = speed * 45 * scale;
5685 velocity *= velspeed;
5687 velocity.y += gravity * multiplier * 20;
5688 ReflectVector(&velocity, terrain.getNormal(coords.x, coords.z));
5689 velspeed = findLength(&velocity);
5690 if (velspeed < speed * 30 * scale)
5691 velspeed = speed * 30 * scale;
5692 velocity = flatfacing * velspeed;
5694 } else if (isRun()) {
5695 velocity += facing * multiplier * speed * 700 * scale;
5696 velspeed = findLength(&velocity);
5697 if (creature == rabbittype) {
5698 if (velspeed > speed * 55 * scale) {
5699 velocity /= velspeed;
5700 velspeed = speed * 55 * scale;
5701 velocity *= velspeed;
5704 if (creature == wolftype) {
5705 if (velspeed > speed * 75 * scale) {
5706 velocity /= velspeed;
5707 velspeed = speed * 75 * scale;
5708 velocity *= velspeed;
5711 velocity.y += gravity * multiplier * 20;
5712 ReflectVector(&velocity, terrain.getNormal(coords.x, coords.z));
5713 velspeed = findLength(&velocity);
5714 velocity = flatfacing * velspeed;
5717 if (animTarget == rollanim && targetFrame().label != 6) {
5718 velocity += facing * multiplier * speed * 700 * scale;
5719 velspeed = findLength(&velocity);
5720 if (velspeed > speed * 45 * scale) {
5721 velocity /= velspeed;
5722 velspeed = speed * 45 * scale;
5723 velocity *= velspeed;
5725 velocity.y += gravity * multiplier * 20;
5726 ReflectVector(&velocity, terrain.getNormal(coords.x, coords.z));
5727 velspeed = findLength(&velocity);
5728 velocity = flatfacing * velspeed;
5731 if (animTarget == sneakanim || animTarget == walkanim) {
5732 velocity += facing * multiplier * speed * 700 * scale;
5733 velspeed = findLength(&velocity);
5734 if (velspeed > speed * 12 * scale) {
5735 velocity /= velspeed;
5736 velspeed = speed * 12 * scale;
5737 velocity *= velspeed;
5739 velocity.y += gravity * multiplier * 20;
5740 ReflectVector(&velocity, terrain.getNormal(coords.x, coords.z));
5741 velspeed = findLength(&velocity);
5742 velocity = flatfacing * velspeed;
5745 if ((animTarget == fightidleanim || animTarget == knifefightidleanim) && (animCurrent == bounceidleanim || animCurrent == hurtidleanim)) {
5746 velocity += facing * multiplier * speed * 700 * scale;
5747 velspeed = findLength(&velocity);
5748 if (velspeed > speed * 2 * scale) {
5749 velocity /= velspeed;
5750 velspeed = speed * 2 * scale;
5751 velocity *= velspeed;
5753 velocity.y += gravity * multiplier * 20;
5754 ReflectVector(&velocity, terrain.getNormal(coords.x, coords.z));
5755 velspeed = findLength(&velocity);
5756 velocity = flatfacing * velspeed;
5760 if ((animTarget == bounceidleanim || animCurrent == hurtidleanim) && (animCurrent == fightidleanim || animCurrent == knifefightidleanim)) {
5761 velocity -= facing * multiplier * speed * 700 * scale;
5762 velspeed = findLength(&velocity);
5763 if (velspeed > speed * 2 * scale) {
5764 velocity /= velspeed;
5765 velspeed = speed * 2 * scale;
5766 velocity *= velspeed;
5768 velocity.y += gravity * multiplier * 20;
5769 ReflectVector(&velocity, terrain.getNormal(coords.x, coords.z));
5770 velspeed = findLength(&velocity);
5771 velocity = flatfacing * velspeed * -1;
5774 if (animTarget == fightsidestep) {
5775 velocity += DoRotation(facing * multiplier * speed * 700 * scale, 0, -90, 0);
5776 velspeed = findLength(&velocity);
5777 if (velspeed > speed * 12 * scale) {
5778 velocity /= velspeed;
5779 velspeed = speed * 12 * scale;
5780 velocity *= velspeed;
5782 velocity.y += gravity * multiplier * 20;
5783 ReflectVector(&velocity, terrain.getNormal(coords.x, coords.z));
5784 velspeed = findLength(&velocity);
5785 velocity = DoRotation(flatfacing * velspeed, 0, -90, 0);
5788 if (animTarget == staggerbackhighanim) {
5789 coords -= facing * multiplier * speed * 16 * scale;
5792 if (animTarget == staggerbackhardanim && Animation::animations[staggerbackhardanim].frames[frameTarget].label != 6) {
5793 coords -= facing * multiplier * speed * 20 * scale;
5797 if (animTarget == backhandspringanim) {
5798 //coords-=facing*multiplier*50*scale;
5799 velocity += facing * multiplier * speed * 700 * scale * -1;
5800 velspeed = findLength(&velocity);
5801 if (velspeed > speed * 50 * scale) {
5802 velocity /= velspeed;
5803 velspeed = speed * 50 * scale;
5804 velocity *= velspeed;
5806 velocity.y += gravity * multiplier * 20;
5807 ReflectVector(&velocity, terrain.getNormal(coords.x, coords.z));
5808 velspeed = findLength(&velocity);
5809 velocity = flatfacing * velspeed * -1;
5811 if (animTarget == dodgebackanim) {
5812 //coords-=facing*multiplier*50*scale;
5813 velocity += facing * multiplier * speed * 700 * scale * -1;
5814 velspeed = findLength(&velocity);
5815 if (velspeed > speed * 60 * scale) {
5816 velocity /= velspeed;
5817 velspeed = speed * 60 * scale;
5818 velocity *= velspeed;
5820 velocity.y += gravity * multiplier * 20;
5821 ReflectVector(&velocity, terrain.getNormal(coords.x, coords.z));
5822 velspeed = findLength(&velocity);
5823 velocity = flatfacing * velspeed * -1;
5826 if (animTarget == jumpupanim || animTarget == jumpdownanim || isFlip()) {
5827 velspeed = findLength(&velocity);
5831 if (animTarget == jumpupanim || animTarget == jumpdownanim || isFlip()) {
5832 velocity.y += gravity * multiplier;
5835 if (animTarget != climbanim && animTarget != hanganim && !isWallJump())
5836 coords += velocity * multiplier;
5838 if (coords.y < terrain.getHeight(coords.x, coords.z) && (animTarget == jumpdownanim || animTarget == jumpupanim || isFlip())) {
5839 if (isFlip() && targetFrame().label == 7)
5842 if (animTarget == jumpupanim) {
5844 animTarget = getIdle();
5851 pause_sound(whooshsound);
5852 OPENAL_SetVolume(channels[whooshsound], 0);
5855 if (animTarget == jumpdownanim || isFlip()) {
5856 if (isFlip())jumppower = -4;
5857 animTarget = getLanding();
5858 emit_sound_at(landsound, coords, 128.);
5861 addEnvSound(coords);
5866 if (animTarget != jumpupanim && animTarget != jumpdownanim && !isFlip() && animTarget != climbanim && animTarget != hanganim && !isWallJump())
5867 coords.y += gravity * multiplier * 2;
5868 if (animTarget != jumpupanim && animTarget != jumpdownanim && !isFlip() && coords.y < terrain.getHeight(coords.x, coords.z)) {
5869 coords.y = terrain.getHeight(coords.x, coords.z);
5874 if (isIdle() || animTarget == drawrightanim || animTarget == drawleftanim || animTarget == crouchdrawrightanim || animTarget == crouchstabanim || animTarget == swordgroundstabanim || isStop() || animTarget == removeknifeanim || animTarget == crouchremoveknifeanim || isLanding() || isCrouch() || Animation::animations[animTarget].attack || (animTarget == rollanim && targetFrame().label == 6)) {
5875 velspeed = findLength(&velocity);
5877 if (velspeed < multiplier * 300 * scale) {
5880 velocity -= velocity / velspeed * multiplier * 300 * scale;
5881 if (velspeed > 5 && (isLanding() || isLandhard())) {
5882 skiddingdelay += multiplier;
5883 if (skiddelay <= 0) {
5884 FootLand(leftfoot, .5);
5885 FootLand(rightfoot, .5);
5893 velspeed = findLength(&velocity);
5895 if (velspeed < multiplier * 600 * scale) {
5898 velocity -= velocity / velspeed * multiplier * 600 * scale;
5900 if (velspeed > 5 && (isLanding() || isLandhard())) {
5901 skiddingdelay += multiplier;
5902 if (skiddelay <= 0) {
5903 FootLand(leftfoot, .5);
5904 FootLand(rightfoot, .5);
5911 if (skiddingdelay < 0)
5912 skiddingdelay += multiplier;
5913 if (skiddingdelay > .02 && !forwardkeydown && !backkeydown && !leftkeydown && !rightkeydown && !jumpkeydown && isLanding() && !landhard) {
5915 if (!onterrain || environment == grassyenvironment) {
5916 emit_sound_at(skidsound, coords, 128 * velspeed / 10);
5918 emit_sound_at(snowskidsound, coords, 128 * velspeed / 10);
5922 if (Animation::animations[animTarget].attack == normalattack && animTarget != rabbitkickanim && !victim->skeleton.free) {
5923 terrainnormal = victim->coords - coords;
5924 Normalise(&terrainnormal);
5925 targetyaw = -asin(0 - terrainnormal.x);
5926 targetyaw *= 360 / 6.28;
5927 if (terrainnormal.z < 0)
5928 targetyaw = 180 - targetyaw;
5929 targettilt2 = -asin(terrainnormal.y) * 360 / 6.28; //*-70;
5932 if (Animation::animations[animTarget].attack == reversal && animTarget != rabbittacklinganim) {
5933 targetyaw = victim->targetyaw;
5935 if (animTarget == rabbittacklinganim) {
5936 coords = victim->coords;
5939 skeleton.oldfree = skeleton.free;
5943 midterrain.x = terrain.size * terrain.scale / 2;
5944 midterrain.z = terrain.size * terrain.scale / 2;
5945 if (distsqflat(&coords, &midterrain) > (terrain.size * terrain.scale / 2 - viewdistance) * (terrain.size * terrain.scale / 2 - viewdistance)) {
5947 tempposit = coords - midterrain;
5949 Normalise(&tempposit);
5950 tempposit *= (terrain.size * terrain.scale / 2 - viewdistance);
5951 coords.x = tempposit.x + midterrain.x;
5952 coords.z = tempposit.z + midterrain.z;
5958 * inverse kinematics helper function
5960 void IKHelper(Person *p, float interp)
5962 XYZ point, change, change2;
5963 float heightleft, heightright;
5965 // TODO: implement localToWorld and worldToLocal
5966 // but keep in mind it won't be the same math if player is ragdolled or something
5967 // - localToWorldStanding / worldToLocalStanding (or crouching or...?)
5968 // then comb through code for places where to use it
5970 // point = localToWorld(jointPos(leftfoot))
5971 point = DoRotation(p->jointPos(leftfoot), 0, p->yaw, 0) * p->scale + p->coords;
5972 // adjust height of foot
5973 heightleft = terrain.getHeight(point.x, point.z) + .04;
5974 point.y = heightleft;
5975 change = p->jointPos(leftankle) - p->jointPos(leftfoot);
5976 change2 = p->jointPos(leftknee) - p->jointPos(leftfoot);
5977 // jointPos(leftfoot) = interpolate(worldToLocal(point), jointPos(leftfoot), interp)
5978 p->jointPos(leftfoot) = DoRotation((point - p->coords) / p->scale, 0, -p->yaw, 0) * interp + p->jointPos(leftfoot) * (1 - interp);
5979 // move ankle along with foot
5980 p->jointPos(leftankle) = p->jointPos(leftfoot) + change;
5981 // average knee pos between old and new pos
5982 p->jointPos(leftknee) = (p->jointPos(leftfoot) + change2) / 2 + (p->jointPos(leftknee)) / 2;
5984 // do same as above for right leg
5985 point = DoRotation(p->jointPos(rightfoot), 0, p->yaw, 0) * p->scale + p->coords;
5986 heightright = terrain.getHeight(point.x, point.z) + .04;
5987 point.y = heightright;
5988 change = p->jointPos(rightankle) - p->jointPos(rightfoot);
5989 change2 = p->jointPos(rightknee) - p->jointPos(rightfoot);
5990 p->jointPos(rightfoot) = DoRotation((point - p->coords) / p->scale, 0, -p->yaw, 0) * interp + p->jointPos(rightfoot) * (1 - interp);
5991 p->jointPos(rightankle) = p->jointPos(rightfoot) + change;
5992 p->jointPos(rightknee) = (p->jointPos(rightfoot) + change2) / 2 + (p->jointPos(rightknee)) / 2;
5994 // fix up skeleton now that we've moved body parts?
5995 p->skeleton.DoConstraints(&p->coords, &p->scale);
6002 int Person::DrawSkeleton()
6004 int oldplayerdetail;
6005 if ((frustum.SphereInFrustum(coords.x, coords.y + scale * 3, coords.z, scale * 8) && distsq(&viewer, &coords) < viewdistance * viewdistance) || skeleton.free == 3) {
6006 if (onterrain && (isIdle() || isCrouch() || wasIdle() || wasCrouch()) && !skeleton.free) {
6016 glAlphaFunc(GL_GREATER, 0.0001);
6018 float terrainheight;
6022 if (!isnormal(tilt))
6024 if (!isnormal(tilt2))
6026 oldplayerdetail = playerdetail;
6028 if (distsq(&viewer, &coords) < viewdistance * viewdistance / 32 && detail == 2) {
6031 if (distsq(&viewer, &coords) < viewdistance * viewdistance / 128 && detail == 1) {
6034 if (distsq(&viewer, &coords) < viewdistance * viewdistance / 256 && (detail != 1 && detail != 2)) {
6039 if (playerdetail != oldplayerdetail) {
6041 normalsupdatedelay = 0;
6043 static float updatedelaychange;
6044 static float morphness;
6045 static float framemult;
6047 skeleton.FindForwards();
6048 if (howactive == typesittingwall) {
6049 skeleton.specialforward[1] = 0;
6050 skeleton.specialforward[1].z = 1;
6056 static int weaponattachmuscle;
6057 static int weaponrotatemuscle;
6058 static XYZ weaponpoint;
6059 static int start, endthing;
6060 if ((dead != 2 || skeleton.free != 2) && updatedelay <= 0) {
6061 if (!isSleeping() && !isSitting()) {
6062 // TODO: give these meaningful names
6063 const bool cond1 = (isIdle() || isCrouch() || isLanding() || isLandhard()
6064 || animTarget == drawrightanim || animTarget == drawleftanim || animTarget == crouchdrawrightanim);
6065 const bool cond2 = (wasIdle() || wasCrouch() || wasLanding() || wasLandhard()
6066 || animCurrent == drawrightanim || animCurrent == drawleftanim || animCurrent == crouchdrawrightanim);
6068 if (onterrain && (cond1 && cond2) && !skeleton.free) {
6070 if (creature == wolftype)
6074 if (onterrain && (cond1 && !cond2) && !skeleton.free) {
6075 IKHelper(this, target);
6076 if (creature == wolftype)
6077 IKHelper(this, target);
6080 if (onterrain && (!cond1 && cond2) && !skeleton.free) {
6081 IKHelper(this, 1 - target);
6082 if (creature == wolftype)
6083 IKHelper(this, 1 - target);
6087 if (!skeleton.free && (!Animation::animations[animTarget].attack && animTarget != getupfrombackanim && ((animTarget != rollanim && !isFlip()) || targetFrame().label == 6) && animTarget != getupfromfrontanim && animTarget != wolfrunninganim && animTarget != rabbitrunninganim && animTarget != backhandspringanim && animTarget != walljumpfrontanim && animTarget != hurtidleanim && !isLandhard() && !isSleeping()))
6090 targetheadyaw = -targetyaw;
6091 targetheadpitch = 0;
6092 if (Animation::animations[animTarget].attack == 3)
6093 targetheadyaw += 180;
6095 for (i = 0; i < skeleton.drawmodel.vertexNum; i++) {
6096 skeleton.drawmodel.vertex[i] = 0;
6097 skeleton.drawmodel.vertex[i].y = 999;
6099 for (i = 0; i < skeleton.drawmodellow.vertexNum; i++) {
6100 skeleton.drawmodellow.vertex[i] = 0;
6101 skeleton.drawmodellow.vertex[i].y = 999;
6103 for (i = 0; i < skeleton.drawmodelclothes.vertexNum; i++) {
6104 skeleton.drawmodelclothes.vertex[i] = 0;
6105 skeleton.drawmodelclothes.vertex[i].y = 999;
6107 for (unsigned i = 0; i < skeleton.muscles.size(); i++) {
6108 // convenience renames
6109 const int p1 = skeleton.muscles[i].parent1->label;
6110 const int p2 = skeleton.muscles[i].parent2->label;
6112 if ((skeleton.muscles[i].vertices.size() > 0 && playerdetail) || (skeleton.muscles[i].verticeslow.size() > 0 && !playerdetail)) {
6117 if (p1 == righthand || p2 == righthand) {
6118 morphness = righthandmorphness;
6119 start = righthandmorphstart;
6120 endthing = righthandmorphend;
6122 if (p1 == lefthand || p2 == lefthand) {
6123 morphness = lefthandmorphness;
6124 start = lefthandmorphstart;
6125 endthing = lefthandmorphend;
6127 if (p1 == head || p2 == head) {
6128 morphness = headmorphness;
6129 start = headmorphstart;
6130 endthing = headmorphend;
6132 if ((p1 == neck && p2 == abdomen) || (p2 == neck && p1 == abdomen)) {
6133 morphness = chestmorphness;
6134 start = chestmorphstart;
6135 endthing = chestmorphend;
6137 if ((p1 == groin && p2 == abdomen) || (p2 == groin && p1 == abdomen)) {
6138 morphness = tailmorphness;
6139 start = tailmorphstart;
6140 endthing = tailmorphend;
6143 skeleton.FindRotationMuscle(i, animTarget);
6144 mid = (skeleton.muscles[i].parent1->position + skeleton.muscles[i].parent2->position) / 2;
6145 glMatrixMode(GL_MODELVIEW);
6149 glRotatef(tilt2, 1, 0, 0);
6151 glRotatef(tilt, 0, 0, 1);
6154 glTranslatef(mid.x, mid.y, mid.z);
6156 skeleton.muscles[i].lastrotate1 = skeleton.muscles[i].rotate1;
6157 glRotatef(-skeleton.muscles[i].lastrotate1 + 90, 0, 1, 0);
6159 skeleton.muscles[i].lastrotate2 = skeleton.muscles[i].rotate2;
6160 glRotatef(-skeleton.muscles[i].lastrotate2 + 90, 0, 0, 1);
6162 skeleton.muscles[i].lastrotate3 = skeleton.muscles[i].rotate3;
6163 glRotatef(-skeleton.muscles[i].lastrotate3, 0, 1, 0);
6165 if (playerdetail || skeleton.free == 3) {
6166 for (unsigned j = 0; j < skeleton.muscles[i].vertices.size(); j++) {
6167 XYZ &v0 = skeleton.model[start].vertex[skeleton.muscles[i].vertices[j]];
6168 XYZ &v1 = skeleton.model[endthing].vertex[skeleton.muscles[i].vertices[j]];
6169 glMatrixMode(GL_MODELVIEW);
6171 if (p1 == abdomen || p2 == abdomen)
6172 glTranslatef((v0.x * (1 - morphness) + v1.x * morphness) * proportionbody.x,
6173 (v0.y * (1 - morphness) + v1.y * morphness) * proportionbody.y,
6174 (v0.z * (1 - morphness) + v1.z * morphness) * proportionbody.z);
6175 if (p1 == lefthand || p1 == righthand || p1 == leftwrist || p1 == rightwrist || p1 == leftelbow || p1 == rightelbow || p2 == leftelbow || p2 == rightelbow)
6176 glTranslatef((v0.x * (1 - morphness) + v1.x * morphness) * proportionarms.x,
6177 (v0.y * (1 - morphness) + v1.y * morphness) * proportionarms.y,
6178 (v0.z * (1 - morphness) + v1.z * morphness) * proportionarms.z);
6179 if (p1 == leftfoot || p1 == rightfoot || p1 == leftankle || p1 == rightankle || p1 == leftknee || p1 == rightknee || p2 == leftknee || p2 == rightknee)
6180 glTranslatef((v0.x * (1 - morphness) + v1.x * morphness) * proportionlegs.x,
6181 (v0.y * (1 - morphness) + v1.y * morphness) * proportionlegs.y,
6182 (v0.z * (1 - morphness) + v1.z * morphness) * proportionlegs.z);
6183 if (p1 == head || p2 == head)
6184 glTranslatef((v0.x * (1 - morphness) + v1.x * morphness) * proportionhead.x,
6185 (v0.y * (1 - morphness) + v1.y * morphness) * proportionhead.y,
6186 (v0.z * (1 - morphness) + v1.z * morphness) * proportionhead.z);
6187 glGetFloatv(GL_MODELVIEW_MATRIX, M);
6188 skeleton.drawmodel.vertex[skeleton.muscles[i].vertices[j]].x = M[12] * scale;
6189 skeleton.drawmodel.vertex[skeleton.muscles[i].vertices[j]].y = M[13] * scale;
6190 skeleton.drawmodel.vertex[skeleton.muscles[i].vertices[j]].z = M[14] * scale;
6194 if (!playerdetail || skeleton.free == 3) {
6195 for (unsigned j = 0; j < skeleton.muscles[i].verticeslow.size(); j++) {
6196 XYZ &v0 = skeleton.modellow.vertex[skeleton.muscles[i].verticeslow[j]];
6197 glMatrixMode(GL_MODELVIEW);
6199 if (p1 == abdomen || p2 == abdomen)
6200 glTranslatef(v0.x * proportionbody.x,
6201 v0.y * proportionbody.y,
6202 v0.z * proportionbody.z);
6203 if (p1 == lefthand || p1 == righthand || p1 == leftwrist || p1 == rightwrist || p1 == leftelbow || p1 == rightelbow || p2 == leftelbow || p2 == rightelbow)
6204 glTranslatef(v0.x * proportionarms.x,
6205 v0.y * proportionarms.y,
6206 v0.z * proportionarms.z);
6207 if (p1 == leftfoot || p1 == rightfoot || p1 == leftankle || p1 == rightankle || p1 == leftknee || p1 == rightknee || p2 == leftknee || p2 == rightknee)
6208 glTranslatef(v0.x * proportionlegs.x,
6209 v0.y * proportionlegs.y,
6210 v0.z * proportionlegs.z);
6211 if (p1 == head || p2 == head)
6212 glTranslatef(v0.x * proportionhead.x,
6213 v0.y * proportionhead.y,
6214 v0.z * proportionhead.z);
6216 glGetFloatv(GL_MODELVIEW_MATRIX, M);
6217 skeleton.drawmodellow.vertex[skeleton.muscles[i].verticeslow[j]].x = M[12] * scale;
6218 skeleton.drawmodellow.vertex[skeleton.muscles[i].verticeslow[j]].y = M[13] * scale;
6219 skeleton.drawmodellow.vertex[skeleton.muscles[i].verticeslow[j]].z = M[14] * scale;
6225 if (skeleton.clothes && skeleton.muscles[i].verticesclothes.size() > 0) {
6226 mid = (skeleton.muscles[i].parent1->position + skeleton.muscles[i].parent2->position) / 2;
6228 glMatrixMode(GL_MODELVIEW);
6232 glRotatef(tilt2, 1, 0, 0);
6234 glRotatef(tilt, 0, 0, 1);
6235 glTranslatef(mid.x, mid.y, mid.z);
6236 skeleton.muscles[i].lastrotate1 = skeleton.muscles[i].rotate1;
6237 glRotatef(-skeleton.muscles[i].lastrotate1 + 90, 0, 1, 0);
6239 skeleton.muscles[i].lastrotate2 = skeleton.muscles[i].rotate2;
6240 glRotatef(-skeleton.muscles[i].lastrotate2 + 90, 0, 0, 1);
6242 skeleton.muscles[i].lastrotate3 = skeleton.muscles[i].rotate3;
6243 glRotatef(-skeleton.muscles[i].lastrotate3, 0, 1, 0);
6245 for (unsigned j = 0; j < skeleton.muscles[i].verticesclothes.size(); j++) {
6246 XYZ &v0 = skeleton.modelclothes.vertex[skeleton.muscles[i].verticesclothes[j]];
6247 glMatrixMode(GL_MODELVIEW);
6249 if (p1 == abdomen || p2 == abdomen)
6250 glTranslatef(v0.x * proportionbody.x,
6251 v0.y * proportionbody.y,
6252 v0.z * proportionbody.z);
6253 if (p1 == lefthand || p1 == righthand || p1 == leftwrist || p1 == rightwrist || p1 == leftelbow || p1 == rightelbow || p2 == leftelbow || p2 == rightelbow)
6254 glTranslatef(v0.x * proportionarms.x,
6255 v0.y * proportionarms.y,
6256 v0.z * proportionarms.z);
6257 if (p1 == leftfoot || p1 == rightfoot || p1 == leftankle || p1 == rightankle || p1 == leftknee || p1 == rightknee || p2 == leftknee || p2 == rightknee)
6258 glTranslatef(v0.x * proportionlegs.x,
6259 v0.y * proportionlegs.y,
6260 v0.z * proportionlegs.z);
6261 if (p1 == head || p2 == head)
6262 glTranslatef(v0.x * proportionhead.x,
6263 v0.y * proportionhead.y,
6264 v0.z * proportionhead.z);
6265 glGetFloatv(GL_MODELVIEW_MATRIX, M);
6266 skeleton.drawmodelclothes.vertex[skeleton.muscles[i].verticesclothes[j]].x = M[12] * scale;
6267 skeleton.drawmodelclothes.vertex[skeleton.muscles[i].verticesclothes[j]].y = M[13] * scale;
6268 skeleton.drawmodelclothes.vertex[skeleton.muscles[i].verticesclothes[j]].z = M[14] * scale;
6273 updatedelay = 1 + (float)(Random() % 100) / 1000;
6275 if (skeleton.free != 2 && (skeleton.free == 1 || skeleton.free == 3 || id == 0 || (normalsupdatedelay <= 0) || animTarget == getupfromfrontanim || animTarget == getupfrombackanim || animCurrent == getupfromfrontanim || animCurrent == getupfrombackanim)) {
6276 normalsupdatedelay = 1;
6277 if (playerdetail || skeleton.free == 3)
6278 skeleton.drawmodel.CalculateNormals(0);
6279 if (!playerdetail || skeleton.free == 3)
6280 skeleton.drawmodellow.CalculateNormals(0);
6281 if (skeleton.clothes)
6282 skeleton.drawmodelclothes.CalculateNormals(0);
6284 if (playerdetail || skeleton.free == 3)
6285 skeleton.drawmodel.UpdateVertexArrayNoTexNoNorm();
6286 if (!playerdetail || skeleton.free == 3)
6287 skeleton.drawmodellow.UpdateVertexArrayNoTexNoNorm();
6288 if (skeleton.clothes) {
6289 skeleton.drawmodelclothes.UpdateVertexArrayNoTexNoNorm();
6294 updatedelaychange = -framemult * 4 * (45 - findDistance(&viewer, &coords) * 1);
6295 if (updatedelaychange > -realmultiplier * 30)
6296 updatedelaychange = -realmultiplier * 30;
6297 if (updatedelaychange > -framemult * 4)
6298 updatedelaychange = -framemult * 4;
6299 if (skeleton.free == 1)
6300 updatedelaychange *= 6;
6302 updatedelaychange *= 8;
6303 updatedelay += updatedelaychange;
6305 glMatrixMode(GL_MODELVIEW);
6307 glTranslatef(coords.x, coords.y - .02, coords.z);
6308 if (!skeleton.free) {
6309 glTranslatef(offset.x * scale, offset.y * scale, offset.z * scale);
6310 glRotatef(yaw, 0, 1, 0);
6314 glColor4f(.4, 1, .4, 1);
6315 glDisable(GL_LIGHTING);
6316 glDisable(GL_TEXTURE_2D);
6319 for (i = 0; i < skeleton.drawmodel.vertexNum; i++) {
6320 XYZ &v0 = skeleton.drawmodel.vertex[i];
6321 glVertex3f(v0.x, v0.y, v0.z);
6327 for (i = 0; i < skeleton.drawmodel.TriangleNum; i++) {
6328 XYZ &v0 = skeleton.drawmodel.vertex[skeleton.drawmodel.Triangles[i].vertex[0]];
6329 XYZ &v1 = skeleton.drawmodel.vertex[skeleton.drawmodel.Triangles[i].vertex[1]];
6330 XYZ &v2 = skeleton.drawmodel.vertex[skeleton.drawmodel.Triangles[i].vertex[2]];
6331 glVertex3f(v0.x, v0.y, v0.z);
6332 glVertex3f(v1.x, v1.y, v1.z);
6333 glVertex3f(v1.x, v1.y, v1.z);
6334 glVertex3f(v2.x, v2.y, v2.z);
6335 glVertex3f(v2.x, v2.y, v2.z);
6336 glVertex3f(v0.x, v0.y, v0.z);
6342 terrainlight = terrain.getLighting(coords.x, coords.z);
6343 distance = distsq(&viewer, &coords);
6344 distance = (viewdistance * viewdistance - (distance - (viewdistance * viewdistance * fadestart)) * (1 / (1 - fadestart))) / viewdistance / viewdistance;
6348 terrainheight = (coords.y - terrain.getHeight(coords.x, coords.z)) / 3 + 1;
6349 if (terrainheight < 1)
6351 if (terrainheight > 1.7)
6352 terrainheight = 1.7;
6354 glColor4f((1 - (1 - terrainlight.x) / terrainheight) - burnt, (1 - (1 - terrainlight.y) / terrainheight) - burnt, (1 - (1 - terrainlight.z) / terrainheight) - burnt, distance);
6355 glDisable(GL_BLEND);
6356 glAlphaFunc(GL_GREATER, 0.0001);
6357 glEnable(GL_TEXTURE_2D);
6359 glDisable(GL_TEXTURE_2D);
6360 glColor4f(.7, .35, 0, .5);
6362 glEnable(GL_LIGHTING);
6365 if (Tutorial::active && id != 0) {
6366 glColor4f(.7, .7, .7, 0.6);
6368 glEnable(GL_LIGHTING);
6370 if (canattack && cananger)
6371 if (Animation::animations[animTarget].attack == normalattack || Animation::animations[animTarget].attack == reversed) {
6372 glDisable(GL_TEXTURE_2D);
6373 glColor4f(1, 0, 0, 0.8);
6375 glMatrixMode(GL_TEXTURE);
6377 glTranslatef(0, -smoketex, 0);
6378 glTranslatef(-smoketex, 0, 0);
6382 if (Tutorial::active && (id != 0))
6383 skeleton.drawmodel.drawdifftex(Sprite::cloudimpacttexture);
6385 skeleton.drawmodel.draw();
6388 if (!playerdetail) {
6389 if (Tutorial::active && (id != 0))
6390 skeleton.drawmodellow.drawdifftex(Sprite::cloudimpacttexture);
6392 skeleton.drawmodellow.drawdifftex(skeleton.drawmodel.textureptr);
6395 if (!(Animation::animations[animTarget].attack == normalattack || Animation::animations[animTarget].attack == reversed))
6396 if (Tutorial::active && id != 0) {
6398 glMatrixMode(GL_MODELVIEW);
6399 glEnable(GL_TEXTURE_2D);
6400 glColor4f(.7, .7, .7, 0.6);
6402 glEnable(GL_LIGHTING);
6404 if (canattack && cananger)
6405 if (Animation::animations[animTarget].attack == normalattack || Animation::animations[animTarget].attack == reversed) {
6406 glDisable(GL_TEXTURE_2D);
6407 glColor4f(1, 0, 0, 0.8);
6409 glMatrixMode(GL_TEXTURE);
6411 glTranslatef(0, -smoketex * .6, 0);
6412 glTranslatef(smoketex * .6, 0, 0);
6415 if (Tutorial::active && (id != 0))
6416 skeleton.drawmodel.drawdifftex(Sprite::cloudimpacttexture);
6418 skeleton.drawmodel.draw();
6421 if (!playerdetail) {
6422 if (Tutorial::active && (id != 0))
6423 skeleton.drawmodellow.drawdifftex(Sprite::cloudimpacttexture);
6425 skeleton.drawmodellow.drawdifftex(skeleton.drawmodel.textureptr);
6430 if (Tutorial::active && id != 0) {
6432 glMatrixMode(GL_MODELVIEW);
6433 glEnable(GL_TEXTURE_2D);
6435 if (skeleton.clothes) {
6439 skeleton.drawmodelclothes.draw();
6441 skeleton.drawmodelclothes.drawimmediate();
6447 if (num_weapons > 0) {
6448 for (k = 0; k < num_weapons; k++) {
6450 if (weaponactive == k) {
6451 if (weapons[i].getType() != staff) {
6452 for (unsigned j = 0; j < skeleton.muscles.size(); j++) {
6453 if ((skeleton.muscles[j].parent1->label == righthand || skeleton.muscles[j].parent2->label == righthand) && skeleton.muscles[j].vertices.size() > 0) {
6454 weaponattachmuscle = j;
6457 for (unsigned j = 0; j < skeleton.muscles.size(); j++) {
6458 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].vertices.size() > 0) {
6459 weaponrotatemuscle = j;
6462 weaponpoint = (skeleton.muscles[weaponattachmuscle].parent1->position + skeleton.muscles[weaponattachmuscle].parent2->position) / 2;
6463 if (creature == wolftype)
6464 weaponpoint = (jointPos(rightwrist) * .7 + jointPos(righthand) * .3);
6466 if (weapons[i].getType() == staff) {
6467 for (unsigned j = 0; j < skeleton.muscles.size(); j++) {
6468 if ((skeleton.muscles[j].parent1->label == righthand || skeleton.muscles[j].parent2->label == righthand) && skeleton.muscles[j].vertices.size() > 0) {
6469 weaponattachmuscle = j;
6472 for (unsigned j = 0; j < skeleton.muscles.size(); j++) {
6473 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].vertices.size() > 0) {
6474 weaponrotatemuscle = j;
6477 //weaponpoint=jointPos(rightwrist);
6478 weaponpoint = (skeleton.muscles[weaponattachmuscle].parent1->position + skeleton.muscles[weaponattachmuscle].parent2->position) / 2;
6479 //weaponpoint+=skeleton.specialforward[1]*.1+(jointPos(rightwrist)-jointPos(rightelbow));
6480 XYZ tempnormthing, vec1, vec2;
6481 vec1 = (jointPos(rightwrist) - jointPos(rightelbow));
6482 vec2 = (jointPos(rightwrist) - jointPos(rightshoulder));
6483 CrossProduct(&vec1, &vec2, &tempnormthing);
6484 Normalise(&tempnormthing);
6485 if (animTarget != staffhitanim && animCurrent != staffhitanim && animTarget != staffgroundsmashanim && animCurrent != staffgroundsmashanim && animTarget != staffspinhitanim && animCurrent != staffspinhitanim)
6486 weaponpoint += tempnormthing * .1 - skeleton.specialforward[1] * .3 + (jointPos(rightwrist) - jointPos(rightelbow));
6489 if (weaponactive != k && weaponstuck != k) {
6490 if (weapons[i].getType() == knife)
6491 weaponpoint = jointPos(abdomen) + (jointPos(righthip) - jointPos(lefthip)) * .1 + (jointPos(rightshoulder) - jointPos(leftshoulder)) * .35;
6492 if (weapons[i].getType() == sword)
6493 weaponpoint = jointPos(abdomen) + (jointPos(lefthip) - jointPos(righthip)) * .09 + (jointPos(leftshoulder) - jointPos(rightshoulder)) * .33;
6494 if (weapons[i].getType() == staff)
6495 weaponpoint = jointPos(abdomen) + (jointPos(lefthip) - jointPos(righthip)) * .09 + (jointPos(leftshoulder) - jointPos(rightshoulder)) * .33;
6496 for (unsigned j = 0; j < skeleton.muscles.size(); j++) {
6497 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].vertices.size() > 0) {
6498 weaponrotatemuscle = j;
6502 if (weaponstuck == k) {
6503 if (weaponstuckwhere == 0)
6504 weaponpoint = jointPos(abdomen) * .5 + jointPos(neck) * .5 - skeleton.forward * .8;
6506 weaponpoint = jointPos(abdomen) * .5 + jointPos(neck) * .5 + skeleton.forward * .8;
6507 for (unsigned j = 0; j < skeleton.muscles.size(); j++) {
6508 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].vertices.size() > 0) {
6509 weaponrotatemuscle = j;
6513 if (skeleton.free) {
6514 weapons[i].position = weaponpoint * scale + coords;
6515 weapons[i].bigrotation = 0;
6516 weapons[i].bigtilt = 0;
6517 weapons[i].bigtilt2 = 0;
6519 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;
6520 weapons[i].bigrotation = yaw;
6521 weapons[i].bigtilt = tilt;
6522 weapons[i].bigtilt2 = tilt2;
6524 weapons[i].rotation1 = skeleton.muscles[weaponrotatemuscle].lastrotate1;
6525 weapons[i].rotation2 = skeleton.muscles[weaponrotatemuscle].lastrotate2;
6526 weapons[i].rotation3 = skeleton.muscles[weaponrotatemuscle].lastrotate3;
6527 if (weaponactive == k) {
6528 if (weapons[i].getType() == knife) {
6529 weapons[i].smallrotation = 180;
6530 weapons[i].smallrotation2 = 0;
6531 if (isCrouch() || wasCrouch()) {
6532 weapons[i].smallrotation2 = 20;
6534 if (animTarget == hurtidleanim) {
6535 weapons[i].smallrotation2 = 50;
6537 if ((animCurrent == crouchstabanim && animTarget == crouchstabanim) || (animCurrent == backhandspringanim && animTarget == backhandspringanim)) {
6538 XYZ temppoint1, temppoint2;
6541 temppoint1 = jointPos(righthand);
6542 temppoint2 = currentFrame().weapontarget * (1 - target) + targetFrame().weapontarget * (target);
6543 distance = findDistance(&temppoint1, &temppoint2);
6544 weapons[i].rotation2 = asin((temppoint1.y - temppoint2.y) / distance);
6545 weapons[i].rotation2 *= 360 / 6.28;
6548 weapons[i].rotation1 = acos((temppoint1.z - temppoint2.z) / findDistance(&temppoint1, &temppoint2));
6549 weapons[i].rotation1 *= 360 / 6.28;
6550 weapons[i].rotation3 = 0;
6551 weapons[i].smallrotation = -90;
6552 weapons[i].smallrotation2 = 0;
6553 if (temppoint1.x > temppoint2.x)
6554 weapons[i].rotation1 = 360 - weapons[i].rotation1;
6556 if ((animCurrent == knifeslashreversalanim && animTarget == knifeslashreversalanim) || (animCurrent == knifeslashreversedanim && animTarget == knifeslashreversedanim)) {
6557 XYZ temppoint1, temppoint2;
6560 temppoint1 = jointPos(righthand);
6561 temppoint2 = currentFrame().weapontarget * (1 - target) + targetFrame().weapontarget * (target);
6562 distance = findDistance(&temppoint1, &temppoint2);
6563 weapons[i].rotation2 = asin((temppoint1.y - temppoint2.y) / distance);
6564 weapons[i].rotation2 *= 360 / 6.28;
6567 weapons[i].rotation1 = acos((temppoint1.z - temppoint2.z) / findDistance(&temppoint1, &temppoint2));
6568 weapons[i].rotation1 *= 360 / 6.28;
6569 weapons[i].rotation3 = 0;
6570 weapons[i].smallrotation = 90;
6571 weapons[i].smallrotation2 = 0;
6572 if (temppoint1.x > temppoint2.x)
6573 weapons[i].rotation1 = 360 - weapons[i].rotation1;
6575 if (animTarget == knifethrowanim) {
6576 weapons[i].smallrotation = 90;
6577 //weapons[i].smallrotation2=-90;
6578 weapons[i].smallrotation2 = 0;
6579 weapons[i].rotation1 = 0;
6580 weapons[i].rotation2 = 0;
6581 weapons[i].rotation3 = 0;
6583 if (animTarget == knifesneakattackanim && frameTarget < 5) {
6584 weapons[i].smallrotation = -90;
6585 weapons[i].rotation1 = 0;
6586 weapons[i].rotation2 = 0;
6587 weapons[i].rotation3 = 0;
6590 if (weapons[i].getType() == sword) {
6591 weapons[i].smallrotation = 0;
6592 weapons[i].smallrotation2 = 0;
6593 if (animTarget == knifethrowanim) {
6594 weapons[i].smallrotation = -90;
6595 weapons[i].smallrotation2 = 0;
6596 weapons[i].rotation1 = 0;
6597 weapons[i].rotation2 = 0;
6598 weapons[i].rotation3 = 0;
6600 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)) {
6601 XYZ temppoint1, temppoint2;
6604 temppoint1 = currentFrame().joints[skeleton.jointlabels[righthand]].position * (1 - target) + targetFrame().joints[skeleton.jointlabels[righthand]].position * (target); //jointPos(righthand);
6605 temppoint2 = currentFrame().weapontarget * (1 - target) + targetFrame().weapontarget * (target);
6606 distance = findDistance(&temppoint1, &temppoint2);
6607 weapons[i].rotation2 = asin((temppoint1.y - temppoint2.y) / distance);
6608 weapons[i].rotation2 *= 360 / 6.28;
6611 weapons[i].rotation1 = acos((temppoint1.z - temppoint2.z) / findDistance(&temppoint1, &temppoint2));
6612 weapons[i].rotation1 *= 360 / 6.28;
6613 weapons[i].rotation3 = 0;
6614 weapons[i].smallrotation = 90;
6615 weapons[i].smallrotation2 = 0;
6616 if (temppoint1.x > temppoint2.x)
6617 weapons[i].rotation1 = 360 - weapons[i].rotation1;
6620 if (weapons[i].getType() == staff) {
6621 weapons[i].smallrotation = 100;
6622 weapons[i].smallrotation2 = 0;
6623 if ((animTarget == staffhitanim && animCurrent == staffhitanim) || (animTarget == staffhitreversedanim && animCurrent == staffhitreversedanim) || (animTarget == staffspinhitreversedanim && animCurrent == staffspinhitreversedanim) || (animTarget == staffgroundsmashanim && animCurrent == staffgroundsmashanim) || (animTarget == staffspinhitanim && animCurrent == staffspinhitanim)) {
6624 XYZ temppoint1, temppoint2;
6627 temppoint1 = currentFrame().joints[skeleton.jointlabels[righthand]].position * (1 - target) + targetFrame().joints[skeleton.jointlabels[righthand]].position * (target); //jointPos(righthand);
6628 temppoint2 = currentFrame().weapontarget * (1 - target) + targetFrame().weapontarget * (target);
6629 distance = findDistance(&temppoint1, &temppoint2);
6630 weapons[i].rotation2 = asin((temppoint1.y - temppoint2.y) / distance);
6631 weapons[i].rotation2 *= 360 / 6.28;
6634 weapons[i].rotation1 = acos((temppoint1.z - temppoint2.z) / findDistance(&temppoint1, &temppoint2));
6635 weapons[i].rotation1 *= 360 / 6.28;
6636 weapons[i].rotation3 = 0;
6637 weapons[i].smallrotation = 90;
6638 weapons[i].smallrotation2 = 0;
6639 if (temppoint1.x > temppoint2.x)
6640 weapons[i].rotation1 = 360 - weapons[i].rotation1;
6644 if (weaponactive != k && weaponstuck != k) {
6645 if (weapons[i].getType() == knife) {
6646 weapons[i].smallrotation = -70;
6647 weapons[i].smallrotation2 = 10;
6649 if (weapons[i].getType() == sword) {
6650 weapons[i].smallrotation = -100;
6651 weapons[i].smallrotation2 = -8;
6653 if (weapons[i].getType() == staff) {
6654 weapons[i].smallrotation = -100;
6655 weapons[i].smallrotation2 = -8;
6658 if (weaponstuck == k) {
6659 if (weaponstuckwhere == 0)
6660 weapons[i].smallrotation = 180;
6662 weapons[i].smallrotation = 0;
6663 weapons[i].smallrotation2 = 10;
6672 if (Animation::animations[animTarget].attack || isRun() || animTarget == staggerbackhardanim || isFlip() || animTarget == climbanim || animTarget == sneakanim || animTarget == rollanim || animTarget == walkanim || animTarget == backhandspringanim || isWallJump())
6674 if (animCurrent != animTarget)
6676 if (skeleton.free == 2)
6685 int Person::SphereCheck(XYZ *p1, float radius, XYZ *p, XYZ *move, float *rotate, Model *model)
6688 static float distance;
6689 static float olddistance;
6690 static int intersecting;
6691 static int firstintersecting;
6694 static XYZ start, end;
6695 static float slopethreshold = -.4;
6697 firstintersecting = -1;
6701 if (distsq(p1, &model->boundingspherecenter) > radius * radius + model->boundingsphereradius * model->boundingsphereradius)
6704 *p1 = DoRotation(*p1, 0, -*rotate, 0);
6705 for (i = 0; i < 4; i++) {
6706 for (j = 0; j < model->TriangleNum; j++) {
6707 if (model->facenormals[j].y <= slopethreshold) {
6709 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)));
6710 if (distance < radius) {
6711 point = *p1 - model->facenormals[j] * distance;
6712 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]]))
6715 intersecting = sphere_line_intersection(&model->vertex[model->Triangles[j].vertex[0]],
6716 &model->vertex[model->Triangles[j].vertex[1]],
6719 intersecting = sphere_line_intersection(&model->vertex[model->Triangles[j].vertex[1]],
6720 &model->vertex[model->Triangles[j].vertex[2]],
6723 intersecting = sphere_line_intersection(&model->vertex[model->Triangles[j].vertex[0]],
6724 &model->vertex[model->Triangles[j].vertex[2]],
6727 if (dotproduct(&model->facenormals[j], &end) > 0 && intersecting) {
6731 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)) {
6732 p1->y = point.y + radius;
6733 if ((animTarget == jumpdownanim || isFlip())) {
6734 if (isFlip() && (frameTarget < 5 || targetFrame().label == 7 || targetFrame().label == 4))
6737 if (animTarget == jumpupanim) {
6739 animTarget = getIdle();
6746 pause_sound(whooshsound);
6747 OPENAL_SetVolume(channels[whooshsound], 0);
6750 if ((animTarget == jumpdownanim || isFlip()) && !wasLanding() && !wasLandhard()) {
6753 animTarget = getLanding();
6754 emit_sound_at(landsound, coords, 128.);
6757 addEnvSound(coords);
6764 if ((distance < olddistance || firstintersecting == -1) && intersecting) {
6765 olddistance = distance;
6766 firstintersecting = j;
6771 for (j = 0; j < model->TriangleNum; j++) {
6772 if (model->facenormals[j].y > slopethreshold) {
6775 start.y -= radius / 4;
6776 XYZ &v0 = model->vertex[model->Triangles[j].vertex[0]];
6777 XYZ &v1 = model->vertex[model->Triangles[j].vertex[1]];
6778 XYZ &v2 = model->vertex[model->Triangles[j].vertex[2]];
6779 distance = abs((model->facenormals[j].x * start.x)
6780 + (model->facenormals[j].y * start.y)
6781 + (model->facenormals[j].z * start.z)
6782 - ((model->facenormals[j].x * v0.x)
6783 + (model->facenormals[j].y * v0.y)
6784 + (model->facenormals[j].z * v0.z)));
6785 if (distance < radius * .5) {
6786 point = start - model->facenormals[j] * distance;
6787 if (PointInTriangle( &point, model->facenormals[j], &v0, &v1, &v2))
6790 intersecting = sphere_line_intersection(v0.x, v0.y, v0.z, v1.x, v1.y, v1.z, p1->x, p1->y, p1->z, radius / 2);
6792 intersecting = sphere_line_intersection(v1.x, v1.y, v1.z, v2.x, v2.y, v2.z, p1->x, p1->y, p1->z, radius / 2);
6794 intersecting = sphere_line_intersection(v0.x, v0.y, v0.z, v2.x, v2.y, v2.z, p1->x, p1->y, p1->z, radius / 2);
6796 if (dotproduct(&model->facenormals[j], &end) > 0 && intersecting) {
6797 if ((animTarget == jumpdownanim || animTarget == jumpupanim || isFlip())) {
6799 velocity -= DoRotation(model->facenormals[j], 0, *rotate, 0) * findLength(&velocity) * abs(normaldotproduct(velocity, DoRotation(model->facenormals[j], 0, *rotate, 0))); //(distance-radius*.5)/multiplier;
6800 if (findLengthfast(&start) < findLengthfast(&velocity))
6803 *p1 += model->facenormals[j] * (distance - radius * .5);
6806 if ((distance < olddistance || firstintersecting == -1) && intersecting) {
6807 olddistance = distance;
6808 firstintersecting = j;
6815 *p = DoRotation(*p, 0, *rotate, 0);
6818 *p1 = DoRotation(*p1, 0, *rotate, 0);
6820 return firstintersecting;
6823 void Person::takeWeapon(int weaponId)
6826 weapons[weaponId].owner = id;
6827 if (num_weapons > 0) {
6828 weaponids[num_weapons] = weaponids[0];
6831 weaponids[0] = weaponId;
6834 void Person::addClothes()
6836 if (numclothes > 0) {
6837 for (int i = 0; i < numclothes; i++) {
6844 bool Person::addClothes(const int& clothesId)
6847 const std::string fileName = clothes[clothesId];
6849 GLubyte* array = &skeleton.skinText[0];
6853 bool opened = load_image(Folders::getResourcePath(fileName).c_str(), texture);
6858 float tintr = clothestintr[clothesId];
6859 float tintg = clothestintg[clothesId];
6860 float tintb = clothestintb[clothesId];
6862 if (tintr > 1) tintr = 1;
6863 if (tintg > 1) tintg = 1;
6864 if (tintb > 1) tintb = 1;
6866 if (tintr < 0) tintr = 0;
6867 if (tintg < 0) tintg = 0;
6868 if (tintb < 0) tintb = 0;
6870 int bytesPerPixel = texture.bpp / 8;
6874 for (int i = 0; i < (int)(texture.sizeY * texture.sizeX * bytesPerPixel); i++) {
6875 if (bytesPerPixel == 3)
6877 else if ((i + 1) % 4 == 0)
6878 alphanum = texture.data[i];
6879 if ((i + 1) % 4 || bytesPerPixel == 3) {
6881 texture.data[i] *= tintr;
6883 texture.data[i] *= tintg;
6885 texture.data[i] *= tintb;
6886 array[tempnum] = (float)array[tempnum] * (1 - alphanum / 255) + (float)texture.data[i] * (alphanum / 255);