2 Copyright (C) 2003, 2010 - Wolfire Games
4 This file is part of Lugaru.
6 Lugaru is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 2 of the License, or
9 (at your option) any later version.
11 Lugaru is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
16 You should have received a copy of the GNU General Public License
17 along with Lugaru. If not, see <http://www.gnu.org/licenses/>.
20 /**> HEADER FILES <**/
22 #include "openal_wrapper.h"
23 #include "Animation.h"
28 extern float multiplier;
29 extern Terrain terrain;
31 extern int environment;
33 extern FRUSTUM frustum;
35 extern float realmultiplier;
37 extern float slomodelay;
38 extern bool cellophane;
39 extern float texdetail;
40 extern float realtexdetail;
41 extern GLubyte bloodText[512 * 512 * 3];
42 extern GLubyte wolfbloodText[512 * 512 * 3];
43 extern int bloodtoggle;
44 extern Objects objects;
46 extern bool autoslomo;
47 extern float camerashake;
49 extern float viewdistance;
50 extern float blackout;
51 extern int difficulty;
53 extern float fadestart;
55 extern bool winfreeze;
56 extern float flashamount, flashr, flashg, flashb;
57 extern int flashdelay;
58 extern bool showpoints;
59 extern bool immediate;
61 extern bool tilt2weird;
62 extern bool tiltweird;
64 extern bool proportionweird;
65 extern bool vertexweird[6];
66 extern XYZ envsound[30];
67 extern float envsoundvol[30];
68 extern float envsoundlife[30];
69 extern int numenvsounds;
70 extern int tutoriallevel;
71 extern float smoketex;
72 extern int tutorialstage;
73 extern bool reversaltrain;
74 extern bool canattack;
76 extern float damagedealt;
78 extern float hostiletime;
80 extern int indialogue;
82 extern bool gamestarted;
84 std::vector<std::shared_ptr<Person>> Person::players(1, std::shared_ptr<Person>(new Person()));
89 * GameTick/doPlayerCollisions
91 void Person::CheckKick()
94 && (animTarget == rabbitkickanim
96 && victim != this->shared_from_this()
98 && animCurrent == rabbitkickanim)
99 && distsq(&coords, &victim->coords) < 1.2
100 && !victim->skeleton.free))
103 if (animation[victim->animTarget].height != lowheight) {
104 float damagemult = (creature == wolftype ? 2.5 : 1.) * power * power;
105 XYZ relative = velocity;
107 Normalise(&relative);
111 if (tutoriallevel != 1)
112 emit_sound_at(heavyimpactsound, victim->coords);
114 for (int i = 0; i < victim->skeleton.num_joints; i++) {
115 victim->skeleton.joints[i].velocity += relative * 120 * damagemult;
118 victim->DoDamage(100 * damagemult / victim->protectionhigh);
124 animTarget = backflipanim;
126 velocity = facing * -10;
130 resume_stream(whooshsound);
132 award_bonus(id, cannon);
133 } else if (victim->isCrouch()) {
134 animTarget = rabbitkickreversedanim;
135 animCurrent = rabbitkickreversedanim;
136 victim->animCurrent = rabbitkickreversalanim;
137 victim->animTarget = rabbitkickreversalanim;
143 victim->oldcoords = victim->coords;
144 coords = victim->coords;
145 victim->targetyaw = targetyaw;
146 victim->victim = this->shared_from_this();
153 * GameTick/doPlayerCollisions - spread fire between players
154 * GameTick/doDebugKeys - press f to ignite
155 * Person::DoStuff - spread fire from lit campfires and bushes
157 void Person::CatchFire()
159 XYZ flatfacing, flatvelocity;
161 for (int i = 0; i < 10; i++) {
162 howmany = abs(Random() % (skeleton.num_joints));
164 flatvelocity = velocity;
166 flatvelocity = skeleton.joints[howmany].velocity;
168 flatfacing = DoRotation(DoRotation(DoRotation(skeleton.joints[howmany].position, 0, 0, tilt), tilt2, 0, 0), 0, yaw, 0) * scale + coords;
170 flatfacing = skeleton.joints[howmany].position * scale + coords;
171 Sprite::MakeSprite(flamesprite, flatfacing, flatvelocity, 1, 1, 1, 2, 1);
176 emit_sound_at(firestartsound, coords);
178 emit_stream_at(stream_firesound, coords);
186 * idle animation for this creature (depending on status)
188 int Person::getIdle()
190 if (indialogue != -1 && howactive == typeactive && creature == rabbittype)
192 if (hasvictim && (victim != this->shared_from_this())/*||(id==0&&attackkeydown)*/)
193 if (/*(id==0&&attackkeydown)||*/(!victim->dead && victim->aitype != passivetype &&
194 victim->aitype != searchtype && aitype != passivetype && aitype != searchtype &&
195 victim->id < Person::players.size())) {
196 if ((aitype == playercontrolled && stunned <= 0 && weaponactive == -1) || pause) {
197 if (creature == rabbittype)
198 return fightidleanim;
199 if (creature == wolftype)
202 if (aitype == playercontrolled && stunned <= 0 && weaponactive != -1) {
203 if (weapons[weaponids[weaponactive]].getType() == knife)
204 return knifefightidleanim;
205 if (weapons[weaponids[weaponactive]].getType() == sword && victim->weaponactive != -1)
206 return swordfightidlebothanim;
207 if (weapons[weaponids[weaponactive]].getType() == sword)
208 return swordfightidleanim;
209 if (weapons[weaponids[weaponactive]].getType() == staff)
210 return swordfightidleanim;
212 if (aitype != playercontrolled && stunned <= 0 && creature != wolftype && !pause)
213 return fightsidestep;
215 if ((damage > permanentdamage || damage > damagetolerance * .8 || deathbleeding > 0) && creature != wolftype)
217 if (howactive == typesitting) return sitanim;
218 if (howactive == typesittingwall) return sitwallanim;
219 if (howactive == typesleeping) return sleepanim;
220 if (howactive == typedead1) return dead1anim;
221 if (howactive == typedead2) return dead2anim;
222 if (howactive == typedead3) return dead3anim;
223 if (howactive == typedead4) return dead4anim;
224 if (creature == rabbittype) return bounceidleanim;
225 if (creature == wolftype) return wolfidle;
230 * crouch animation for this creature
232 int Person::getCrouch()
234 if (creature == rabbittype)
236 if (creature == wolftype)
237 return wolfcrouchanim;
242 * running animation for this creature (can be upright or all fours)
246 if (creature == rabbittype && (!superruntoggle || weaponactive != -1))
248 if (creature == wolftype && (!superruntoggle))
251 if (creature == rabbittype && (superruntoggle && weaponactive == -1))
252 return rabbitrunninganim;
253 if (creature == wolftype && (superruntoggle))
254 return wolfrunninganim;
260 int Person::getStop()
262 if (creature == rabbittype)
264 if (creature == wolftype)
271 int Person::getLanding()
273 if (creature == rabbittype)
275 if (creature == wolftype)
282 int Person::getLandhard()
284 if (creature == rabbittype)
286 if (creature == wolftype)
287 return wolflandhardanim;
294 * Person::DoAnimations
297 SolidHitBonus(int playerid)
299 if (bonustime < 1.5 && bonus >= solidhit && bonus <= megacombo)
300 award_bonus(playerid, bonus == megacombo ? bonus : bonus + 1);
302 award_bonus(playerid, solidhit);
306 * spawns blood effects
308 void Person::DoBlood(float howmuch, int which)
310 // FIXME: should abstract out inputs
311 static int bleedxint, bleedyint;
313 //if(howmuch&&id==0)blooddimamount=1;
314 if (bloodtoggle && tutoriallevel != 1) {
315 if (bleeding <= 0 && spurt) {
317 for (int i = 0; i < 3; i++) {
318 // emit blood particles
320 if (!skeleton.free) {
322 bloodvel = DoRotation(bloodvel, ((float)(Random() % 100)) / 4, yaw + ((float)(Random() % 100)) / 4, 0) * scale;
325 bloodvel -= DoRotation(skeleton.forward * 10 * scale, ((float)(Random() % 100)) / 4, ((float)(Random() % 100)) / 4, 0);
328 bloodvel += DoRotation(jointVel(head), ((float)(Random() % 100)) / 4, yaw + ((float)(Random() % 100)) / 4, 0) * scale;
330 bloodvel += DoRotation(velocity, ((float)(Random() % 100)) / 4, ((float)(Random() % 100)) / 4, 0) * scale;
332 Sprite::MakeSprite(bloodsprite, jointPos(head) * scale + coords, bloodvel, 1, 1, 1, .05, 1);
333 Sprite::MakeSprite(bloodflamesprite, jointPos(head) * scale + coords, bloodvel, 1, 1, 1, .3, 1);
335 if (!skeleton.free) {
336 Sprite::MakeSprite(bloodsprite, DoRotation((jointPos(head) + jointPos(neck)) / 2, 0, yaw, 0)*scale + coords, bloodvel, 1, 1, 1, .05, 1);
337 Sprite::MakeSprite(bloodflamesprite, DoRotation((jointPos(head) + jointPos(neck)) / 2, 0, yaw, 0)*scale + coords, bloodvel, 1, 1, 1, .3, 1);
340 if (Random() % 2 == 0) // 50% chance
341 for (int i = 0; i < 3; i++) {
342 if (Random() % 2 != 0) {
343 // emit teeth particles
346 bloodvel -= DoRotation(skeleton.forward * 10 * scale, ((float)(Random() % 100)) / 4, ((float)(Random() % 100)) / 4, 0);
347 bloodvel += DoRotation(jointVel(head), ((float)(Random() % 100)) / 4, yaw + ((float)(Random() % 100)) / 4, 0) * scale;
350 bloodvel = DoRotation(bloodvel, ((float)(Random() % 100)) / 4, yaw + ((float)(Random() % 100)) / 4, 0) * scale;
351 bloodvel += DoRotation(velocity, ((float)(Random() % 100)) / 4, ((float)(Random() % 100)) / 4, 0) * scale;
355 Sprite::MakeSprite(splintersprite, jointPos(head) * scale + coords, bloodvel, 1, 1, 1, .05, 1);
357 Sprite::MakeSprite(splintersprite, DoRotation((jointPos(head) + jointPos(neck)) / 2, 0, yaw, 0)*scale + coords, bloodvel, 1, 1, 1, .05, 1);
359 Sprite::setLastSpriteSpecial(3); // sets it to teeth
364 // FIXME: manipulating attributes
365 bleeding = howmuch + (float)abs(Random() % 100) / 200 - .25;
368 if (creature == rabbittype)
369 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) {
370 bleedxint = abs(Random() % 512);
371 bleedyint = abs(Random() % 512);
373 if (creature == wolftype)
374 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) {
375 bleedxint = abs(Random() % 512);
376 bleedyint = abs(Random() % 512);
380 bleedy /= realtexdetail;
381 bleedx /= realtexdetail;
382 direction = abs(Random() % 2) * 2 - 1;
391 * spawns big blood effects and ???
392 * modifies character's skin texture
394 void Person::DoBloodBig(float howmuch, int which)
396 static int bleedxint, bleedyint, i, j;
398 if (howmuch && id == 0)
401 if (tutoriallevel != 1 || id == 0)
402 if (aitype != playercontrolled && howmuch > 0) {
406 // FIXME: seems to be spawning sounds by manipulating attributes... MESSY!
407 if (creature == wolftype) {
408 int i = abs(Random() % 2);
410 whichsound = snarlsound;
412 whichsound = snarl2sound;
413 envsound[numenvsounds] = coords;
414 envsoundvol[numenvsounds] = 16;
415 envsoundlife[numenvsounds] = .4;
418 if (creature == rabbittype) {
419 int i = abs(Random() % 2);
421 whichsound = rabbitpainsound;
422 if (i == 1 && howmuch >= 2)
423 whichsound = rabbitpain1sound;
424 envsound[numenvsounds] = coords;
425 envsoundvol[numenvsounds] = 16;
426 envsoundlife[numenvsounds] = .4;
428 //if(i==2)whichsound=rabbitpain2sound;
431 if (whichsound != -1)
432 emit_sound_at(whichsound, coords);
435 if (id == 0 && howmuch > 0) {
436 // FIXME: manipulating attributes
444 if (bloodtoggle && decals && tutoriallevel != 1) {
445 if (bleeding <= 0 && spurt) {
447 for (int i = 0; i < 3; i++) {
448 // emit blood particles
449 // FIXME: copypaste from above
451 if (!skeleton.free) {
453 bloodvel = DoRotation(bloodvel, ((float)(Random() % 100)) / 4, yaw + ((float)(Random() % 100)) / 4, 0) * scale;
456 bloodvel -= DoRotation(skeleton.forward * 10 * scale, ((float)(Random() % 100)) / 4, ((float)(Random() % 100)) / 4, 0);
459 bloodvel += DoRotation(jointVel(head), ((float)(Random() % 100)) / 4, yaw + ((float)(Random() % 100)) / 4, 0) * scale;
461 bloodvel += DoRotation(velocity, ((float)(Random() % 100)) / 4, ((float)(Random() % 100)) / 4, 0) * scale;
463 Sprite::MakeSprite(bloodsprite, jointPos(head) * scale + coords, bloodvel, 1, 1, 1, .05, 1);
464 Sprite::MakeSprite(bloodflamesprite, jointPos(head) * scale + coords, bloodvel, 1, 1, 1, .3, 1);
466 if (!skeleton.free) {
467 Sprite::MakeSprite(bloodsprite, DoRotation((jointPos(head) + jointPos(neck)) / 2, 0, yaw, 0)*scale + coords, bloodvel, 1, 1, 1, .05, 1);
468 Sprite::MakeSprite(bloodflamesprite, DoRotation((jointPos(head) + jointPos(neck)) / 2, 0, yaw, 0)*scale + coords, bloodvel, 1, 1, 1, .3, 1);
473 // weird texture manipulation code follows.
474 // looks like this is painting blood onto the character's skin texture
475 // FIXME: surely there's a better way
477 int offsetx = 0, offsety = 0;
479 offsety = Random() % 40;
480 offsetx = abs(Random() % 60);
482 if (which == 190 || which == 185) {
483 offsety = Random() % 40;
484 offsetx = abs(Random() % 100) - 20;
487 offsety = Random() % 10;
488 offsetx = Random() % 10;
491 offsety = Random() % 20;
492 offsetx = Random() % 20;
494 if (which == 220 || which == 215) {
504 if (creature == rabbittype)
505 for (i = 0; i < 512; i++) {
506 for (j = 0; j < 512; j++) {
507 if (bloodText[i * 512 * 3 + j * 3 + 0] <= which + 4 && bloodText[i * 512 * 3 + j * 3 + 0] >= which - 4) {
508 if (i < startx) startx = i;
509 if (j < starty) starty = j;
510 if (i > endx) endx = i;
511 if (j > endy) endy = j;
515 if (creature == wolftype)
516 for (i = 0; i < 512; i++) {
517 for (j = 0; j < 512; j++) {
518 if (wolfbloodText[i * 512 * 3 + j * 3 + 0] <= which + 4 && wolfbloodText[i * 512 * 3 + j * 3 + 0] >= which - 4) {
519 if (i < startx) startx = i;
520 if (j < starty) starty = j;
521 if (i > endx) endx = i;
522 if (j > endy) endy = j;
532 if (startx < 0) startx = 0;
533 if (starty < 0) starty = 0;
534 if (endx > 512 - 1) endx = 512 - 1;
535 if (endy > 512 - 1) endy = 512 - 1;
536 if (endx < startx) endx = startx;
537 if (endy < starty) endy = starty;
539 startx /= realtexdetail;
540 starty /= realtexdetail;
541 endx /= realtexdetail;
542 endy /= realtexdetail;
544 int texdetailint = realtexdetail;
546 if (creature == rabbittype)
547 for (i = startx; i < endx; i++) {
548 for (j = starty; j < endy; j++) {
549 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) {
550 color = Random() % 85 + 170;
551 where = i * skeleton.skinsize * 3 + j * 3;
552 if (skeleton.skinText[where + 0] > color / 2)
553 skeleton.skinText[where + 0] = color / 2;
554 skeleton.skinText[where + 1] = 0;
555 skeleton.skinText[where + 2] = 0;
559 if (creature == wolftype)
560 for (i = startx; i < endx; i++) {
561 for (j = starty; j < endy; j++) {
562 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) {
563 color = Random() % 85 + 170;
564 where = i * skeleton.skinsize * 3 + j * 3;
565 if (skeleton.skinText[where + 0] > color / 2)
566 skeleton.skinText[where + 0] = color / 2;
567 skeleton.skinText[where + 1] = 0;
568 skeleton.skinText[where + 2] = 0;
572 skeleton.drawmodel.textureptr.bind();
577 if (creature == rabbittype)
578 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) {
579 bleedxint = abs(Random() % 512);
580 bleedyint = abs(Random() % 512);
582 if (creature == wolftype)
583 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) {
584 bleedxint = abs(Random() % 512);
585 bleedyint = abs(Random() % 512);
587 bleedy = bleedxint + offsetx;
588 bleedx = bleedyint + offsety;
589 bleedy /= realtexdetail;
590 bleedx /= realtexdetail;
595 if (bleedx > skeleton.skinsize - 1)
596 bleedx = skeleton.skinsize - 1;
597 if (bleedy > skeleton.skinsize - 1)
598 bleedy = skeleton.skinsize - 1;
599 direction = abs(Random() % 2) * 2 - 1;
602 bleeding = howmuch + (float)abs(Random() % 100) / 200 - .25;
603 deathbleeding += bleeding;
604 bloodloss += bleeding * 3;
606 if (tutoriallevel != 1 && aitype != playercontrolled && bloodloss > damagetolerance * 2 / 3 && bloodloss < damagetolerance && creature == rabbittype) {
607 if (abs(Random() % 2) == 0) {
608 aitype = gethelptype;
611 aitype = attacktypecutoff;
619 * similar to DoBloodBig
621 bool Person::DoBloodBigWhere(float howmuch, int which, XYZ where)
625 static XYZ startpoint, endpoint, colpoint, movepoint;
626 static float rotationpoint;
628 static XYZ p1, p2, p3, p0;
632 float coordsx, coordsy;
635 if (bloodtoggle && decals && tutoriallevel != 1) {
638 where = DoRotation(where, 0, -yaw, 0);
646 // ray testing for a tri in the character model
647 whichtri = skeleton.drawmodel.LineCheck(&startpoint, &endpoint, &colpoint, &movepoint, &rotationpoint);
648 if (whichtri != -1) {
649 // low level geometry math
651 p1 = skeleton.drawmodel.vertex[skeleton.drawmodel.Triangles[whichtri].vertex[0]];
652 p2 = skeleton.drawmodel.vertex[skeleton.drawmodel.Triangles[whichtri].vertex[1]];
653 p3 = skeleton.drawmodel.vertex[skeleton.drawmodel.Triangles[whichtri].vertex[2]];
655 CrossProduct(p2-p1,p3-p1,&N);
656 CrossProduct(p0-p1,p3-p1,&temp);
657 s = dotproduct(&temp,&N)/findLength(&N);
658 CrossProduct(p2-p1,p1-p0,&temp);
659 t = dotproduct(&temp,&N)/findLength(&N);
662 bary.x = distsq(&p0, &p1);
663 bary.y = distsq(&p0, &p2);
664 bary.z = distsq(&p0, &p3);
666 total = bary.x + bary.y + bary.z;
675 total = bary.x + bary.y + bary.z;
681 gxx.x = skeleton.drawmodel.Triangles[whichtri].gx[0];
682 gxx.y = skeleton.drawmodel.Triangles[whichtri].gx[1];
683 gxx.z = skeleton.drawmodel.Triangles[whichtri].gx[2];
684 gyy.x = skeleton.drawmodel.Triangles[whichtri].gy[0];
685 gyy.y = skeleton.drawmodel.Triangles[whichtri].gy[1];
686 gyy.z = skeleton.drawmodel.Triangles[whichtri].gy[2];
687 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;
688 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;
690 //coordsx=skeleton.drawmodel.Triangles[whichtri].gx[1];
691 //coordsy=skeleton.drawmodel.Triangles[whichtri].gy[1];
693 if (bleeding <= 0 && spurt) {
695 for (int i = 0; i < 3; i++) {
696 // emit blood particles
697 // FIXME: more copypaste code
699 if (!skeleton.free) {
701 bloodvel = DoRotation(bloodvel, ((float)(Random() % 100)) / 4, yaw + ((float)(Random() % 100)) / 4, 0) * scale;
704 bloodvel -= DoRotation(skeleton.forward * 10 * scale, ((float)(Random() % 100)) / 4, ((float)(Random() % 100)) / 4, 0);
707 bloodvel += DoRotation(jointVel(head), ((float)(Random() % 100)) / 4, yaw + ((float)(Random() % 100)) / 4, 0) * scale;
709 bloodvel += DoRotation(velocity, ((float)(Random() % 100)) / 4, ((float)(Random() % 100)) / 4, 0) * scale;
711 Sprite::MakeSprite(bloodsprite, jointPos(head) * scale + coords, bloodvel, 1, 1, 1, .05, 1);
712 Sprite::MakeSprite(bloodflamesprite, jointPos(head) * scale + coords, bloodvel, 1, 1, 1, .3, 1);
714 if (!skeleton.free) {
715 Sprite::MakeSprite(bloodsprite, DoRotation((jointPos(head) + jointPos(neck)) / 2, 0, yaw, 0)*scale + coords, bloodvel, 1, 1, 1, .05, 1);
716 Sprite::MakeSprite(bloodflamesprite, DoRotation((jointPos(head) + jointPos(neck)) / 2, 0, yaw, 0)*scale + coords, bloodvel, 1, 1, 1, .3, 1);
721 // texture manipulation follows
723 int offsetx = 0, offsety = 0;
726 offsetx=abs(Random()%120);
728 if(which==220||which==215){
730 offsetx=abs(Random()%80);
733 offsetx = (1 + coordsy) * 512 - 291;
734 offsety = coordsx * 512 - 437;
741 if (creature == rabbittype)
742 for (i = 0; i < 512; i++) {
743 for (j = 0; j < 512; j++) {
744 if (bloodText[i * 512 * 3 + j * 3 + 0] <= which + 4 && bloodText[i * 512 * 3 + j * 3 + 0] >= which - 4) {
745 if (i < startx) startx = i;
746 if (j < starty) starty = j;
747 if (i > endx) endx = i;
748 if (j > endy) endy = j;
752 if (creature == wolftype)
753 for (i = 0; i < 512; i++) {
754 for (j = 0; j < 512; j++) {
755 if (wolfbloodText[i * 512 * 3 + j * 3 + 0] <= which + 4 && wolfbloodText[i * 512 * 3 + j * 3 + 0] >= which - 4) {
756 if (i < startx) startx = i;
757 if (j < starty) starty = j;
758 if (i > endx) endx = i;
759 if (j > endy) endy = j;
768 if (startx < 0) startx = 0;
769 if (starty < 0) starty = 0;
770 if (endx > 512 - 1) endx = 512 - 1;
771 if (endy > 512 - 1) endy = 512 - 1;
772 if (endx < startx) endx = startx;
773 if (endy < starty) endy = starty;
775 startx /= realtexdetail;
776 starty /= realtexdetail;
777 endx /= realtexdetail;
778 endy /= realtexdetail;
780 int texdetailint = realtexdetail;
782 if (creature == rabbittype)
783 for (i = startx; i < endx; i++) {
784 for (j = starty; j < endy; j++) {
785 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) {
786 color = Random() % 85 + 170;
787 where = i * skeleton.skinsize * 3 + j * 3;
788 if (skeleton.skinText[where + 0] > color / 2)
789 skeleton.skinText[where + 0] = color / 2;
790 skeleton.skinText[where + 1] = 0;
791 skeleton.skinText[where + 2] = 0;
792 } 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) {
793 color = Random() % 85 + 170;
794 where = i * skeleton.skinsize * 3 + j * 3;
795 if (skeleton.skinText[where + 0] > color / 2)
796 skeleton.skinText[where + 0] = color / 2;
797 skeleton.skinText[where + 1] = 0;
798 skeleton.skinText[where + 2] = 0;
802 if (creature == wolftype)
803 for (i = startx; i < endx; i++) {
804 for (j = starty; j < endy; j++) {
805 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) {
806 color = Random() % 85 + 170;
807 where = i * skeleton.skinsize * 3 + j * 3;
808 if (skeleton.skinText[where + 0] > color / 2)
809 skeleton.skinText[where + 0] = color / 2;
810 skeleton.skinText[where + 1] = 0;
811 skeleton.skinText[where + 2] = 0;
812 } 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) {
813 color = Random() % 85 + 170;
814 where = i * skeleton.skinsize * 3 + j * 3;
815 if (skeleton.skinText[where + 0] > color / 2)
816 skeleton.skinText[where + 0] = color / 2;
817 skeleton.skinText[where + 1] = 0;
818 skeleton.skinText[where + 2] = 0;
822 skeleton.drawmodel.textureptr.bind();
825 bleedy = (1 + coordsy) * 512;
826 bleedx = coordsx * 512;
827 bleedy /= realtexdetail;
828 bleedx /= realtexdetail;
833 if (bleedx > skeleton.skinsize - 1)
834 bleedx = skeleton.skinsize - 1;
835 if (bleedy > skeleton.skinsize - 1)
836 bleedy = skeleton.skinsize - 1;
837 direction = abs(Random() % 2) * 2 - 1;
842 bleeding = howmuch + (float)abs(Random() % 100) / 200 - .25;
843 deathbleeding += bleeding;
844 bloodloss += bleeding * 3;
846 if (tutoriallevel != 1 && aitype != playercontrolled && bloodloss > damagetolerance * 2 / 3 && bloodloss < damagetolerance && creature == rabbittype) {
847 if (abs(Random() % 2) == 0) {
848 aitype = gethelptype;
851 aitype = attacktypecutoff;
862 * guessing this performs a reversal
864 void Person::Reverse()
866 if (!((victim->aitype == playercontrolled
868 || staggerdelay <= 0)
869 && victim->animTarget != jumpupanim
870 && victim->animTarget != jumpdownanim
871 && (tutoriallevel != 1 || cananger)
875 if (normaldotproduct (victim->facing, victim->coords - coords) > 0
876 && (victim->id != 0 || difficulty >= 2)
877 && (creature != wolftype || victim->creature == wolftype))
880 if (animTarget == sweepanim) {
881 animTarget = sweepreversedanim;
882 animCurrent = sweepreversedanim;
883 victim->animCurrent = sweepreversalanim;
884 victim->animTarget = sweepreversalanim;
886 if (animTarget == spinkickanim) {
887 animTarget = spinkickreversedanim;
888 animCurrent = spinkickreversedanim;
889 victim->animCurrent = spinkickreversalanim;
890 victim->animTarget = spinkickreversalanim;
892 if (animTarget == upunchanim || animTarget == rabbittacklinganim) {
893 if (animTarget == rabbittacklinganim) {
896 victim->frameCurrent = 6;
897 victim->frameTarget = 7;
899 animTarget = upunchreversedanim;
900 animCurrent = upunchreversedanim;
901 victim->animCurrent = upunchreversalanim;
902 victim->animTarget = upunchreversalanim;
904 if (animTarget == staffhitanim && distsq(&victim->coords, &coords) < 2 && ((victim->id == 0 && victim->crouchkeydown) || Random() % 4 == 0)) {
905 if (victim->weaponactive != -1) {
906 victim->throwtogglekeydown = 1;
907 weapons[victim->weaponids[0]].owner = -1;
908 weapons[victim->weaponids[0]].velocity = victim->velocity * .2;
909 if (weapons[victim->weaponids[0]].velocity.x == 0)
910 weapons[victim->weaponids[0]].velocity.x = .1;
911 weapons[victim->weaponids[0]].tipvelocity = weapons[victim->weaponids[0]].velocity;
912 weapons[victim->weaponids[0]].missed = 1;
913 weapons[victim->weaponids[0]].freetime = 0;
914 weapons[victim->weaponids[0]].firstfree = 1;
915 weapons[victim->weaponids[0]].physics = 1;
916 victim->num_weapons--;
917 if (victim->num_weapons) {
918 victim->weaponids[0] = victim->weaponids[victim->num_weapons];
919 if (victim->weaponstuck == victim->num_weapons)
920 victim->weaponstuck = 0;
923 victim->weaponactive = -1;
924 for (unsigned j = 0; j < Person::players.size(); j++) {
925 Person::players[j]->wentforweapon = 0;
929 animTarget = staffhitreversedanim;
930 animCurrent = staffhitreversedanim;
931 victim->animCurrent = staffhitreversalanim;
932 victim->animTarget = staffhitreversalanim;
934 if (animTarget == staffspinhitanim && distsq(&victim->coords, &coords) < 2 && ((victim->id == 0 && victim->crouchkeydown) || Random() % 2 == 0)) {
935 if (victim->weaponactive != -1) {
936 victim->throwtogglekeydown = 1;
937 weapons[victim->weaponids[0]].owner = -1;
938 weapons[victim->weaponids[0]].velocity = victim->velocity * .2;
939 if (weapons[victim->weaponids[0]].velocity.x == 0)
940 weapons[victim->weaponids[0]].velocity.x = .1;
941 weapons[victim->weaponids[0]].tipvelocity = weapons[victim->weaponids[0]].velocity;
942 weapons[victim->weaponids[0]].missed = 1;
943 weapons[victim->weaponids[0]].freetime = 0;
944 weapons[victim->weaponids[0]].firstfree = 1;
945 weapons[victim->weaponids[0]].physics = 1;
946 victim->num_weapons--;
947 if (victim->num_weapons) {
948 victim->weaponids[0] = victim->weaponids[victim->num_weapons];
949 if (victim->weaponstuck == victim->num_weapons)
950 victim->weaponstuck = 0;
953 victim->weaponactive = -1;
954 for (unsigned j = 0; j < Person::players.size(); j++) {
955 Person::players[j]->wentforweapon = 0;
958 animTarget = staffspinhitreversedanim;
959 animCurrent = staffspinhitreversedanim;
960 victim->animCurrent = staffspinhitreversalanim;
961 victim->animTarget = staffspinhitreversalanim;
963 if (animTarget == swordslashanim && distsq(&victim->coords, &coords) < 2 && ((victim->id == 0 && victim->crouchkeydown) || Random() % 4 == 0)) {
964 if (victim->weaponactive != -1) {
965 victim->throwtogglekeydown = 1;
966 weapons[victim->weaponids[0]].owner = -1;
967 weapons[victim->weaponids[0]].velocity = victim->velocity * .2;
968 if (weapons[victim->weaponids[0]].velocity.x == 0)
969 weapons[victim->weaponids[0]].velocity.x = .1;
970 weapons[victim->weaponids[0]].tipvelocity = weapons[victim->weaponids[0]].velocity;
971 weapons[victim->weaponids[0]].missed = 1;
972 weapons[victim->weaponids[0]].freetime = 0;
973 weapons[victim->weaponids[0]].firstfree = 1;
974 weapons[victim->weaponids[0]].physics = 1;
975 victim->num_weapons--;
976 if (victim->num_weapons) {
977 victim->weaponids[0] = victim->weaponids[victim->num_weapons];
978 if (victim->weaponstuck == victim->num_weapons)
979 victim->weaponstuck = 0;
982 victim->weaponactive = -1;
983 for (unsigned j = 0; j < Person::players.size(); j++) {
984 Person::players[j]->wentforweapon = 0;
987 animTarget = swordslashreversedanim;
988 animCurrent = swordslashreversedanim;
989 victim->animCurrent = swordslashreversalanim;
990 victim->animTarget = swordslashreversalanim;
992 if (animTarget == knifeslashstartanim && distsq(&victim->coords, &coords) < 2 && (victim->id == 0 || Random() % 4 == 0)) {
993 if (victim->weaponactive != -1) {
994 victim->throwtogglekeydown = 1;
995 weapons[victim->weaponids[0]].owner = -1;
996 weapons[victim->weaponids[0]].velocity = victim->velocity * .2;
997 if (weapons[victim->weaponids[0]].velocity.x == 0)
998 weapons[victim->weaponids[0]].velocity.x = .1;
999 weapons[victim->weaponids[0]].tipvelocity = weapons[victim->weaponids[0]].velocity;
1000 weapons[victim->weaponids[0]].missed = 1;
1001 weapons[victim->weaponids[0]].freetime = 0;
1002 weapons[victim->weaponids[0]].firstfree = 1;
1003 weapons[victim->weaponids[0]].physics = 1;
1004 victim->num_weapons--;
1005 if (victim->num_weapons) {
1006 victim->weaponids[0] = victim->weaponids[victim->num_weapons];
1007 if (victim->weaponstuck == victim->num_weapons)
1008 victim->weaponstuck = 0;
1011 victim->weaponactive = -1;
1012 for (unsigned j = 0; j < Person::players.size(); j++) {
1013 Person::players[j]->wentforweapon = 0;
1016 animTarget = knifeslashreversedanim;
1017 animCurrent = knifeslashreversedanim;
1018 victim->animCurrent = knifeslashreversalanim;
1019 victim->animTarget = knifeslashreversalanim;
1021 if (animTarget != knifeslashstartanim && animTarget != staffhitanim && animTarget != staffspinhitanim && animTarget != winduppunchanim && animTarget != wolfslapanim && animTarget != swordslashanim && animTarget != swordslashanim) {
1022 victim->targettilt2 = targettilt2;
1023 victim->frameCurrent = frameCurrent;
1024 victim->frameTarget = frameTarget;
1025 victim->target = target;
1026 victim->velocity = 0;
1027 victim->oldcoords = victim->coords;
1028 victim->coords = coords;
1029 victim->targetyaw = targetyaw;
1030 victim->yaw = targetyaw;
1031 victim->victim = this->shared_from_this();
1033 if (animTarget == winduppunchanim) {
1034 animTarget = winduppunchblockedanim;
1035 victim->animTarget = blockhighleftanim;
1036 victim->frameTarget = 1;
1037 victim->target = .5;
1038 victim->victim = this->shared_from_this();
1039 victim->targetyaw = targetyaw + 180;
1041 if (animTarget == wolfslapanim) {
1042 animTarget = winduppunchblockedanim;
1043 victim->animTarget = blockhighleftanim;
1044 victim->frameTarget = 1;
1045 victim->target = .5;
1046 victim->victim = this->shared_from_this();
1047 victim->targetyaw = targetyaw + 180;
1049 if ((animTarget == swordslashanim || animTarget == staffhitanim || animTarget == staffspinhitanim) && victim->weaponactive != -1) {
1050 animTarget = swordslashparriedanim;
1051 parriedrecently = .4;
1052 victim->parriedrecently = 0;
1053 victim->animTarget = swordslashparryanim;
1054 victim->frameTarget = 1;
1055 victim->target = .5;
1056 victim->victim = this->shared_from_this();
1057 victim->targetyaw = targetyaw + 180;
1059 if (abs(Random() % 20) == 0 || weapons[victim->weaponids[victim->weaponactive]].getType() == knife) {
1060 if (victim->weaponactive != -1) {
1061 if (weapons[victim->weaponids[0]].getType() == staff || weapons[weaponids[0]].getType() == staff) {
1062 if (weapons[victim->weaponids[0]].getType() == staff)
1063 weapons[victim->weaponids[0]].damage += .2 + float(abs(Random() % 100) - 50) / 250;
1064 if (weapons[weaponids[0]].getType() == staff)
1065 weapons[weaponids[0]].damage += .2 + float(abs(Random() % 100) - 50) / 250;
1066 emit_sound_at(swordstaffsound, victim->coords);
1068 emit_sound_at(metalhitsound, victim->coords);
1072 victim->Puff(righthand);
1074 victim->frameTarget = 0;
1075 victim->animTarget = staggerbackhighanim;
1076 victim->targetyaw = targetyaw + 180;
1078 weapons[victim->weaponids[0]].owner = -1;
1079 aim = DoRotation(facing, 0, 90, 0) * 21;
1081 weapons[victim->weaponids[0]].velocity = aim * -.2;
1082 weapons[victim->weaponids[0]].tipvelocity = aim;
1083 weapons[victim->weaponids[0]].missed = 1;
1084 weapons[victim->weaponids[0]].hitsomething = 0;
1085 weapons[victim->weaponids[0]].freetime = 0;
1086 weapons[victim->weaponids[0]].firstfree = 1;
1087 weapons[victim->weaponids[0]].physics = 1;
1088 victim->num_weapons--;
1089 if (victim->num_weapons) {
1090 victim->weaponids[0] = victim->weaponids[num_weapons];
1091 if (victim->weaponstuck == victim->num_weapons)
1092 victim->weaponstuck = 0;
1094 victim->weaponactive = -1;
1095 for (unsigned i = 0; i < Person::players.size(); i++) {
1096 Person::players[i]->wentforweapon = 0;
1100 if (abs(Random() % 20) == 0) {
1101 if (weaponactive != -1) {
1102 if (weapons[victim->weaponids[0]].getType() == staff || weapons[weaponids[0]].getType() == staff) {
1103 if (weapons[victim->weaponids[0]].getType() == staff)
1104 weapons[victim->weaponids[0]].damage += .2 + float(abs(Random() % 100) - 50) / 250;
1105 if (weapons[weaponids[0]].getType() == staff)
1106 weapons[weaponids[0]].damage += .2 + float(abs(Random() % 100) - 50) / 250;
1108 emit_sound_at(swordstaffsound, coords);
1110 emit_sound_at(metalhitsound, coords);
1118 animTarget = staggerbackhighanim;
1119 targetyaw = targetyaw + 180;
1121 weapons[weaponids[0]].owner = -1;
1122 aim = DoRotation(facing, 0, 90, 0) * 21;
1124 weapons[weaponids[0]].velocity = aim * -.2;
1125 weapons[weaponids[0]].tipvelocity = aim;
1126 weapons[weaponids[0]].hitsomething = 0;
1127 weapons[weaponids[0]].missed = 1;
1128 weapons[weaponids[0]].freetime = 0;
1129 weapons[weaponids[0]].firstfree = 1;
1130 weapons[weaponids[0]].physics = 1;
1133 weaponids[0] = weaponids[num_weapons];
1134 if (weaponstuck == num_weapons)
1138 for (unsigned i = 0; i < Person::players.size(); i++) {
1139 Person::players[i]->wentforweapon = 0;
1146 if (animTarget == knifeslashstartanim || animTarget == swordslashanim || animTarget == staffhitanim || animTarget == staffspinhitanim) {
1147 if ((animTarget != staffhitanim && animTarget != staffspinhitanim) || distsq(&coords, &victim->coords) > .2) {
1148 victim->animTarget = dodgebackanim;
1149 victim->frameTarget = 0;
1153 rotatetarget = coords - victim->coords;
1154 Normalise(&rotatetarget);
1155 victim->targetyaw = -asin(0 - rotatetarget.x);
1156 victim->targetyaw *= 360 / 6.28;
1157 if (rotatetarget.z < 0)
1158 victim->targetyaw = 180 - victim->targetyaw;
1160 victim->targettilt2 = -asin(rotatetarget.y) * 360 / 6.28; //*-70;
1162 victim->lastattack3 = victim->lastattack2;
1163 victim->lastattack2 = victim->lastattack;
1164 victim->lastattack = victim->animTarget;
1166 victim->animTarget = sweepanim;
1167 victim->frameTarget = 0;
1171 rotatetarget = coords - victim->coords;
1172 Normalise(&rotatetarget);
1173 victim->targetyaw = -asin(0 - rotatetarget.x);
1174 victim->targetyaw *= 360 / 6.28;
1175 if (rotatetarget.z < 0)
1176 victim->targetyaw = 180 - victim->targetyaw;
1178 victim->targettilt2 = -asin(rotatetarget.y) * 360 / 6.28; //*-70;
1180 victim->lastattack3 = victim->lastattack2;
1181 victim->lastattack2 = victim->lastattack;
1182 victim->lastattack = victim->animTarget;
1187 victim->velocity = 0;
1189 if (aitype != playercontrolled)
1191 if (aitype != playercontrolled && Random() % 3 == 0 && escapednum < 2 && difficulty == 2)
1193 if (aitype != playercontrolled && Random() % 5 == 0 && escapednum < 2 && difficulty == 1)
1195 if (aitype != playercontrolled && Random() % 10 == 0 && escapednum < 2 && difficulty == 0)
1198 if (victim->id == 0 && animation[victim->animTarget].attack == reversal)
1205 void Person::DoDamage(float howmuch)
1207 // subtract health (temporary?)
1208 if (tutoriallevel != 1)
1209 damage += howmuch / power;
1212 damagedealt += howmuch / power;
1214 damagetaken += howmuch / power;
1217 if (id == 0 && (bonus == solidhit || bonus == twoxcombo || bonus == threexcombo || bonus == fourxcombo || bonus == megacombo))
1220 if (tutoriallevel != 1)
1221 permanentdamage += howmuch / 2 / power;
1222 if (tutoriallevel != 1)
1223 superpermanentdamage += howmuch / 4 / power;
1225 if (permanentdamage > damagetolerance / 2 && permanentdamage - howmuch < damagetolerance / 2 && Random() % 2)
1227 if ((permanentdamage > damagetolerance * .8 && Random() % 2 && !deathbleeding) || spurt)
1231 camerashake += howmuch / 100;
1232 if (id == 0 && ((howmuch > 50 && damage > damagetolerance / 2)))
1233 blackout = damage / damagetolerance;
1238 if (aitype == passivetype && damage < damagetolerance && ((tutoriallevel != 1 || cananger) && hostile))
1239 aitype = attacktypecutoff;
1240 if (tutoriallevel != 1 && aitype != playercontrolled && damage < damagetolerance && damage > damagetolerance * 2 / 3 && creature == rabbittype) {
1241 if (abs(Random() % 2) == 0) {
1242 aitype = gethelptype;
1245 aitype = attacktypecutoff;
1249 if (howmuch > damagetolerance * 50 && skeleton.free != 2) {
1252 for (int i = 0; i < skeleton.num_joints; i++) {
1254 flatvelocity2 = velocity;
1256 flatvelocity2 = skeleton.joints[i].velocity;
1258 flatfacing2 = DoRotation(DoRotation(DoRotation(skeleton.joints[i].position, 0, 0, tilt), tilt2, 0, 0), 0, yaw, 0) * scale + coords;
1260 flatfacing2 = skeleton.joints[i].position * scale + coords;
1261 flatvelocity2.x += (float)(abs(Random() % 100) - 50) / 10;
1262 flatvelocity2.y += (float)(abs(Random() % 100) - 50) / 10;
1263 flatvelocity2.z += (float)(abs(Random() % 100) - 50) / 10;
1264 Sprite::MakeSprite(bloodflamesprite, flatfacing2, flatvelocity2, 1, 1, 1, 3, 1);
1265 Sprite::MakeSprite(bloodsprite, flatfacing2, flatvelocity2, 1, 1, 1, .4, 1);
1266 Sprite::MakeSprite(cloudsprite, flatfacing2, flatvelocity2 * 0, .6, 0, 0, 1, .5);
1269 emit_sound_at(splattersound, coords);
1278 if (!dead && creature == wolftype) {
1279 award_bonus(0, Wolfbonus);
1286 if (tutoriallevel != 1 || id == 0)
1287 if (speechdelay <= 0 && !dead && aitype != playercontrolled) {
1288 int whichsound = -1;
1290 if (creature == wolftype) {
1291 int i = abs(Random() % 2);
1293 whichsound = snarlsound;
1295 whichsound = snarl2sound;
1296 envsound[numenvsounds] = coords;
1297 envsoundvol[numenvsounds] = 16;
1298 envsoundlife[numenvsounds] = .4;
1301 if (creature == rabbittype) {
1302 int i = abs(Random() % 2);
1304 whichsound = rabbitpainsound;
1305 if (i == 1 && damage > damagetolerance)
1306 whichsound = rabbitpain1sound;
1307 envsound[numenvsounds] = coords;
1308 envsoundvol[numenvsounds] = 16;
1309 envsoundlife[numenvsounds] = .4;
1311 //if(i==2)whichsound=rabbitpain2sound;
1314 if (whichsound != -1) {
1315 emit_sound_at(whichsound, coords);
1320 //if(permanentdamage>=damagetolerance&&howmuch<50)permanentdamage=damagetolerance-1;
1321 //if(damage>=damagetolerance&&howmuch<30&&!dead)damage=damagetolerance-1;
1325 * calculate/animate head facing direction?
1327 void Person::DoHead()
1329 static XYZ rotatearound;
1331 static float lookspeed = 500;
1333 if (!freeze && !winfreeze) {
1336 targetheadyaw = (float)((int)((0 - yaw - targetheadyaw + 180) * 100) % 36000) / 100;
1337 targetheadpitch = (float)((int)(targetheadpitch * 100) % 36000) / 100;
1339 while (targetheadyaw > 180)targetheadyaw -= 360;
1340 while (targetheadyaw < -180)targetheadyaw += 360;
1342 if (targetheadyaw > 160)
1343 targetheadpitch = targetheadpitch * -1;
1344 if (targetheadyaw < -160)
1345 targetheadpitch = targetheadpitch * -1;
1346 if (targetheadyaw > 160)
1347 targetheadyaw = targetheadyaw - 180;
1348 if (targetheadyaw < -160)
1349 targetheadyaw = targetheadyaw + 180;
1351 if (targetheadpitch > 120)
1352 targetheadpitch = 120;
1353 if (targetheadpitch < -120)
1354 targetheadpitch = -120;
1355 if (targetheadyaw > 120)
1356 targetheadyaw = 120;
1357 if (targetheadyaw < -120)
1358 targetheadyaw = -120;
1361 targetheadpitch = 0;
1363 if (targetheadyaw > 80)
1365 if (targetheadyaw < -80)
1366 targetheadyaw = -80;
1367 if (targetheadpitch > 50)
1368 targetheadpitch = 50;
1369 if (targetheadpitch < -50)
1370 targetheadpitch = -50;
1373 if (abs(headyaw - targetheadyaw) < multiplier * lookspeed)
1374 headyaw = targetheadyaw;
1375 else if (headyaw > targetheadyaw) {
1376 headyaw -= multiplier * lookspeed;
1377 } else if (headyaw < targetheadyaw) {
1378 headyaw += multiplier * lookspeed;
1381 if (abs(headpitch - targetheadpitch) < multiplier * lookspeed / 2)
1382 headpitch = targetheadpitch;
1383 else if (headpitch > targetheadpitch) {
1384 headpitch -= multiplier * lookspeed / 2;
1385 } else if (headpitch < targetheadpitch) {
1386 headpitch += multiplier * lookspeed / 2;
1389 rotatearound = jointPos(neck);
1390 jointPos(head) = rotatearound + DoRotation(jointPos(head) - rotatearound, headpitch, 0, 0);
1394 if (animTarget != bounceidleanim && animTarget != fightidleanim && animTarget != wolfidle && animTarget != knifefightidleanim && animTarget != drawrightanim && animTarget != drawleftanim && animTarget != walkanim) {
1395 facing = DoRotation(facing, headpitch * .4, 0, 0);
1396 facing = DoRotation(facing, 0, headyaw * .4, 0);
1399 if (animTarget == bounceidleanim || animTarget == fightidleanim || animTarget == wolfidle || animTarget == knifefightidleanim || animTarget == drawrightanim || animTarget == drawleftanim) {
1400 facing = DoRotation(facing, headpitch * .8, 0, 0);
1401 facing = DoRotation(facing, 0, headyaw * .8, 0);
1404 if (animTarget == walkanim) {
1405 facing = DoRotation(facing, headpitch * .6, 0, 0);
1406 facing = DoRotation(facing, 0, headyaw * .6, 0);
1409 skeleton.specialforward[0] = facing;
1410 //skeleton.specialforward[0]=DoRotation(facing,0,yaw,0);
1411 for (int i = 0; i < skeleton.num_muscles; i++) {
1412 if (skeleton.muscles[i].visible && (skeleton.muscles[i].parent1->label == head || skeleton.muscles[i].parent2->label == head)) {
1413 skeleton.FindRotationMuscle(i, animTarget);
1420 * ragdolls character?
1422 void Person::RagDoll(bool checkcollision)
1427 if (!skeleton.free) {
1430 if (id == 0 && isFlip())
1437 facing = DoRotation(facing, 0, yaw, 0);
1439 skeleton.freetime = 0;
1441 skeleton.longdead = 0;
1444 skeleton.broken = 0;
1445 skeleton.spinny = 1;
1447 skeleton.freefall = 1;
1449 if (!isnormal(velocity.x)) velocity.x = 0;
1450 if (!isnormal(velocity.y)) velocity.y = 0;
1451 if (!isnormal(velocity.z)) velocity.z = 0;
1452 if (!isnormal(yaw)) yaw = 0;
1453 if (!isnormal(coords.x)) coords = 0;
1454 if (!isnormal(tilt)) tilt = 0;
1455 if (!isnormal(tilt2)) tilt2 = 0;
1457 for (int i = 0; i < skeleton.num_joints; i++) {
1458 skeleton.joints[i].delay = 0;
1459 skeleton.joints[i].locked = 0;
1460 skeleton.joints[i].position = DoRotation(DoRotation(DoRotation(skeleton.joints[i].position, 0, 0, tilt), tilt2, 0, 0), 0, yaw, 0);
1461 if (!isnormal(skeleton.joints[i].position.x)) skeleton.joints[i].position = DoRotation(skeleton.joints[i].position, 0, yaw, 0);
1462 if (!isnormal(skeleton.joints[i].position.x)) skeleton.joints[i].position = skeleton.joints[i].position;
1463 if (!isnormal(skeleton.joints[i].position.x)) skeleton.joints[i].position = coords;
1464 skeleton.joints[i].position.y += .1;
1465 skeleton.joints[i].oldposition = skeleton.joints[i].position;
1466 skeleton.joints[i].realoldposition = skeleton.joints[i].position * scale + coords;
1469 for (int i = 0; i < skeleton.num_joints; i++) {
1470 skeleton.joints[i].velocity = 0;
1471 skeleton.joints[i].velchange = 0;
1473 skeleton.DoConstraints(&coords, &scale);
1474 if (animation[animCurrent].height == lowheight || animation[animTarget].height == lowheight) {
1475 skeleton.DoConstraints(&coords, &scale);
1476 skeleton.DoConstraints(&coords, &scale);
1477 skeleton.DoConstraints(&coords, &scale);
1478 skeleton.DoConstraints(&coords, &scale);
1481 speed = animation[animTarget].speed[frameTarget] * 2;
1482 if (animation[animCurrent].speed[frameCurrent] > animation[animTarget].speed[frameTarget]) {
1483 speed = animation[animCurrent].speed[frameCurrent] * 2;
1486 speed = transspeed * 2;
1490 for (int i = 0; i < skeleton.num_joints; i++) {
1491 if ((animation[animCurrent].attack != reversed || animCurrent == swordslashreversedanim) && animCurrent != rabbitkickanim && !isLanding() && !wasLanding() && animation[animCurrent].height == animation[animTarget].height)
1492 skeleton.joints[i].velocity = velocity / scale + facing * 5 + DoRotation(DoRotation(DoRotation((animation[animTarget].position[i][frameTarget] - animation[animCurrent].position[i][frameCurrent]) * speed, 0, 0, tilt), tilt2, 0, 0), 0, yaw, 0);
1494 skeleton.joints[i].velocity = velocity / scale + facing * 5;
1495 change.x = (float)(Random() % 100) / 100;
1496 change.y = (float)(Random() % 100) / 100;
1497 change.z = (float)(Random() % 100) / 100;
1498 skeleton.joints[i].velocity += change;
1499 skeleton.joints[abs(Random() % skeleton.num_joints)].velocity -= change;
1501 change.x = (float)(Random() % 100) / 100;
1502 change.y = (float)(Random() % 100) / 100;
1503 change.z = (float)(Random() % 100) / 100;
1504 skeleton.joints[i].velchange += change;
1505 skeleton.joints[abs(Random() % skeleton.num_joints)].velchange -= change;
1508 if (checkcollision) {
1515 for (j = 0; j < skeleton.num_joints; j++) {
1516 average += skeleton.joints[j].position;
1520 coords += average * scale;
1521 for (j = 0; j < skeleton.num_joints; j++) {
1522 skeleton.joints[j].position -= average;
1525 whichpatchx = coords.x / (terrain.size / subdivision * terrain.scale);
1526 whichpatchz = coords.z / (terrain.size / subdivision * terrain.scale);
1527 if (terrain.patchobjectnum[whichpatchx][whichpatchz])
1528 for (l = 0; l < terrain.patchobjectnum[whichpatchx][whichpatchz]; l++) {
1529 i = terrain.patchobjects[whichpatchx][whichpatchz][l];
1532 if (SphereCheck(&lowpoint, 3, &colpoint, &objects.position[i], &objects.yaw[i], &objects.model[i]) != -1) {
1533 coords.x = lowpoint.x;
1534 coords.z = lowpoint.z;
1543 for (int i = 0; i < skeleton.num_joints; i++) {
1544 velocity += skeleton.joints[i].velocity * scale;
1546 velocity /= skeleton.num_joints;
1549 if (Random() % 2 == 0) {
1550 if (weaponactive != -1 && animTarget != rabbitkickanim && num_weapons > 0) {
1551 weapons[weaponids[0]].owner = -1;
1552 weapons[weaponids[0]].hitsomething = 0;
1553 weapons[weaponids[0]].velocity = jointVel(righthand) * scale * -.3;
1554 weapons[weaponids[0]].velocity.x += .01;
1555 weapons[weaponids[0]].tipvelocity = jointVel(righthand) * scale;
1556 weapons[weaponids[0]].missed = 1;
1557 weapons[weaponids[0]].freetime = 0;
1558 weapons[weaponids[0]].firstfree = 1;
1559 weapons[weaponids[0]].physics = 1;
1562 weaponids[0] = weaponids[num_weapons];
1563 if (weaponstuck == num_weapons)
1567 for (unsigned i = 0; i < Person::players.size(); i++) {
1568 Person::players[i]->wentforweapon = 0;
1573 animTarget = bounceidleanim;
1574 animCurrent = bounceidleanim;
1584 void Person::FootLand(int which, float opacity)
1586 static XYZ terrainlight;
1587 static XYZ footvel, footpoint;
1588 if (opacity >= 1 || skiddelay <= 0)
1592 footpoint = DoRotation(jointPos(leftfoot), 0, yaw, 0) * scale + coords;
1594 footpoint = DoRotation(jointPos(rightfoot), 0, yaw, 0) * scale + coords;
1595 //footpoint.y=coords.y;
1596 if (distsq(&footpoint, &viewer))
1597 Sprite::MakeSprite(cloudsprite, footpoint, footvel, 1, 1, 1, .5, .2 * opacity);
1598 } else if (environment == snowyenvironment && onterrain && terrain.getOpacity(coords.x, coords.z) < .2) {
1599 footvel = velocity / 5;
1603 footpoint = DoRotation(jointPos(leftfoot), 0, yaw, 0) * scale + coords;
1605 footpoint = DoRotation(jointPos(rightfoot), 0, yaw, 0) * scale + coords;
1606 footpoint.y = terrain.getHeight(footpoint.x, footpoint.z);
1607 terrainlight = terrain.getLighting(footpoint.x, footpoint.z);
1608 if (distsq(&footpoint, &viewer) < viewdistance * viewdistance / 4)
1609 Sprite::MakeSprite(cloudsprite, footpoint, footvel * .6, terrainlight.x, terrainlight.y, terrainlight.z, .5, .7 * opacity);
1610 if (opacity >= 1 || detail == 2)
1612 if (distsq(&footpoint, &viewer) < viewdistance * viewdistance / 4)
1613 terrain.MakeDecal(footprintdecal, footpoint, .2, 1 * opacity, yaw);
1614 } else if (environment == grassyenvironment && onterrain && terrain.getOpacity(coords.x, coords.z) < .2) {
1615 footvel = velocity / 5;
1619 footpoint = DoRotation(jointPos(leftfoot), 0, yaw, 0) * scale + coords;
1621 footpoint = DoRotation(jointPos(rightfoot), 0, yaw, 0) * scale + coords;
1622 footpoint.y = terrain.getHeight(footpoint.x, footpoint.z);
1623 terrainlight = terrain.getLighting(footpoint.x, footpoint.z);
1624 if (distsq(&footpoint, &viewer) < viewdistance * viewdistance / 4)
1625 Sprite::MakeSprite(cloudsprite, footpoint, footvel * .6, terrainlight.x * 90 / 255, terrainlight.y * 70 / 255, terrainlight.z * 8 / 255, .5, .5 * opacity);
1626 } else if (environment == desertenvironment && onterrain && terrain.getOpacity(coords.x, coords.z) < .2) {
1627 footvel = velocity / 5;
1631 footpoint = DoRotation(jointPos(leftfoot), 0, yaw, 0) * scale + coords;
1633 footpoint = DoRotation(jointPos(rightfoot), 0, yaw, 0) * scale + coords;
1634 footpoint.y = terrain.getHeight(footpoint.x, footpoint.z);
1635 terrainlight = terrain.getLighting(footpoint.x, footpoint.z);
1636 if (distsq(&footpoint, &viewer) < viewdistance * viewdistance / 4)
1637 Sprite::MakeSprite(cloudsprite, footpoint, footvel * .6, terrainlight.x * 190 / 255, terrainlight.y * 170 / 255, terrainlight.z * 108 / 255, .5, .7 * opacity);
1638 if (opacity >= 1 || detail == 2)
1640 if (distsq(&footpoint, &viewer) < viewdistance * viewdistance / 4)
1641 terrain.MakeDecal(footprintdecal, footpoint, .2, .25 * opacity, yaw);
1642 } else if (isLanding() || animTarget == jumpupanim || isLandhard()) {
1643 footvel = velocity / 5;
1647 footpoint = DoRotation(jointPos(leftfoot), 0, yaw, 0) * scale + coords;
1649 footpoint = DoRotation(jointPos(rightfoot), 0, yaw, 0) * scale + coords;
1650 //footpoint.y=coords.y;
1651 if (distsq(&footpoint, &viewer) < viewdistance * viewdistance / 4)
1652 Sprite::MakeSprite(cloudsprite, footpoint, footvel * .6, 1, 1, 1, .5, .2 * opacity);
1657 * make a puff effect at a body part (dust effect?)
1659 void Person::Puff(int whichlabel)
1661 static XYZ footvel, footpoint;
1664 footpoint = DoRotation(jointPos(whichlabel), 0, yaw, 0) * scale + coords;
1665 Sprite::MakeSprite(cloudimpactsprite, footpoint, footvel, 1, 1, 1, .9, .3);
1669 * I think I added this in an attempt to clean up code
1671 void Person::setAnimation(int animation)
1673 animTarget = animation;
1682 void Person::DoAnimations()
1684 if (!skeleton.free) {
1685 static float oldtarget;
1687 if (isIdle() && animCurrent != getIdle())
1688 normalsupdatedelay = 0;
1690 if (animTarget == tempanim || animCurrent == tempanim) {
1691 animation[tempanim] = tempanimation;
1693 if (animTarget == jumpupanim || animTarget == jumpdownanim || isFlip()) {
1699 vel[0] = velocity.x;
1700 vel[1] = velocity.y;
1701 vel[2] = velocity.z;
1704 OPENAL_3D_SetAttributes(channels[whooshsound], gLoc, vel);
1705 OPENAL_SetVolume(channels[whooshsound], 64 * findLength(&velocity) / 5);
1707 if (((velocity.y < -15) || (crouchkeydown && velocity.y < -8)) && abs(velocity.y) * 4 > fast_sqrt(velocity.x * velocity.x * velocity.z * velocity.z))
1709 if (!crouchkeydown && velocity.y >= -15)
1712 if ((animCurrent == jumpupanim || animTarget == jumpdownanim)/*&&velocity.y<40*/ && !isFlip() && (!isLanding() && !isLandhard()) && ((crouchkeydown && !crouchtogglekeydown))) {
1717 targfacing = DoRotation(targfacing, 0, targetyaw, 0);
1719 if (normaldotproduct(targfacing, velocity) >= -.3)
1720 animTarget = flipanim;
1722 animTarget = backflipanim;
1723 crouchtogglekeydown = 1;
1731 if (animation[animTarget].attack != reversed)
1733 if (!crouchkeydown || (isLanding() || isLandhard()) || (wasLanding() || wasLandhard())) {
1734 crouchtogglekeydown = 0;
1735 if (aitype == playercontrolled)
1738 if (!crouchtogglekeydown && animation[animTarget].attack == reversed && aitype == playercontrolled && (escapednum < 2 || reversaltrain))
1741 crouchtogglekeydown = 1;
1745 if (animation[animTarget].attack || animCurrent == getupfrombackanim || animCurrent == getupfromfrontanim) {
1747 normalsupdatedelay = 0;
1751 if (animTarget == rollanim && frameTarget == 3 && onfire) {
1753 emit_sound_at(fireendsound, coords);
1754 pause_sound(stream_firesound);
1758 if (animTarget == rabbittacklinganim && frameTarget == 1) {
1759 //if(victim->aitype==attacktypecutoff&&Random()%2==0&&victim->stunned<=0&&animation[victim->animTarget].attack==neutral&&victim->id!=0)Reverse();
1760 if (victim->aitype == attacktypecutoff && victim->stunned <= 0 && victim->surprised <= 0 && victim->id != 0)
1762 if (animTarget == rabbittacklinganim && frameTarget == 1 && !victim->isCrouch() && victim->animTarget != backhandspringanim) {
1763 if (normaldotproduct(victim->facing, facing) > 0)
1764 victim->animTarget = rabbittackledbackanim;
1766 victim->animTarget = rabbittackledfrontanim;
1767 victim->frameTarget = 2;
1770 victim->targetyaw = yaw;
1771 if (victim->aitype == gethelptype)
1772 victim->DoDamage(victim->damagetolerance - victim->damage);
1773 //victim->DoDamage(30);
1774 if (creature == wolftype) {
1776 emit_sound_at(clawslicesound, victim->coords);
1778 victim->DoBloodBig(1 / victim->armorhead, 210);
1780 award_bonus(id, TackleBonus,
1781 victim->aitype == gethelptype ? 50 : 0);
1785 if (!drawtogglekeydown && drawkeydown && (weaponactive == -1 || num_weapons == 1) && (animation[animTarget].label[frameTarget] || (animTarget != animCurrent && animCurrent == rollanim)) && num_weapons > 0 && creature != wolftype) {
1786 if (weapons[weaponids[0]].getType() == knife) {
1787 if (weaponactive == -1)
1789 else if (weaponactive == 0)
1792 if (weaponactive == -1) {
1793 emit_sound_at(knifesheathesound, coords);
1795 if (weaponactive != -1) {
1796 emit_sound_at(knifedrawsound, coords, 128);
1799 drawtogglekeydown = 1;
1802 if (tutoriallevel != 1 || id == 0)
1803 if ((animation[animTarget].label[frameTarget] && (animation[animTarget].label[frameTarget] < 5 || animation[animTarget].label[frameTarget] == 8))/*||(animTarget==rollanim&&frameTarget==animation[rollanim].numframes-1)*/) {
1806 if (terrain.getOpacity(coords.x, coords.z) < .2) {
1807 if (animation[animTarget].label[frameTarget] == 1)
1808 whichsound = footstepsound;
1810 whichsound = footstepsound2;
1811 if (animation[animTarget].label[frameTarget] == 1)
1813 if (animation[animTarget].label[frameTarget] == 2)
1815 if (animation[animTarget].label[frameTarget] == 3 && isRun()) {
1821 if (terrain.getOpacity(coords.x, coords.z) >= .2) {
1822 if (animation[animTarget].label[frameTarget] == 1)
1823 whichsound = footstepsound3;
1825 whichsound = footstepsound4;
1829 if (animation[animTarget].label[frameTarget] == 1)
1830 whichsound = footstepsound3;
1832 whichsound = footstepsound4;
1834 if (animation[animTarget].label[frameTarget] == 4 && (weaponactive == -1 || (animTarget != knifeslashstartanim && animTarget != knifethrowanim && animTarget != crouchstabanim && animTarget != swordgroundstabanim && animTarget != knifefollowanim))) {
1835 if (animation[animTarget].attack != neutral) {
1836 unsigned r = abs(Random() % 3);
1838 whichsound = lowwhooshsound;
1840 whichsound = midwhooshsound;
1842 whichsound = highwhooshsound;
1844 if (animation[animTarget].attack == neutral)
1845 whichsound = movewhooshsound;
1846 } else if (animation[animTarget].label[frameTarget] == 4)
1847 whichsound = knifeswishsound;
1848 if (animation[animTarget].label[frameTarget] == 8 && tutoriallevel != 1)
1849 whichsound = landsound2;
1851 emit_sound_at(whichsound, coords, 256.);
1854 if (whichsound == footstepsound || whichsound == footstepsound2 || whichsound == footstepsound3 || whichsound == footstepsound4) {
1855 envsound[numenvsounds] = coords;
1856 if (animTarget == wolfrunninganim || animTarget == rabbitrunninganim)
1857 envsoundvol[numenvsounds] = 15;
1859 envsoundvol[numenvsounds] = 6;
1860 envsoundlife[numenvsounds] = .4;
1864 if (animation[animTarget].label[frameTarget] == 3) {
1866 emit_sound_at(whichsound, coords, 128.);
1871 if (tutoriallevel != 1 || id == 0)
1872 if (speechdelay <= 0)
1873 if (animTarget != crouchstabanim && animTarget != swordgroundstabanim && animTarget != staffgroundsmashanim)
1874 if ((animation[animTarget].label[frameTarget] && (animation[animTarget].label[frameTarget] < 5 || animation[animTarget].label[frameTarget] == 8))/*||(animTarget==rollanim&&frameTarget==animation[rollanim].numframes-1)*/) {
1875 int whichsound = -1;
1876 if (animation[animTarget].label[frameTarget] == 4 && aitype != playercontrolled) {
1877 if (animation[animTarget].attack != neutral) {
1878 unsigned r = abs(Random() % 4);
1879 if (creature == rabbittype) {
1880 if (r == 0) whichsound = rabbitattacksound;
1881 if (r == 1) whichsound = rabbitattack2sound;
1882 if (r == 2) whichsound = rabbitattack3sound;
1883 if (r == 3) whichsound = rabbitattack4sound;
1885 if (creature == wolftype) {
1886 if (r == 0) whichsound = barksound;
1887 if (r == 1) whichsound = bark2sound;
1888 if (r == 2) whichsound = bark3sound;
1889 if (r == 3) whichsound = barkgrowlsound;
1893 //if(animation[animTarget].attack==neutral)whichsound=movewhooshsound;
1895 //else if(animation[animTarget].label[frameTarget]==4)whichsound=knifeswishsound;
1896 //if(animation[animTarget].label[frameTarget]==8)whichsound=landsound2;
1898 if (whichsound != -1) {
1899 emit_sound_at(whichsound, coords);
1905 if ((!wasLanding() && !wasLandhard()) && animCurrent != getIdle() && (isLanding() || isLandhard())) {
1911 currentoffset = targetoffset;
1912 frameTarget = frameCurrent;
1913 animCurrent = animTarget;
1916 if (animTarget == removeknifeanim && animation[animTarget].label[frameCurrent] == 5) {
1917 for (unsigned i = 0; i < weapons.size(); i++) {
1918 if (weapons[i].owner == -1)
1919 if (distsqflat(&coords, &weapons[i].position) < 4 && weaponactive == -1) {
1920 if (distsq(&coords, &weapons[i].position) >= 1) {
1921 if (weapons[i].getType() != staff) {
1922 emit_sound_at(knifedrawsound, coords, 128.);
1926 weapons[i].owner = id;
1927 if (num_weapons > 0) {
1928 weaponids[num_weapons] = weaponids[0];
1937 if (animTarget == crouchremoveknifeanim && animation[animTarget].label[frameCurrent] == 5) {
1938 for (unsigned i = 0; i < weapons.size(); i++) {
1939 bool willwork = true;
1940 if (weapons[i].owner != -1)
1941 if (Person::players[weapons[i].owner]->weaponstuck != -1)
1942 if (Person::players[weapons[i].owner]->weaponids[Person::players[weapons[i].owner]->weaponstuck] == int(i))
1943 if (Person::players[weapons[i].owner]->num_weapons > 1)
1945 if ((weapons[i].owner == -1) || (hasvictim && (weapons[i].owner == int(victim->id)) && victim->skeleton.free))
1946 if (willwork && distsqflat(&coords, &weapons[i].position) < 3 && weaponactive == -1) {
1947 if (distsq(&coords, &weapons[i].position) < 1 || hasvictim) {
1948 bool fleshstuck = false;
1949 if (weapons[i].owner != -1)
1950 if (victim->weaponstuck != -1) {
1951 if (victim->weaponids[victim->weaponstuck] == int(i)) {
1956 emit_sound_at(fleshstabremovesound, coords, 128.);
1958 if (weapons[i].getType() != staff) {
1959 emit_sound_at(knifedrawsound, coords, 128.);
1963 if (weapons[i].owner != -1) {
1965 victim = Person::players[weapons[i].owner];
1966 if (victim->num_weapons == 1)
1967 victim->num_weapons = 0;
1969 victim->num_weapons = 1;
1971 //victim->weaponactive=-1;
1972 victim->skeleton.longdead = 0;
1973 victim->skeleton.free = 1;
1974 victim->skeleton.broken = 0;
1976 for (int j = 0; j < victim->skeleton.num_joints; j++) {
1977 victim->skeleton.joints[j].velchange = 0;
1978 victim->skeleton.joints[j].locked = 0;
1984 Normalise(&relative);
1985 XYZ footvel, footpoint;
1987 footpoint = weapons[i].position;
1988 if (victim->weaponstuck != -1) {
1989 if (victim->weaponids[victim->weaponstuck] == int(i)) {
1991 Sprite::MakeSprite(cloudimpactsprite, footpoint, footvel, 1, 0, 0, .8, .3);
1992 weapons[i].bloody = 2;
1993 weapons[i].blooddrip = 5;
1994 victim->weaponstuck = -1;
1997 if (victim->num_weapons > 0) {
1998 if (victim->weaponstuck != 0 && victim->weaponstuck != -1)
1999 victim->weaponstuck = 0;
2000 if (victim->weaponids[0] == int(i))
2001 victim->weaponids[0] = victim->weaponids[victim->num_weapons];
2004 victim->jointVel(abdomen) += relative * 6;
2005 victim->jointVel(neck) += relative * 6;
2006 victim->jointVel(rightshoulder) += relative * 6;
2007 victim->jointVel(leftshoulder) += relative * 6;
2009 weapons[i].owner = id;
2010 if (num_weapons > 0) {
2011 weaponids[num_weapons] = weaponids[0];
2020 if (animCurrent == drawleftanim && animation[animTarget].label[frameCurrent] == 5) {
2021 if (weaponactive == -1)
2023 else if (weaponactive == 0) {
2025 if (num_weapons == 2) {
2027 buffer = weaponids[0];
2028 weaponids[0] = weaponids[1];
2029 weaponids[1] = buffer;
2032 if (weaponactive == -1) {
2033 emit_sound_at(knifesheathesound, coords, 128.);
2035 if (weaponactive != -1) {
2036 emit_sound_at(knifedrawsound, coords, 128.);
2041 if ((animCurrent == walljumprightkickanim && animTarget == walljumprightkickanim) || (animCurrent == walljumpleftkickanim && animTarget == walljumpleftkickanim)) {
2042 XYZ rotatetarget = DoRotation(skeleton.forward, 0, yaw, 0);
2043 Normalise(&rotatetarget);
2044 targetyaw = -asin(0 - rotatetarget.x);
2045 targetyaw *= 360 / 6.28;
2046 if (rotatetarget.z < 0)
2047 targetyaw = 180 - targetyaw;
2049 if (animTarget == walljumprightkickanim)
2051 if (animTarget == walljumpleftkickanim)
2057 if ((animTarget == rabbitrunninganim || animTarget == wolfrunninganim) && frameTarget == 3 && (jumpkeydown || attackkeydown || id != 0))
2060 if (distsq(&victim->coords, &/*Person::players[i]->*/coords) < 5 && victim->aitype == gethelptype && (attackkeydown) && !victim->skeleton.free && victim->isRun() && victim->runninghowlong >= 1)
2065 if ((animTarget == rabbitrunninganim || animTarget == wolfrunninganim) && id == 0) {
2066 animTarget = rabbittackleanim;
2068 emit_sound_at(jumpsound, coords);
2076 targetloc = velocity;
2077 Normalise(&targetloc);
2078 targetloc += coords;
2079 for (unsigned i = 0; i < Person::players.size(); i++) {
2081 if (distsq(&targetloc, &Person::players[i]->coords) < closestdist || closestdist == 0) {
2082 closestdist = distsq(&targetloc, &Person::players[i]->coords);
2086 if (closestid != -1)
2087 if (closestdist < 5 && !Person::players[closestid]->dead && animation[Person::players[closestid]->animTarget].height != lowheight && Person::players[closestid]->animTarget != backhandspringanim) {
2089 victim = Person::players[closestid];
2090 coords = victim->coords;
2091 animCurrent = rabbittacklinganim;
2092 animTarget = rabbittacklinganim;
2096 if (coords.z != victim->coords.z || coords.x != victim->coords.x) {
2097 rotatetarget = coords - victim->coords;
2098 Normalise(&rotatetarget);
2099 targetyaw = -asin(0 - rotatetarget.x);
2100 targetyaw *= 360 / 6.28;
2101 if (rotatetarget.z < 0)
2102 targetyaw = 180 - targetyaw;
2104 if (animTarget != rabbitrunninganim) {
2105 emit_sound_at(jumpsound, coords, 128.);
2111 float damagemult = 1 * power;
2112 if (creature == wolftype)
2113 damagemult = 2.5 * power;
2115 damagemult /= victim->damagetolerance / 200;
2117 //if(onfire)damagemult=3;
2118 if ((animation[animTarget].attack == normalattack || animTarget == walljumprightkickanim || animTarget == walljumpleftkickanim) && (!feint) && (victim->skeleton.free != 2 || animTarget == killanim || animTarget == dropkickanim || animTarget == crouchstabanim || animTarget == swordgroundstabanim || animTarget == staffgroundsmashanim)) {
2119 if (animTarget == spinkickanim && animation[animTarget].label[frameCurrent] == 5) {
2120 if (distsq(&coords, &victim->coords) < (scale * 5) * (scale * 5) * 3 && 3 && animation[victim->animTarget].height != lowheight) {
2124 if (Random() % 2 || creature == wolftype) {
2127 if (creature == wolftype)
2130 if (tutoriallevel != 1) {
2131 emit_sound_at(heavyimpactsound, victim->coords, 128.);
2133 if (creature == wolftype) {
2134 emit_sound_at(clawslicesound, victim->coords, 128.);
2136 victim->DoBloodBig(2 / victim->armorhead, 175);
2140 relative = victim->coords - coords;
2142 Normalise(&relative);
2143 relative = DoRotation(relative, 0, -90, 0);
2144 for (int i = 0; i < victim->skeleton.num_joints; i++) {
2145 victim->skeleton.joints[i].velocity += relative * damagemult * 40;
2147 victim->jointVel(head) += relative * damagemult * 200;
2150 victim->DoDamage(damagemult * 100 / victim->protectionhead);
2156 if (animTarget == wolfslapanim && animation[animTarget].label[frameCurrent] == 5) {
2157 if (distsq(&coords, &victim->coords) < (scale * 5) * (scale * 5) * 3 && 3 && animation[victim->animTarget].height != lowheight) {
2161 if (Random() % 2 || creature == wolftype) {
2163 if (creature == wolftype)
2166 emit_sound_at(whooshhitsound, victim->coords);
2167 if (creature == wolftype) {
2168 emit_sound_at(clawslicesound, victim->coords, 128.);
2170 victim->DoBloodBig(2, 175);
2174 relative = victim->coords - coords;
2176 Normalise(&relative);
2178 Normalise(&relative);
2179 relative = DoRotation(relative, 0, 90, 0);
2180 for (int i = 0; i < victim->skeleton.num_joints; i++) {
2181 victim->skeleton.joints[i].velocity += relative * damagemult * 20;
2183 victim->jointVel(head) += relative * damagemult * 100;
2186 victim->DoDamage(damagemult * 50 / victim->protectionhead);
2190 if (animTarget == walljumprightkickanim && animation[animTarget].label[frameCurrent] == 5) {
2191 if (distsq(&coords, &victim->coords) < (scale * 5) * (scale * 5) * 3 && animation[victim->animTarget].height != lowheight) {
2197 if (tutoriallevel != 1) {
2198 emit_sound_at(heavyimpactsound, victim->coords, 160.);
2200 if (creature == wolftype) {
2201 emit_sound_at(clawslicesound, victim->coords, 128.);
2203 victim->DoBloodBig(2 / victim->armorhead, 175);
2209 Normalise(&relative);
2210 relative = DoRotation(relative, 0, -90, 0);
2211 for (int i = 0; i < victim->skeleton.num_joints; i++) {
2212 victim->skeleton.joints[i].velocity += relative * damagemult * 40;
2214 victim->jointVel(head) += relative * damagemult * 200;
2217 victim->DoDamage(damagemult * 150 / victim->protectionhead);
2219 if (victim->damage > victim->damagetolerance)
2220 award_bonus(id, style);
2226 if (animTarget == walljumpleftkickanim && animation[animTarget].label[frameCurrent] == 5) {
2227 if (distsq(&coords, &victim->coords) < (scale * 5) * (scale * 5) * 3 && animation[victim->animTarget].height != lowheight) {
2233 if (tutoriallevel != 1) {
2234 emit_sound_at(heavyimpactsound, victim->coords, 160.);
2236 if (creature == wolftype) {
2237 emit_sound_at(clawslicesound, victim->coords, 128.);
2239 victim->DoBloodBig(2 / victim->armorhead, 175);
2245 Normalise(&relative);
2246 relative = DoRotation(relative, 0, 90, 0);
2247 for (int i = 0; i < victim->skeleton.num_joints; i++) {
2248 victim->skeleton.joints[i].velocity += relative * damagemult * 40;
2250 victim->jointVel(head) += relative * damagemult * 200;
2253 victim->DoDamage(damagemult * 150 / victim->protectionhead);
2255 if (victim->damage > victim->damagetolerance)
2256 award_bonus(id, style);
2262 if (animTarget == blockhighleftstrikeanim && animation[animTarget].label[frameCurrent] == 5) {
2263 if (distsq(&coords, &victim->coords) < (scale * 5) * (scale * 5) * 3 && animation[victim->animTarget].height != lowheight) {
2271 emit_sound_at(whooshhitsound, victim->coords);
2274 relative = victim->coords - coords;
2276 Normalise(&relative);
2277 for (int i = 0; i < victim->skeleton.num_joints; i++) {
2278 victim->skeleton.joints[i].velocity += relative * damagemult * 30;
2280 victim->jointVel(head) += relative * damagemult * 100;
2283 victim->DoDamage(damagemult * 50 / victim->protectionhead);
2287 if (animTarget == killanim && animation[animTarget].label[frameCurrent] == 8) {
2288 if (distsq(&coords, &victim->coords) < (scale * 5) * (scale * 5) * 3 && victim->dead) {
2292 emit_sound_at(whooshhitsound, victim->coords, 128.);
2294 victim->skeleton.longdead = 0;
2295 victim->skeleton.free = 1;
2296 victim->skeleton.broken = 0;
2297 victim->skeleton.spinny = 1;
2299 for (int i = 0; i < victim->skeleton.num_joints; i++) {
2300 victim->skeleton.joints[i].velchange = 0;
2301 victim->skeleton.joints[i].delay = 0;
2302 victim->skeleton.joints[i].locked = 0;
2303 //victim->skeleton.joints[i].velocity=0;
2309 Normalise(&relative);
2310 for (int i = 0; i < victim->skeleton.num_joints; i++) {
2311 victim->skeleton.joints[i].velocity.y = relative.y * 10;
2312 victim->skeleton.joints[i].position.y += relative.y * .3;
2313 victim->skeleton.joints[i].oldposition.y += relative.y * .3;
2314 victim->skeleton.joints[i].realoldposition.y += relative.y * .3;
2316 victim->Puff(abdomen);
2317 victim->jointVel(abdomen).y = relative.y * 400;
2321 if (animTarget == killanim && animation[animTarget].label[frameCurrent] == 5) {
2322 if (distsq(&coords, &victim->coords) < (scale * 5) * (scale * 5) * 9 && victim->dead) {
2326 if (tutoriallevel != 1) {
2327 emit_sound_at(heavyimpactsound, coords, 128.);
2330 relative = victim->coords - coords;
2332 Normalise(&relative);
2333 for (int i = 0; i < victim->skeleton.num_joints; i++) {
2334 victim->skeleton.joints[i].velocity += relative * damagemult * 90;
2336 victim->Puff(abdomen);
2337 if (victim->dead != 2 && victim->permanentdamage > victim->damagetolerance - 250 && autoslomo) {
2341 victim->DoDamage(damagemult * 500 / victim->protectionhigh);
2342 victim->jointVel(abdomen) += relative * damagemult * 300;
2346 if (animTarget == dropkickanim && animation[animTarget].label[frameCurrent] == 7) {
2347 if (distsq(&coords, &victim->coords) < (scale * 5) * (scale * 5) * 9 && victim->skeleton.free) {
2351 if (tutoriallevel != 1) {
2352 emit_sound_at(thudsound, coords);
2355 victim->skeleton.longdead = 0;
2356 victim->skeleton.free = 1;
2357 victim->skeleton.broken = 0;
2358 victim->skeleton.spinny = 1;
2360 for (int i = 0; i < victim->skeleton.num_joints; i++) {
2361 victim->skeleton.joints[i].velchange = 0;
2362 //victim->skeleton.joints[i].delay=0;
2363 victim->skeleton.joints[i].locked = 0;
2366 relative = victim->coords - coords;
2367 Normalise(&relative);
2369 Normalise(&relative);
2370 for (int i = 0; i < victim->skeleton.num_joints; i++) {
2371 victim->skeleton.joints[i].velocity += relative * damagemult * 20;
2376 victim->Puff(abdomen);
2377 victim->DoDamage(damagemult * 20 / victim->protectionhigh);
2378 victim->jointVel(abdomen) += relative * damagemult * 200;
2387 if ((animTarget == crouchstabanim || animTarget == swordgroundstabanim) && animation[animTarget].label[frameCurrent] == 5) {
2388 //if(id==0)camerashake+=.4;
2391 if (!victim->skeleton.free)
2395 terrain.MakeDecal(blooddecalfast, (weapons[weaponids[weaponactive]].tippoint * .8 + weapons[weaponids[weaponactive]].position * .2), .08, .6, Random() % 360);
2396 emit_sound_at(knifesheathesound, coords, 128.);
2399 if (victim && hasvictim) {
2400 if (distsq(&coords, &victim->coords) < (scale * 5) * (scale * 5) * 3) {
2402 XYZ where, startpoint, endpoint, movepoint, colpoint;
2403 float rotationpoint;
2405 if (weapons[weaponids[weaponactive]].getType() == knife) {
2406 where = (weapons[weaponids[weaponactive]].tippoint * .6 + weapons[weaponids[weaponactive]].position * .4);
2407 where -= victim->coords;
2408 if (!victim->skeleton.free)
2409 where = DoRotation(where, 0, -victim->yaw, 0);
2412 startpoint.y += 100;
2416 if (weapons[weaponids[weaponactive]].getType() == sword) {
2417 where = weapons[weaponids[weaponactive]].position;
2418 where -= victim->coords;
2419 if (!victim->skeleton.free)
2420 where = DoRotation(where, 0, -victim->yaw, 0);
2422 where = weapons[weaponids[weaponactive]].tippoint;
2423 where -= victim->coords;
2424 if (!victim->skeleton.free)
2425 where = DoRotation(where, 0, -victim->yaw, 0);
2428 if (weapons[weaponids[weaponactive]].getType() == staff) {
2429 where = weapons[weaponids[weaponactive]].position;
2430 where -= victim->coords;
2431 if (!victim->skeleton.free)
2432 where = DoRotation(where, 0, -victim->yaw, 0);
2434 where = weapons[weaponids[weaponactive]].tippoint;
2435 where -= victim->coords;
2436 if (!victim->skeleton.free)
2437 where = DoRotation(where, 0, -victim->yaw, 0);
2442 whichtri = victim->skeleton.drawmodel.LineCheck(&startpoint, &endpoint, &colpoint, &movepoint, &rotationpoint);
2444 if (whichtri != -1) {
2445 if (victim->dead != 2) {
2446 victim->DoDamage(abs((victim->damagetolerance - victim->permanentdamage) * 2));
2448 award_bonus(id, FinishedBonus);
2451 weapons[weaponids[weaponactive]].bloody = 2;
2453 victim->skeleton.longdead = 0;
2454 victim->skeleton.free = 1;
2455 victim->skeleton.broken = 0;
2457 for (int i = 0; i < victim->skeleton.num_joints; i++) {
2458 victim->skeleton.joints[i].velchange = 0;
2459 victim->skeleton.joints[i].locked = 0;
2460 //victim->skeleton.joints[i].velocity=0;
2462 emit_sound_at(fleshstabsound, coords, 128);
2465 if (whichtri != -1 || weapons[weaponids[weaponactive]].bloody) {
2466 weapons[weaponids[weaponactive]].blooddrip += 5;
2467 weapons[weaponids[weaponactive]].blooddripdelay = 0;
2469 if (whichtri == -1) {
2471 emit_sound_at(knifesheathesound, coords, 128.);
2477 if ((animTarget == crouchstabanim || animTarget == swordgroundstabanim) && animation[animTarget].label[frameCurrent] == 6) {
2479 emit_sound_at(knifedrawsound, coords, 128);
2482 if (victim && hasvictim) {
2483 XYZ footvel, footpoint;
2485 emit_sound_at(fleshstabremovesound, coords, 128.);
2488 footpoint = (weapons[weaponids[weaponactive]].tippoint * .8 + weapons[weaponids[weaponactive]].position * .2);
2490 if (weapons[weaponids[weaponactive]].getType() == sword) {
2491 XYZ where, startpoint, endpoint, movepoint;
2492 float rotationpoint;
2495 where = weapons[weaponids[weaponactive]].position;
2496 where -= victim->coords;
2497 if (!victim->skeleton.free)
2498 where = DoRotation(where, 0, -victim->yaw, 0);
2500 where = weapons[weaponids[weaponactive]].tippoint;
2501 where -= victim->coords;
2502 if (!victim->skeleton.free)
2503 where = DoRotation(where, 0, -victim->yaw, 0);
2508 whichtri = victim->skeleton.drawmodel.LineCheck(&startpoint, &endpoint, &footpoint, &movepoint, &rotationpoint);
2509 footpoint += victim->coords;
2511 if (whichtri == -1) {
2512 footpoint = (weapons[weaponids[weaponactive]].tippoint * .8 + weapons[weaponids[weaponactive]].position * .2);
2515 if (weapons[weaponids[weaponactive]].getType() == staff) {
2516 XYZ where, startpoint, endpoint, movepoint;
2517 float rotationpoint;
2520 where = weapons[weaponids[weaponactive]].position;
2521 where -= victim->coords;
2522 if (!victim->skeleton.free)
2523 where = DoRotation(where, 0, -victim->yaw, 0);
2525 where = weapons[weaponids[weaponactive]].tippoint;
2526 where -= victim->coords;
2527 if (!victim->skeleton.free)
2528 where = DoRotation(where, 0, -victim->yaw, 0);
2533 whichtri = victim->skeleton.drawmodel.LineCheck(&startpoint, &endpoint, &footpoint, &movepoint, &rotationpoint);
2534 footpoint += victim->coords;
2536 if (whichtri == -1) {
2537 footpoint = (weapons[weaponids[weaponactive]].tippoint * .8 + weapons[weaponids[weaponactive]].position * .2);
2540 hasvictim = victim->DoBloodBigWhere(2, 220, footpoint);
2542 if (distsq(&coords, &victim->coords) < (scale * 5) * (scale * 5) * 3) {
2543 victim->skeleton.longdead = 0;
2544 victim->skeleton.free = 1;
2545 victim->skeleton.broken = 0;
2547 for (int i = 0; i < victim->skeleton.num_joints; i++) {
2548 victim->skeleton.joints[i].velchange = 0;
2549 victim->skeleton.joints[i].locked = 0;
2550 //victim->skeleton.joints[i].velocity=0;
2556 Normalise(&relative);
2557 //victim->Puff(abdomen);
2559 Sprite::MakeSprite(cloudimpactsprite, footpoint, footvel, 1, 0, 0, .8, .3);
2561 if (victim->bloodloss < victim->damagetolerance) {
2562 victim->bloodloss += 1000;
2566 victim->jointVel(abdomen) += relative * damagemult * 20;
2570 if (!hasvictim && onterrain) {
2571 weapons[weaponids[weaponactive]].bloody = 0;
2572 weapons[weaponids[weaponactive]].blooddrip = 0;
2576 if (animTarget == upunchanim && animation[animTarget].label[frameCurrent] == 5) {
2577 if (distsq(&coords, &victim->coords) < (scale * 5) * (scale * 5) * 3) {
2585 if (tutoriallevel != 1) {
2586 emit_sound_at(heavyimpactsound, victim->coords, 128);
2591 relative = victim->coords - coords;
2593 Normalise(&relative);
2594 for (int i = 0; i < victim->skeleton.num_joints; i++) {
2595 victim->skeleton.joints[i].velocity = relative * 30;
2597 victim->jointVel(head) += relative * damagemult * 150;
2599 victim->frameTarget = 0;
2600 victim->animTarget = staggerbackhardanim;
2601 victim->targetyaw = targetyaw + 180;
2603 victim->stunned = 1;
2606 victim->Puff(abdomen);
2607 victim->DoDamage(damagemult * 60 / victim->protectionhigh);
2614 if (animTarget == winduppunchanim && animation[animTarget].label[frameCurrent] == 5) {
2615 if (distsq(&coords, &victim->coords) < (scale * 5) * (scale * 5) * 2) {
2619 if (victim->damage <= victim->damagetolerance - 60 && normaldotproduct(victim->facing, victim->coords - coords) < (scale * 5) * (scale * 5) * 0 && animation[victim->animTarget].height != lowheight) {
2620 if (tutoriallevel != 1) {
2621 emit_sound_at(thudsound, victim->coords);
2623 } else if (victim->damage <= victim->damagetolerance - 60 && normaldotproduct(victim->facing, victim->coords - coords) < (scale * 5) * (scale * 5) * 0 && animation[victim->animTarget].height == lowheight) {
2624 if (tutoriallevel != 1) {
2625 emit_sound_at(whooshhitsound, victim->coords);
2628 if (tutoriallevel != 1) {
2629 emit_sound_at(heavyimpactsound, victim->coords);
2633 if (victim->damage > victim->damagetolerance - 60 || normaldotproduct(victim->facing, victim->coords - coords) > 0 || animation[victim->animTarget].height == lowheight)
2636 relative = victim->coords - coords;
2638 Normalise(&relative);
2640 Normalise(&relative);
2641 for (int i = 0; i < victim->skeleton.num_joints; i++) {
2642 victim->skeleton.joints[i].velocity = relative * 5;
2644 victim->jointVel(abdomen) += relative * damagemult * 400;
2646 victim->frameTarget = 0;
2647 victim->animTarget = staggerbackhardanim;
2648 victim->targetyaw = targetyaw + 180;
2650 victim->stunned = 1;
2652 victim->Puff(abdomen);
2653 victim->DoDamage(damagemult * 60 / victim->protectionhigh);
2659 if (animTarget == blockhighleftanim && animation[animTarget].label[frameCurrent] == 5) {
2660 if (distsq(&coords, &victim->coords) < (scale * 5) * (scale * 5) * 4) {
2661 if (victim->id == 0)
2663 emit_sound_at(landsound2, victim->coords);
2669 if (animTarget == swordslashparryanim && animation[animTarget].label[frameCurrent] == 5) {
2670 if (distsq(&coords, &victim->coords) < (scale * 5) * (scale * 5) * 4) {
2671 if (victim->id == 0)
2674 if (weaponactive != -1) {
2675 if (weapons[victim->weaponids[0]].getType() == staff || weapons[weaponids[0]].getType() == staff) {
2676 if (weapons[victim->weaponids[0]].getType() == staff)
2677 weapons[victim->weaponids[0]].damage += .2 + float(abs(Random() % 100) - 50) / 250;
2678 if (weapons[weaponids[0]].getType() == staff)
2679 weapons[weaponids[0]].damage += .2 + float(abs(Random() % 100) - 50) / 250;
2681 emit_sound_at(swordstaffsound, victim->coords);
2683 emit_sound_at(metalhitsound, victim->coords);
2691 if (animTarget == knifethrowanim && animation[animTarget].label[frameCurrent] == 5) {
2692 if (weaponactive != -1) {
2695 weapons[weaponids[0]].owner = -1;
2696 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);
2698 /*if(victim->animTarget==jumpupanim||victim->animTarget==jumpdownanim){
2699 aim=DoRotation(aim,(float)abs(Random()%15)-7,(float)abs(Random()%15)-7,0);
2701 weapons[weaponids[0]].velocity = aim * 50;
2702 weapons[weaponids[0]].tipvelocity = aim * 50;
2703 weapons[weaponids[0]].missed = 0;
2704 weapons[weaponids[0]].hitsomething = 0;
2705 weapons[weaponids[0]].freetime = 0;
2706 weapons[weaponids[0]].firstfree = 1;
2707 weapons[weaponids[0]].physics = 0;
2710 weaponids[0] = weaponids[num_weapons];
2716 if (animTarget == knifeslashstartanim && animation[animTarget].label[frameCurrent] == 5) {
2718 if (distsq(&coords, &victim->coords) < (scale * 5) * (scale * 5) * 4.5 &&/*animation[victim->animTarget].height!=lowheight&&*/victim->animTarget != dodgebackanim && victim->animTarget != rollanim) {
2720 if (tutoriallevel != 1)
2721 victim->DoBloodBig(1.5 / victim->armorhigh, 225);
2723 award_bonus(id, Slicebonus);
2724 if (tutoriallevel != 1) {
2725 emit_sound_at(knifeslicesound, victim->coords);
2727 //victim->jointVel(abdomen)+=relative*damagemult*200;
2728 if (animation[victim->animTarget].attack && (victim->aitype != playercontrolled || victim->animTarget == knifeslashstartanim) && (victim->creature == rabbittype || victim->deathbleeding <= 0)) {
2729 if (victim->id != 0 || difficulty == 2) {
2730 victim->frameTarget = 0;
2731 victim->animTarget = staggerbackhardanim;
2732 victim->targetyaw = targetyaw + 180;
2736 victim->lowreversaldelay = 0;
2737 victim->highreversaldelay = 0;
2738 if (aitype != playercontrolled)
2739 weaponmissdelay = .6;
2741 if (tutoriallevel != 1)
2742 if (bloodtoggle && !weapons[weaponids[weaponactive]].bloody)
2743 weapons[weaponids[weaponactive]].bloody = 1;
2744 if (tutoriallevel != 1)
2745 weapons[weaponids[weaponactive]].blooddrip += 3;
2747 XYZ footvel, footpoint;
2749 if (skeleton.free) {
2750 footpoint = (victim->jointPos(abdomen) + victim->jointPos(neck)) / 2 * victim->scale + victim->coords;
2752 if (!skeleton.free) {
2753 footpoint = DoRotation((victim->jointPos(abdomen) + victim->jointPos(neck)) / 2, 0, victim->yaw, 0) * victim->scale + victim->coords;
2755 if (tutoriallevel != 1) {
2757 Sprite::MakeSprite(cloudimpactsprite, footpoint, footvel, 1, 0, 0, .6, .3);
2758 footvel = DoRotation(facing, 0, 90, 0) * .8;
2760 Sprite::MakeSprite(bloodsprite, footpoint, DoRotation(footvel * 7, (float)(Random() % 20), (float)(Random() % 20), 0), 1, 1, 1, .05, .9);
2761 Sprite::MakeSprite(bloodsprite, footpoint, DoRotation(footvel * 3, (float)(Random() % 20), (float)(Random() % 20), 0), 1, 1, 1, .05, .9);
2762 Sprite::MakeSprite(bloodflamesprite, footpoint, footvel * 5, 1, 1, 1, .2, 1);
2763 Sprite::MakeSprite(bloodflamesprite, footpoint, footvel * 2, 1, 1, 1, .2, 1);
2765 if (tutoriallevel == 1) {
2766 Sprite::MakeSprite(cloudimpactsprite, footpoint, footvel, 1, 1, 1, .6, .3);
2768 victim->DoDamage(damagemult * 0);
2771 if (animTarget == swordslashanim && animation[animTarget].label[frameCurrent] == 5 && victim->animTarget != rollanim) {
2772 if (distsq(&coords, &victim->coords) < (scale * 5) * (scale * 5) * 6.5 && victim->animTarget != dodgebackanim) {
2773 if (victim->weaponactive == -1 || normaldotproduct(victim->facing, victim->coords - coords) > 0 || (Random() % 2 == 0)) {
2774 award_bonus(id, Slashbonus);
2776 if (tutoriallevel != 1) {
2777 if (normaldotproduct(victim->facing, victim->coords - coords) < 0)
2778 victim->DoBloodBig(2 / victim->armorhigh, 190);
2780 victim->DoBloodBig(2 / victim->armorhigh, 185);
2781 victim->deathbleeding = 1;
2782 emit_sound_at(swordslicesound, victim->coords);
2784 //victim->jointVel(abdomen)+=relative*damagemult*200;
2785 if (tutoriallevel != 1) {
2786 victim->frameTarget = 0;
2787 victim->animTarget = staggerbackhardanim;
2788 victim->targetyaw = targetyaw + 180;
2792 if (tutoriallevel != 1) {
2793 if (bloodtoggle && !weapons[weaponids[weaponactive]].bloody)
2794 weapons[weaponids[weaponactive]].bloody = 1;
2795 weapons[weaponids[weaponactive]].blooddrip += 3;
2797 float bloodlossamount;
2798 bloodlossamount = 200 + abs((float)(Random() % 40)) - 20;
2799 victim->bloodloss += bloodlossamount / victim->armorhigh;
2800 //victim->bloodloss+=100*(6.5-distsq(&coords,&victim->coords));
2801 victim->DoDamage(damagemult * 0);
2803 XYZ footvel, footpoint;
2805 if (skeleton.free) {
2806 footpoint = (victim->jointPos(abdomen) + victim->jointPos(neck)) / 2 * victim->scale + victim->coords;
2808 if (!skeleton.free) {
2809 footpoint = DoRotation((victim->jointPos(abdomen) + victim->jointPos(neck)) / 2, 0, victim->yaw, 0) * victim->scale + victim->coords;
2812 Sprite::MakeSprite(cloudimpactsprite, footpoint, footvel, 1, 0, 0, .9, .3);
2813 footvel = DoRotation(facing, 0, 90, 0) * .8;
2815 Sprite::MakeSprite(bloodsprite, footpoint, DoRotation(footvel * 7, (float)(Random() % 20), (float)(Random() % 20), 0), 1, 1, 1, .05, .9);
2816 Sprite::MakeSprite(bloodsprite, footpoint, DoRotation(footvel * 3, (float)(Random() % 20), (float)(Random() % 20), 0), 1, 1, 1, .05, .9);
2817 Sprite::MakeSprite(bloodflamesprite, footpoint, footvel * 5, 1, 1, 1, .3, 1);
2818 Sprite::MakeSprite(bloodflamesprite, footpoint, footvel * 2, 1, 1, 1, .3, 1);
2821 if (victim->weaponactive != -1) {
2822 if (weapons[victim->weaponids[0]].getType() == staff || weapons[weaponids[0]].getType() == staff) {
2823 if (weapons[victim->weaponids[0]].getType() == staff)
2824 weapons[victim->weaponids[0]].damage += .2 + float(abs(Random() % 100) - 50) / 250;
2825 if (weapons[weaponids[0]].getType() == staff)
2826 weapons[weaponids[0]].damage += .2 + float(abs(Random() % 100) - 50) / 250;
2828 emit_sound_at(swordstaffsound, victim->coords);
2830 emit_sound_at(metalhitsound, victim->coords);
2836 victim->Puff(righthand);
2838 victim->frameTarget = 0;
2839 victim->animTarget = staggerbackhighanim;
2840 victim->targetyaw = targetyaw + 180;
2842 weapons[victim->weaponids[0]].owner = -1;
2843 aim = DoRotation(facing, 0, 90, 0) * 21;
2845 weapons[victim->weaponids[0]].velocity = aim * -.2;
2846 weapons[victim->weaponids[0]].tipvelocity = aim;
2847 weapons[victim->weaponids[0]].missed = 1;
2848 weapons[weaponids[0]].hitsomething = 0;
2849 weapons[victim->weaponids[0]].freetime = 0;
2850 weapons[victim->weaponids[0]].firstfree = 1;
2851 weapons[victim->weaponids[0]].physics = 1;
2852 victim->num_weapons--;
2853 if (victim->num_weapons) {
2854 victim->weaponids[0] = victim->weaponids[num_weapons];
2855 if (victim->weaponstuck == victim->num_weapons)
2856 victim->weaponstuck = 0;
2858 victim->weaponactive = -1;
2859 for (unsigned i = 0; i < Person::players.size(); i++) {
2860 Person::players[i]->wentforweapon = 0;
2867 if (animTarget == staffhitanim && animation[animTarget].label[frameCurrent] == 5 && victim->animTarget != rollanim) {
2868 if (distsq(&coords, &victim->coords) < (scale * 5) * (scale * 5) * 6.5 && victim->animTarget != dodgebackanim && victim->animTarget != sweepanim) {
2869 if (tutoriallevel != 1) {
2870 weapons[weaponids[0]].damage += .4 + float(abs(Random() % 100) - 50) / 250;
2874 if (Random() % 2 || creature == wolftype) {
2877 emit_sound_at(staffheadsound, victim->coords);
2881 relative = victim->coords - coords;
2883 Normalise(&relative);
2884 relative = DoRotation(relative, 0, 90, 0);
2886 Normalise(&relative);
2887 for (int i = 0; i < victim->skeleton.num_joints; i++) {
2888 victim->skeleton.joints[i].velocity += relative * damagemult * 60;
2890 victim->jointVel(head) += relative * damagemult * 230;
2891 victim->jointVel(neck) += relative * damagemult * 230;
2894 if (tutoriallevel != 1) {
2895 victim->DoDamage(damagemult * 120 / victim->protectionhigh);
2897 award_bonus(id, solidhit, 30);
2902 if (animTarget == staffspinhitanim && animation[animTarget].label[frameCurrent] == 5 && victim->animTarget != rollanim) {
2903 if (distsq(&coords, &victim->coords) < (scale * 5) * (scale * 5) * 6.5 && victim->animTarget != dodgebackanim && victim->animTarget != sweepanim) {
2904 if (tutoriallevel != 1) {
2905 weapons[weaponids[0]].damage += .6 + float(abs(Random() % 100) - 50) / 250;
2909 if (Random() % 2 || creature == wolftype) {
2912 emit_sound_at(staffheadsound, victim->coords);
2916 relative = victim->coords - coords;
2918 Normalise(&relative);
2919 relative = DoRotation(relative, 0, -90, 0);
2920 for (int i = 0; i < victim->skeleton.num_joints; i++) {
2921 victim->skeleton.joints[i].velocity += relative * damagemult * 40;
2923 victim->jointVel(head) += relative * damagemult * 220;
2924 victim->jointVel(neck) += relative * damagemult * 220;
2927 if (tutoriallevel != 1) {
2928 victim->DoDamage(damagemult * 350 / victim->protectionhead);
2930 award_bonus(id, solidhit, 60);
2935 if (animTarget == staffgroundsmashanim && animation[animTarget].label[frameCurrent] == 5) {
2936 if (distsq(&coords, &victim->coords) < (scale * 5) * (scale * 5) * 6.5) {
2938 if (tutoriallevel != 1) {
2940 weapons[weaponids[0]].damage += .4 + float(abs(Random() % 100) - 50) / 500;
2943 if (Random() % 2 || creature == wolftype) {
2946 emit_sound_at(staffbodysound, victim->coords);
2948 victim->skeleton.longdead = 0;
2949 victim->skeleton.free = 1;
2950 victim->skeleton.broken = 0;
2952 for (int i = 0; i < victim->skeleton.num_joints; i++) {
2953 victim->skeleton.joints[i].velchange = 0;
2954 victim->skeleton.joints[i].locked = 0;
2955 //victim->skeleton.joints[i].velocity=0;
2961 /*relative=victim->coords-coords;
2963 Normalise(&relative);
2964 relative=DoRotation(relative,0,90,0);*/
2966 Normalise(&relative);
2967 if (!victim->dead) {
2968 for (int i = 0; i < victim->skeleton.num_joints; i++) {
2969 victim->skeleton.joints[i].velocity = relative * damagemult * 40;
2972 victim->jointVel(abdomen) += relative * damagemult * 40;
2975 for (int i = 0; i < victim->skeleton.num_joints; i++) {
2976 victim->skeleton.joints[i].velocity = relative * damagemult * abs(Random() % 20);
2979 //victim->jointVel(abdomen)+=relative*damagemult*20;
2981 victim->Puff(abdomen);
2982 if (tutoriallevel != 1) {
2983 victim->DoDamage(damagemult * 100 / victim->protectionhigh);
2985 if (!victim->dead) {
2986 award_bonus(id, solidhit, 40);
2992 if (animTarget == lowkickanim && animation[animTarget].label[frameCurrent] == 5) {
2993 if (distsq(&coords, &victim->coords) < (scale * 5) * (scale * 5) * 3 && animation[victim->animTarget].height != highheight) {
2998 relative = victim->coords - coords;
3000 Normalise(&relative);
3004 if (animation[victim->animTarget].height == lowheight) {
3010 for (int i = 0; i < victim->skeleton.num_joints; i++) {
3011 victim->skeleton.joints[i].velocity += relative * damagemult * 40;
3013 victim->jointVel(head) += relative * damagemult * 200;
3014 if (tutoriallevel != 1) {
3015 emit_sound_at(heavyimpactsound, victim->coords, 128.);
3018 victim->DoDamage(damagemult * 100 / victim->protectionhead);
3019 if (victim->howactive == typesleeping)
3020 victim->DoDamage(damagemult * 150 / victim->protectionhead);
3021 if (creature == wolftype) {
3022 emit_sound_at(clawslicesound, victim->coords, 128.);
3024 victim->DoBloodBig(2 / victim->armorhead, 175);
3027 if (victim->damage >= victim->damagetolerance)
3029 for (int i = 0; i < victim->skeleton.num_joints; i++) {
3030 victim->skeleton.joints[i].velocity += relative * damagemult * 10;
3032 victim->jointVel(abdomen) += relative * damagemult * 200;
3033 victim->frameTarget = 0;
3034 victim->animTarget = staggerbackhighanim;
3035 victim->targetyaw = targetyaw + 180;
3037 if (tutoriallevel != 1) {
3038 emit_sound_at(landsound2, victim->coords, 128.);
3040 victim->Puff(abdomen);
3041 victim->DoDamage(damagemult * 30 / victim->protectionhigh);
3042 if (creature == wolftype) {
3043 emit_sound_at(clawslicesound, victim->coords, 128.);
3045 victim->DoBloodBig(2 / victim->armorhigh, 170);
3052 if (animTarget == sweepanim && animation[animTarget].label[frameCurrent] == 5) {
3053 if ((victim->animTarget != jumpupanim) &&
3054 (distsq(&coords, &victim->coords) < (scale * 5) * (scale * 5) * 3) &&
3055 (victim != this->shared_from_this())) {
3059 if (tutoriallevel != 1) {
3060 emit_sound_at(landsound2, victim->coords, 128.);
3063 relative = victim->coords - coords;
3065 Normalise(&relative);
3067 if (animation[victim->animTarget].height == middleheight || animation[victim->animCurrent].height == middleheight || victim->damage >= victim->damagetolerance - 40) {
3070 for (int i = 0; i < victim->skeleton.num_joints; i++) {
3071 victim->skeleton.joints[i].velocity += relative * damagemult * 15;
3073 relative = DoRotation(relative, 0, -90, 0);
3075 for (int i = 0; i < victim->skeleton.num_joints; i++) {
3076 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)
3077 victim->skeleton.joints[i].velocity = relative * 80;
3079 victim->Puff(rightankle);
3080 victim->Puff(leftankle);
3081 victim->DoDamage(damagemult * 40 / victim->protectionlow);
3083 if (victim->damage >= victim->damagetolerance)
3085 for (int i = 0; i < victim->skeleton.num_joints; i++) {
3086 victim->skeleton.joints[i].velocity += relative * damagemult * 10;
3088 relative = DoRotation(relative, 0, -90, 0);
3089 for (int i = 0; i < victim->skeleton.num_joints; i++) {
3090 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)
3091 victim->skeleton.joints[i].velocity += relative * damagemult * 80;
3093 victim->jointVel(abdomen) += relative * damagemult * 200;
3094 victim->frameTarget = 0;
3095 victim->animTarget = staggerbackhighanim;
3096 victim->targetyaw = targetyaw + 180;
3098 if (tutoriallevel != 1) {
3099 emit_sound_at(landsound2, victim->coords, 128.);
3101 victim->Puff(abdomen);
3102 victim->DoDamage(damagemult * 30 / victim->protectionlow);
3110 if (animation[animTarget].attack == reversal && (!victim->feint || (victim->lastattack == victim->lastattack2 && victim->lastattack2 == victim->lastattack3 && Random() % 2) || animTarget == knifefollowanim)) {
3111 if (animTarget == spinkickreversalanim && animation[animTarget].label[frameCurrent] == 7) {
3119 if (tutoriallevel != 1) {
3120 emit_sound_at(heavyimpactsound, victim->coords, 128.);
3122 if (creature == wolftype) {
3123 emit_sound_at(clawslicesound, victim->coords, 128);
3125 victim->DoBloodBig(2 / victim->armorhigh, 170);
3129 relative = victim->coords - oldcoords;
3131 Normalise(&relative);
3132 //relative=DoRotation(relative,0,-90,0);
3133 for (int i = 0; i < victim->skeleton.num_joints; i++) {
3134 victim->skeleton.joints[i].velocity += relative * damagemult * 40;
3136 victim->jointVel(abdomen) += relative * damagemult * 200;
3138 victim->Puff(abdomen);
3139 victim->DoDamage(damagemult * 150 / victim->protectionhigh);
3141 award_bonus(id, Reversal);
3144 if ((animTarget == swordslashreversalanim || animTarget == knifeslashreversalanim || animTarget == staffhitreversalanim || animTarget == staffspinhitreversalanim) && animation[animTarget].label[frameCurrent] == 5) {
3145 if (victim->weaponactive != -1 && victim->num_weapons > 0) {
3146 if (weapons[victim->weaponids[victim->weaponactive]].owner == int(victim->id)) {
3147 weapons[victim->weaponids[victim->weaponactive]].owner = id;
3149 if (num_weapons > 0) {
3150 weaponids[num_weapons] = weaponids[victim->weaponactive];
3153 weaponids[0] = victim->weaponids[victim->weaponactive];
3154 victim->num_weapons--;
3155 if (victim->num_weapons > 0) {
3156 victim->weaponids[victim->weaponactive] = victim->weaponids[victim->num_weapons];
3157 //if(victim->weaponstuck==victim->num_weapons)victim->weaponstuck=0;
3159 victim->weaponactive = -1;
3164 if (animTarget == staffhitreversalanim && animation[animTarget].label[frameCurrent] == 5) {
3172 emit_sound_at(whooshhitsound, victim->coords, 128.);
3175 relative = victim->coords - oldcoords;
3177 Normalise(&relative);
3178 //relative=DoRotation(relative,0,-90,0);
3179 for (int i = 0; i < victim->skeleton.num_joints; i++) {
3180 victim->skeleton.joints[i].velocity += relative * damagemult * 30;
3182 victim->jointVel(abdomen) += relative * damagemult * 200;
3185 victim->DoDamage(damagemult * 70 / victim->protectionhigh);
3188 if (animTarget == staffspinhitreversalanim && animation[animTarget].label[frameCurrent] == 7) {
3197 award_bonus(id, staffreversebonus);
3199 if (tutoriallevel != 1) {
3200 emit_sound_at(heavyimpactsound, victim->coords, 128.);
3203 award_bonus(id, staffreversebonus); // Huh, again?
3206 relative = victim->coords - oldcoords;
3208 Normalise(&relative);
3209 //relative=DoRotation(relative,0,-90,0);
3210 for (int i = 0; i < victim->skeleton.num_joints; i++) {
3211 victim->skeleton.joints[i].velocity += relative * damagemult * 30;
3213 victim->jointVel(abdomen) += relative * damagemult * 200;
3216 victim->DoDamage(damagemult * 70 / victim->protectionhigh);
3219 if (animTarget == upunchreversalanim && animation[animTarget].label[frameCurrent] == 7) {
3225 Normalise(&relative);
3228 for (int i = 0; i < victim->skeleton.num_joints; i++) {
3229 victim->skeleton.joints[i].velocity += relative * damagemult * 70;
3231 victim->jointVel(lefthand) *= .1;
3232 victim->jointVel(leftwrist) *= .2;
3233 victim->jointVel(leftelbow) *= .5;
3234 victim->jointVel(leftshoulder) *= .7;
3235 victim->jointVel(righthand) *= .1;
3236 victim->jointVel(rightwrist) *= .2;
3237 victim->jointVel(rightelbow) *= .5;
3238 victim->jointVel(rightshoulder) *= .7;
3240 victim->Puff(abdomen);
3241 victim->DoDamage(damagemult * 90 / victim->protectionhigh);
3243 award_bonus(id, Reversal);
3247 if (weaponactive != -1 || creature == wolftype)
3249 if (creature == rabbittype && weaponactive != -1)
3250 if (weapons[weaponids[0]].getType() == staff)
3253 if (weaponactive != -1) {
3254 victim->DoBloodBig(2 / victim->armorhigh, 225);
3255 emit_sound_at(knifeslicesound, victim->coords);
3256 if (bloodtoggle && !weapons[weaponids[weaponactive]].bloody)
3257 weapons[weaponids[weaponactive]].bloody = 1;
3258 weapons[weaponids[weaponactive]].blooddrip += 3;
3260 if (weaponactive == -1 && creature == wolftype) {
3262 emit_sound_at(clawslicesound, victim->coords, 128.);
3264 victim->DoBloodBig(2 / victim->armorhigh, 175);
3271 if (animTarget == swordslashreversalanim && animation[animTarget].label[frameCurrent] == 7) {
3277 Normalise(&relative);
3280 for (int i = 0; i < victim->skeleton.num_joints; i++) {
3281 victim->skeleton.joints[i].velocity += relative * damagemult * 70;
3283 victim->jointVel(lefthand) *= .1 - 1;
3284 victim->jointVel(leftwrist) *= .2 - 1;
3285 victim->jointVel(leftelbow) *= .5 - 1;
3286 victim->jointVel(leftshoulder) *= .7 - 1;
3287 victim->jointVel(righthand) *= .1 - 1;
3288 victim->jointVel(rightwrist) *= .2 - 1;
3289 victim->jointVel(rightelbow) *= .5 - 1;
3290 victim->jointVel(rightshoulder) *= .7 - 1;
3292 award_bonus(id, swordreversebonus);
3295 if (hasvictim && animTarget == knifeslashreversalanim && animation[animTarget].label[frameCurrent] == 7) {
3303 if (tutoriallevel != 1) {
3304 emit_sound_at(heavyimpactsound, victim->coords, 128.);
3308 relative = victim->coords - oldcoords;
3310 Normalise(&relative);
3311 relative = DoRotation(relative, 0, -90, 0);
3312 for (int i = 0; i < victim->skeleton.num_joints; i++) {
3313 victim->skeleton.joints[i].velocity += relative * damagemult * 40;
3315 victim->jointVel(abdomen) += relative * damagemult * 200;
3317 victim->Puff(abdomen);
3318 victim->DoDamage(damagemult * 30 / victim->protectionhigh);
3320 award_bonus(id, Reversal);
3323 if (hasvictim && animTarget == sneakattackanim && animation[animTarget].label[frameCurrent] == 7) {
3326 victim->skeleton.spinny = 0;
3328 relative = facing * -1;
3330 Normalise(&relative);
3331 if (victim->id == 0)
3333 for (int i = 0; i < victim->skeleton.num_joints; i++) {
3334 victim->skeleton.joints[i].velocity += relative * damagemult * 40;
3336 //victim->DoDamage(1000);
3337 victim->damage = victim->damagetolerance;
3338 victim->permanentdamage = victim->damagetolerance - 1;
3341 if (weaponactive != -1 || creature == wolftype)
3343 if (creature == rabbittype && weaponactive != -1)
3344 if (weapons[weaponids[0]].getType() == staff)
3347 if (weaponactive != -1) {
3348 victim->DoBloodBig(200, 225);
3349 emit_sound_at(knifeslicesound, victim->coords);
3351 weapons[weaponids[weaponactive]].bloody = 2;
3352 weapons[weaponids[weaponactive]].blooddrip += 5;
3355 if (creature == wolftype && weaponactive == -1) {
3356 emit_sound_at(clawslicesound, victim->coords, 128.);
3358 victim->DoBloodBig(2, 175);
3361 award_bonus(id, spinecrusher);
3364 if (hasvictim && (animTarget == knifefollowanim || animTarget == knifesneakattackanim) && animation[animTarget].label[frameCurrent] == 5) {
3365 if (weaponactive != -1 && victim->bloodloss < victim->damagetolerance) {
3367 if (animTarget == knifefollowanim)
3368 victim->DoBloodBig(200, 210);
3369 if (animTarget == knifesneakattackanim) {
3370 /*victim->DoBloodBig(200,195);
3375 bloodvel=DoRotation(bloodvel,((float)(Random()%100))/4,yaw+((float)(Random()%100))/4,0)*scale;
3376 Sprite::MakeSprite(bloodsprite, DoRotation(jointPos(neck),0,yaw,0)*scale+coords,bloodvel, 1,1,1, .05, 1);
3378 XYZ footvel, footpoint;
3380 footpoint = weapons[weaponids[0]].tippoint;
3382 Sprite::MakeSprite(cloudimpactsprite, footpoint, footvel, 1, 0, 0, .9, .3);
3383 footvel = (weapons[weaponids[0]].tippoint - weapons[weaponids[0]].position);
3384 Sprite::MakeSprite(bloodsprite, footpoint, DoRotation(footvel * 7, (float)(Random() % 20), (float)(Random() % 20), 0), 1, 1, 1, .05, .9);
3385 Sprite::MakeSprite(bloodsprite, footpoint, DoRotation(footvel * 3, (float)(Random() % 20), (float)(Random() % 20), 0), 1, 1, 1, .05, .9);
3386 Sprite::MakeSprite(bloodflamesprite, footpoint, footvel * 5, 1, 1, 1, .3, 1);
3387 Sprite::MakeSprite(bloodflamesprite, footpoint, footvel * 2, 1, 1, 1, .3, 1);
3388 victim->DoBloodBig(200, 195);
3389 award_bonus(id, tracheotomy);
3391 if (animTarget == knifefollowanim) {
3392 award_bonus(id, Stabbonus);
3393 XYZ footvel, footpoint;
3395 footpoint = weapons[weaponids[0]].tippoint;
3397 Sprite::MakeSprite(cloudimpactsprite, footpoint, footvel, 1, 0, 0, .9, .3);
3398 footvel = (weapons[weaponids[0]].tippoint - weapons[weaponids[0]].position) * -1;
3399 Sprite::MakeSprite(bloodsprite, footpoint, DoRotation(footvel * 7, (float)(Random() % 20), (float)(Random() % 20), 0), 1, 1, 1, .05, .9);
3400 Sprite::MakeSprite(bloodsprite, footpoint, DoRotation(footvel * 3, (float)(Random() % 20), (float)(Random() % 20), 0), 1, 1, 1, .05, .9);
3401 Sprite::MakeSprite(bloodflamesprite, footpoint, footvel * 5, 1, 1, 1, .2, 1);
3402 Sprite::MakeSprite(bloodflamesprite, footpoint, footvel * 2, 1, 1, 1, .2, 1);
3405 victim->bloodloss += 10000;
3406 victim->velocity = 0;
3407 emit_sound_at(fleshstabsound, victim->coords);
3409 weapons[weaponids[weaponactive]].bloody = 2;
3410 weapons[weaponids[weaponactive]].blooddrip += 5;
3414 if (hasvictim && (animTarget == knifefollowanim || animTarget == knifesneakattackanim) && animation[animTarget].label[frameCurrent] == 6) {
3416 victim->velocity = 0;
3417 for (int i = 0; i < victim->skeleton.num_joints; i++) {
3418 victim->skeleton.joints[i].velocity = 0;
3420 if (animTarget == knifefollowanim) {
3422 for (int i = 0; i < victim->skeleton.num_joints; i++) {
3423 victim->skeleton.joints[i].velocity = 0;
3426 if (weaponactive != -1 && animation[victim->animTarget].attack != reversal) {
3427 emit_sound_at(fleshstabremovesound, victim->coords);
3429 weapons[weaponids[weaponactive]].bloody = 2;
3430 weapons[weaponids[weaponactive]].blooddrip += 5;
3432 XYZ footvel, footpoint;
3434 footpoint = weapons[weaponids[0]].tippoint;
3436 Sprite::MakeSprite(cloudimpactsprite, footpoint, footvel, 1, 0, 0, .9, .3);
3437 footvel = (weapons[weaponids[0]].tippoint - weapons[weaponids[0]].position) * -1;
3438 Sprite::MakeSprite(bloodsprite, footpoint, DoRotation(footvel * 7, (float)(Random() % 20), (float)(Random() % 20), 0), 1, 1, 1, .05, .9);
3439 Sprite::MakeSprite(bloodsprite, footpoint, DoRotation(footvel * 3, (float)(Random() % 20), (float)(Random() % 20), 0), 1, 1, 1, .05, .9);
3440 Sprite::MakeSprite(bloodflamesprite, footpoint, footvel * 5, 1, 1, 1, .3, 1);
3441 Sprite::MakeSprite(bloodflamesprite, footpoint, footvel * 2, 1, 1, 1, .3, 1);
3445 if (hasvictim && (animTarget == swordsneakattackanim) && animation[animTarget].label[frameCurrent] == 5) {
3446 if (weaponactive != -1 && victim->bloodloss < victim->damagetolerance) {
3447 award_bonus(id, backstab);
3451 XYZ footvel, footpoint;
3453 footpoint = (weapons[weaponids[0]].tippoint + weapons[weaponids[0]].position) / 2;
3455 Sprite::MakeSprite(cloudimpactsprite, footpoint, footvel, 1, 0, 0, .9, .3);
3456 footvel = (weapons[weaponids[0]].tippoint - weapons[weaponids[0]].position);
3457 Sprite::MakeSprite(bloodsprite, footpoint, DoRotation(footvel * 7, (float)(Random() % 20), (float)(Random() % 20), 0), 1, 1, 1, .05, .9);
3458 Sprite::MakeSprite(bloodsprite, footpoint, DoRotation(footvel * 3, (float)(Random() % 20), (float)(Random() % 20), 0), 1, 1, 1, .05, .9);
3459 Sprite::MakeSprite(bloodflamesprite, footpoint, DoRotation(footvel * 5, (float)(Random() % 20), (float)(Random() % 20), 0), 1, 1, 1, .3, 1);
3460 Sprite::MakeSprite(bloodflamesprite, footpoint, DoRotation(footvel * 3, (float)(Random() % 20), (float)(Random() % 20), 0), 1, 1, 1, .3, 1);
3461 victim->DoBloodBig(200, 180);
3462 victim->DoBloodBig(200, 215);
3463 victim->bloodloss += 10000;
3464 victim->velocity = 0;
3465 emit_sound_at(fleshstabsound, victim->coords);
3467 weapons[weaponids[weaponactive]].bloody = 2;
3468 weapons[weaponids[weaponactive]].blooddrip += 5;
3472 if (hasvictim && animTarget == swordsneakattackanim && animation[animTarget].label[frameCurrent] == 6) {
3474 victim->velocity = 0;
3475 for (int i = 0; i < victim->skeleton.num_joints; i++) {
3476 victim->skeleton.joints[i].velocity = 0;
3478 if (weaponactive != -1) {
3479 emit_sound_at(fleshstabremovesound, victim->coords);
3481 weapons[weaponids[weaponactive]].bloody = 2;
3482 weapons[weaponids[weaponactive]].blooddrip += 5;
3484 XYZ footvel, footpoint;
3486 footpoint = weapons[weaponids[0]].tippoint;
3488 Sprite::MakeSprite(cloudimpactsprite, footpoint, footvel, 1, 0, 0, .9, .3);
3489 footvel = (weapons[weaponids[0]].tippoint - weapons[weaponids[0]].position) * -1;
3490 Sprite::MakeSprite(bloodsprite, footpoint, DoRotation(footvel * 7, (float)(Random() % 20), (float)(Random() % 20), 0), 1, 1, 1, .05, .9);
3491 Sprite::MakeSprite(bloodsprite, footpoint, DoRotation(footvel * 3, (float)(Random() % 20), (float)(Random() % 20), 0), 1, 1, 1, .05, .9);
3492 Sprite::MakeSprite(bloodflamesprite, footpoint, footvel * 5, 1, 1, 1, .3, 1);
3493 Sprite::MakeSprite(bloodflamesprite, footpoint, footvel * 2, 1, 1, 1, .3, 1);
3497 if (animTarget == sweepreversalanim && animation[animTarget].label[frameCurrent] == 7) {
3505 if (weaponactive == -1) {
3506 if (tutoriallevel != 1) {
3507 emit_sound_at(heavyimpactsound, victim->coords, 128.);
3512 if (weaponactive != -1 || creature == wolftype)
3514 if (creature == rabbittype && weaponactive != -1)
3515 if (weapons[weaponids[0]].getType() == staff)
3518 if (weaponactive != -1) {
3519 victim->DoBloodBig(2 / victim->armorhead, 225);
3520 emit_sound_at(knifeslicesound, victim->coords);
3521 if (bloodtoggle && !weapons[weaponids[weaponactive]].bloody)
3522 weapons[weaponids[weaponactive]].bloody = 1;
3523 weapons[weaponids[weaponactive]].blooddrip += 3;
3525 if (weaponactive == -1 && creature == wolftype) {
3526 emit_sound_at(clawslicesound, victim->coords, 128.);
3528 victim->DoBloodBig(2 / victim->armorhead, 175);
3532 award_bonus(id, Reversal);
3537 //relative=victim->coords-oldcoords;
3538 relative = facing * -1;
3540 Normalise(&relative);
3541 relative = DoRotation(relative, 0, 90, 0);
3543 Normalise(&relative);
3544 for (int i = 0; i < victim->skeleton.num_joints; i++) {
3545 victim->skeleton.joints[i].velocity += relative * damagemult * 20;
3547 victim->jointVel(head) += relative * damagemult * 200;
3548 if (victim->damage < victim->damagetolerance - 100)
3549 victim->velocity = relative * 200;
3550 victim->DoDamage(damagemult * 100 / victim->protectionhead);
3551 victim->velocity = 0;
3554 if (animTarget == sweepreversalanim && ((animation[animTarget].label[frameCurrent] == 9 && victim->damage < victim->damagetolerance) || (animation[animTarget].label[frameCurrent] == 7 && victim->damage > victim->damagetolerance))) {
3558 //relative=victim->coords-oldcoords;
3559 relative = facing * -1;
3561 Normalise(&relative);
3562 relative = DoRotation(relative, 0, 90, 0);
3564 Normalise(&relative);
3565 for (int i = 0; i < victim->skeleton.num_joints; i++) {
3566 victim->skeleton.joints[i].velocity += relative * damagemult * 20;
3568 victim->jointVel(head) += relative * damagemult * 200;
3571 if (hasvictim && (animTarget == spinkickreversalanim || animTarget == sweepreversalanim || animTarget == rabbitkickreversalanim || animTarget == upunchreversalanim || animTarget == jumpreversalanim || animTarget == swordslashreversalanim || animTarget == knifeslashreversalanim || animTarget == rabbittacklereversal || animTarget == wolftacklereversal || animTarget == staffhitreversalanim || animTarget == staffspinhitreversalanim))
3572 if (victim->damage > victim->damagetolerance && bonus != reverseko) {
3573 award_bonus(id, reverseko);
3579 if (frameTarget > animation[animCurrent].numframes - 1) {
3582 animTarget = getIdle();
3586 if (animCurrent == rabbittackleanim || animCurrent == rabbittacklinganim) {
3587 animTarget = rollanim;
3589 emit_sound_at(movewhooshsound, coords, 128.);
3591 if (animCurrent == staggerbackhighanim) {
3592 animTarget = getIdle();
3594 if (animCurrent == staggerbackhardanim) {
3595 animTarget = getIdle();
3597 if (animCurrent == removeknifeanim) {
3598 animTarget = getIdle();
3600 if (animCurrent == crouchremoveknifeanim) {
3601 animTarget = getCrouch();
3603 if (animCurrent == backhandspringanim) {
3604 animTarget = getIdle();
3606 if (animCurrent == dodgebackanim) {
3607 animTarget = getIdle();
3609 if (animCurrent == drawleftanim) {
3610 animTarget = getIdle();
3612 if (animCurrent == drawrightanim || animCurrent == crouchdrawrightanim) {
3613 animTarget = getIdle();
3614 if (animCurrent == crouchdrawrightanim) {
3615 animTarget = getCrouch();
3617 if (weaponactive == -1)
3619 else if (weaponactive == 0) {
3621 if (num_weapons == 2) {
3623 buffer = weaponids[0];
3624 weaponids[0] = weaponids[1];
3625 weaponids[1] = buffer;
3629 if (weaponactive == -1) {
3630 emit_sound_at(knifesheathesound, coords, 128.);
3632 if (weaponactive != -1) {
3633 emit_sound_at(knifedrawsound, coords, 128.);
3636 if (animCurrent == rollanim) {
3637 animTarget = getCrouch();
3642 if (animTarget == walljumprightkickanim) {
3645 if (animTarget == walljumpleftkickanim) {
3648 animTarget = jumpdownanim;
3650 if (animCurrent == climbanim) {
3651 animTarget = getCrouch();
3653 coords += facing * .1;
3654 if (!isnormal(coords.x))
3665 if (animTarget == rabbitkickreversalanim) {
3666 animTarget = getCrouch();
3669 if (animTarget == jumpreversalanim) {
3670 animTarget = getCrouch();
3673 if (animTarget == walljumprightanim || animTarget == walljumpbackanim || animTarget == walljumpfrontanim) {
3674 if (attackkeydown && animTarget != walljumpfrontanim) {
3676 float closestdist = -1;
3678 if (Person::players.size() > 1)
3679 for (unsigned i = 0; i < Person::players.size(); i++) {
3680 if (id != i && Person::players[i]->coords.y < coords.y && !Person::players[i]->skeleton.free) {
3681 distance = distsq(&Person::players[i]->coords, &coords);
3682 if (closestdist == -1 || distance < closestdist) {
3683 closestdist = distance;
3688 if (closestdist > 0 && closest >= 0 && closestdist < 16) {
3689 victim = Person::players[closest];
3690 animTarget = walljumprightkickanim;
3692 XYZ rotatetarget = victim->coords - coords;
3693 Normalise(&rotatetarget);
3694 yaw = -asin(0 - rotatetarget.x);
3696 if (rotatetarget.z < 0)
3698 targettilt2 = -asin(rotatetarget.y) * 360 / 6.28;
3699 velocity = (victim->coords - coords) * 4;
3704 if (animTarget == walljumpbackanim) {
3705 animTarget = backflipanim;
3707 velocity = facing * -8;
3710 resume_stream(whooshsound);
3712 if (animTarget == walljumprightanim) {
3713 animTarget = rightflipanim;
3717 velocity = DoRotation(facing, 0, 30, 0) * -8;
3720 if (animTarget == walljumpfrontanim) {
3721 animTarget = frontflipanim;
3725 velocity = facing * 8;
3729 resume_stream(whooshsound);
3731 if (animTarget == walljumpleftanim) {
3732 if (attackkeydown) {
3734 float closestdist = -1;
3736 if (Person::players.size() > 1)
3737 for (unsigned i = 0; i < Person::players.size(); i++) {
3738 if (id != i && Person::players[i]->coords.y < coords.y && !Person::players[i]->skeleton.free) {
3739 distance = distsq(&Person::players[i]->coords, &coords);
3740 if (closestdist == -1 || distance < closestdist) {
3741 closestdist = distance;
3746 if (closestdist > 0 && closest >= 0 && closestdist < 16) {
3747 victim = Person::players[closest];
3748 animTarget = walljumpleftkickanim;
3750 XYZ rotatetarget = victim->coords - coords;
3751 Normalise(&rotatetarget);
3752 yaw = -asin(0 - rotatetarget.x);
3754 if (rotatetarget.z < 0)
3756 targettilt2 = -asin(rotatetarget.y) * 360 / 6.28;
3757 velocity = (victim->coords - coords) * 4;
3762 if (animTarget != walljumpleftkickanim) {
3763 animTarget = leftflipanim;
3767 velocity = DoRotation(facing, 0, -30, 0) * -8;
3771 resume_stream(whooshsound);
3773 if (animTarget == sneakattackanim) {
3774 animCurrent = getCrouch();
3775 animTarget = getCrouch();
3782 transspeed = 1000000;
3783 targetheadyaw += 180;
3784 coords -= facing * .7;
3786 coords.y = terrain.getHeight(coords.x, coords.z);
3790 if (animTarget == knifesneakattackanim || animTarget == swordsneakattackanim) {
3791 animTarget = getIdle();
3794 coords.y = terrain.getHeight(coords.x, coords.z);
3798 if (animCurrent == knifefollowanim) {
3799 animTarget = getIdle();
3802 if (animation[animTarget].attack == reversal && animCurrent != sneakattackanim && animCurrent != knifesneakattackanim && animCurrent != swordsneakattackanim && animCurrent != knifefollowanim) {
3803 float ycoords = oldcoords.y;
3804 animTarget = getStop();
3809 transspeed = 1000000;
3810 targetheadyaw += 180;
3811 if (!isnormal(coords.x))
3813 if (animCurrent == spinkickreversalanim || animCurrent == swordslashreversalanim)
3814 oldcoords = coords + facing * .5;
3815 else if (animCurrent == sweepreversalanim)
3816 oldcoords = coords + facing * 1.1;
3817 else if (animCurrent == upunchreversalanim) {
3818 oldcoords = coords + facing * 1.5;
3821 targetheadyaw += 180;
3824 } else if (animCurrent == knifeslashreversalanim) {
3825 oldcoords = coords + facing * .5;
3828 targetheadyaw += 90;
3831 } else if (animCurrent == staffspinhitreversalanim) {
3834 targetheadyaw += 180;
3839 oldcoords.y = terrain.getHeight(oldcoords.x, oldcoords.z);
3841 oldcoords.y = ycoords;
3842 currentoffset = coords - oldcoords;
3848 if (animCurrent == knifesneakattackedanim || animCurrent == swordsneakattackedanim) {
3853 if (animation[animTarget].attack == reversed) {
3855 if (animTarget == sweepreversedanim)
3857 animTarget = backhandspringanim;
3859 emit_sound_at(landsound, coords, 128);
3861 if (animCurrent == upunchreversedanim || animCurrent == swordslashreversedanim) {
3862 animTarget = rollanim;
3865 coords += (DoRotation(jointPos(leftfoot), 0, yaw, 0) + DoRotation(jointPos(rightfoot), 0, yaw, 0)) / 2 * scale;
3866 coords.y = oldcoords.y;
3868 if (animCurrent == knifeslashreversedanim) {
3869 animTarget = rollanim;
3874 coords += (DoRotation(jointPos(leftfoot), 0, yaw, 0) + DoRotation(jointPos(rightfoot), 0, yaw, 0)) / 2 * scale;
3875 coords.y = oldcoords.y;
3879 animTarget = jumpdownanim;
3882 animTarget = getIdle();
3884 animTarget = getIdle();
3885 if (animCurrent == spinkickanim || animCurrent == getupfrombackanim || animCurrent == getupfromfrontanim || animCurrent == lowkickanim) {
3886 animTarget = getIdle();
3888 coords += (DoRotation(jointPos(leftfoot), 0, yaw, 0) + DoRotation(jointPos(rightfoot), 0, yaw, 0)) / 2 * scale;
3889 coords.y = oldcoords.y;
3890 //coords+=DoRotation(animation[animCurrent].offset,0,yaw,0)*scale;
3891 targetoffset.y = coords.y;
3893 targetoffset.y = terrain.getHeight(coords.x, coords.z);
3894 currentoffset = DoRotation(animation[animCurrent].offset * -1, 0, yaw, 0) * scale;
3895 currentoffset.y -= (coords.y - targetoffset.y);
3896 coords.y = targetoffset.y;
3898 normalsupdatedelay = 0;
3900 if (animCurrent == upunchanim) {
3901 animTarget = getStop();
3902 normalsupdatedelay = 0;
3905 if (animCurrent == rabbitkickanim && animTarget != backflipanim) {
3909 if (num_weapons > 0)
3910 if (weapons[0].getType() == staff)
3916 rabbitkickragdoll = 1;
3918 if (animCurrent == rabbitkickreversedanim) {
3924 skeleton.spinny = 0;
3925 SolidHitBonus(!id); // FIXME: tricky id
3929 animTarget = rollanim;
3932 pause_sound(whooshsound);
3936 if (animCurrent == rabbittackledbackanim || animCurrent == rabbittackledfrontanim) {
3940 skeleton.spinny = 0;
3942 if (animCurrent == jumpreversedanim) {
3948 skeleton.spinny = 0;
3949 SolidHitBonus(!id); // FIXME: tricky id
3953 animTarget = rollanim;
3954 coords += facing * 2;
3956 pause_sound(whooshsound);
3961 if (animation[animCurrent].attack == normalattack && !victim->skeleton.free && victim->animTarget != staggerbackhighanim && victim->animTarget != staggerbackhardanim && animTarget != winduppunchblockedanim && animTarget != blockhighleftanim && animTarget != swordslashparryanim && animTarget != swordslashparriedanim && animTarget != crouchstabanim && animTarget != swordgroundstabanim) {
3962 animTarget = getupfromfrontanim;
3964 } else if (animation[animCurrent].attack == normalattack) {
3965 animTarget = getIdle();
3968 if (animCurrent == blockhighleftanim && aitype != playercontrolled) {
3969 animTarget = blockhighleftstrikeanim;
3971 if (animCurrent == knifeslashstartanim || animCurrent == knifethrowanim || animCurrent == swordslashanim || animCurrent == staffhitanim || animCurrent == staffgroundsmashanim || animCurrent == staffspinhitanim) {
3972 animTarget = getIdle();
3975 if (animCurrent == spinkickanim && victim->skeleton.free) {
3976 if (creature == rabbittype)
3977 animTarget = fightidleanim;
3982 if (isIdle() && !wasIdle())
3983 normalsupdatedelay = 0;
3985 if (animCurrent == jumpupanim && velocity.y < 0 && !isFlip()) {
3986 animTarget = jumpdownanim;
3989 if (!skeleton.free) {
3991 if (!transspeed && animation[animTarget].attack != 2 && animation[animTarget].attack != 3) {
3992 if (!isRun() || !wasRun()) {
3993 if (animation[animTarget].speed[frameTarget] > animation[animCurrent].speed[frameCurrent])
3994 target += multiplier * animation[animTarget].speed[frameTarget] * speed * 2;
3995 if (animation[animTarget].speed[frameTarget] <= animation[animCurrent].speed[frameCurrent])
3996 target += multiplier * animation[animCurrent].speed[frameCurrent] * speed * 2;
3998 if (isRun() && wasRun()) {
4000 tempspeed = velspeed;
4001 if (tempspeed < 10 * speedmult)
4002 tempspeed = 10 * speedmult;
4003 target += multiplier * animation[animTarget].speed[frameCurrent] * speed * 1.7 * tempspeed / (speed * 45 * scale);
4005 } else if (transspeed)
4006 target += multiplier * transspeed * speed * 2;
4008 if (!isRun() || !wasRun()) {
4009 if (animation[animTarget].speed[frameTarget] > animation[animCurrent].speed[frameCurrent])
4010 target += multiplier * animation[animTarget].speed[frameTarget] * 2;
4011 if (animation[animTarget].speed[frameTarget] <= animation[animCurrent].speed[frameCurrent])
4012 target += multiplier * animation[animCurrent].speed[frameCurrent] * 2;
4016 if (animCurrent != animTarget)
4017 target = (target + oldtarget) / 2;
4020 frameCurrent = frameTarget;
4024 rot = targetrot * target;
4025 yaw += rot - oldrot;
4031 if (animCurrent != oldanimCurrent || animTarget != oldanimTarget || ((frameCurrent != oldframeCurrent || frameTarget != oldframeTarget) && !calcrot)) {
4033 for (int i = 0; i < skeleton.num_joints; i++) {
4034 skeleton.joints[i].position = animation[animCurrent].position[i][frameCurrent];
4037 skeleton.FindForwards();
4039 for (int i = 0; i < skeleton.num_muscles; i++) {
4040 if (skeleton.muscles[i].visible) {
4041 skeleton.FindRotationMuscle(i, animTarget);
4044 for (int i = 0; i < skeleton.num_muscles; i++) {
4045 if (skeleton.muscles[i].visible) {
4046 if (isnormal((float)((int)(skeleton.muscles[i].rotate1 * 100) % 36000) / 100))
4047 skeleton.muscles[i].oldrotate1 = (float)((int)(skeleton.muscles[i].rotate1 * 100) % 36000) / 100;
4048 if (isnormal((float)((int)(skeleton.muscles[i].rotate2 * 100) % 36000) / 100))
4049 skeleton.muscles[i].oldrotate2 = (float)((int)(skeleton.muscles[i].rotate2 * 100) % 36000) / 100;
4050 if (isnormal((float)((int)(skeleton.muscles[i].rotate3 * 100) % 36000) / 100))
4051 skeleton.muscles[i].oldrotate3 = (float)((int)(skeleton.muscles[i].rotate3 * 100) % 36000) / 100;
4056 for (int i = 0; i < skeleton.num_joints; i++) {
4057 skeleton.joints[i].position = animation[animTarget].position[i][frameTarget];
4060 skeleton.FindForwards();
4062 for (int i = 0; i < skeleton.num_muscles; i++) {
4063 if (skeleton.muscles[i].visible) {
4064 skeleton.FindRotationMuscle(i, animTarget);
4067 for (int i = 0; i < skeleton.num_muscles; i++) {
4068 if (skeleton.muscles[i].visible) {
4069 if (isnormal((float)((int)(skeleton.muscles[i].rotate1 * 100) % 36000) / 100))
4070 skeleton.muscles[i].newrotate1 = (float)((int)(skeleton.muscles[i].rotate1 * 100) % 36000) / 100;
4071 if (isnormal((float)((int)(skeleton.muscles[i].rotate2 * 100) % 36000) / 100))
4072 skeleton.muscles[i].newrotate2 = (float)((int)(skeleton.muscles[i].rotate2 * 100) % 36000) / 100;
4073 if (isnormal((float)((int)(skeleton.muscles[i].rotate3 * 100) % 36000) / 100))
4074 skeleton.muscles[i].newrotate3 = (float)((int)(skeleton.muscles[i].rotate3 * 100) % 36000) / 100;
4075 if (skeleton.muscles[i].newrotate3 > skeleton.muscles[i].oldrotate3 + 180) skeleton.muscles[i].newrotate3 -= 360;
4076 if (skeleton.muscles[i].newrotate3 < skeleton.muscles[i].oldrotate3 - 180) skeleton.muscles[i].newrotate3 += 360;
4077 if (skeleton.muscles[i].newrotate2 > skeleton.muscles[i].oldrotate2 + 180) skeleton.muscles[i].newrotate2 -= 360;
4078 if (skeleton.muscles[i].newrotate2 < skeleton.muscles[i].oldrotate2 - 180) skeleton.muscles[i].newrotate2 += 360;
4079 if (skeleton.muscles[i].newrotate1 > skeleton.muscles[i].oldrotate1 + 180) skeleton.muscles[i].newrotate1 -= 360;
4080 if (skeleton.muscles[i].newrotate1 < skeleton.muscles[i].oldrotate1 - 180) skeleton.muscles[i].newrotate1 += 360;
4084 if (frameCurrent >= animation[animCurrent].numframes)
4085 frameCurrent = animation[animCurrent].numframes - 1;
4087 oldanimCurrent = animCurrent;
4088 oldanimTarget = animTarget;
4089 oldframeTarget = frameTarget;
4090 oldframeCurrent = frameCurrent;
4092 for (int i = 0; i < skeleton.num_joints; i++) {
4093 skeleton.joints[i].velocity = (animation[animCurrent].position[i][frameCurrent] * (1 - target) + animation[animTarget].position[i][frameTarget] * (target) - skeleton.joints[i].position) / multiplier;
4094 skeleton.joints[i].position = animation[animCurrent].position[i][frameCurrent] * (1 - target) + animation[animTarget].position[i][frameTarget] * (target);
4096 offset = currentoffset * (1 - target) + targetoffset * target;
4097 for (int i = 0; i < skeleton.num_muscles; i++) {
4098 if (skeleton.muscles[i].visible) {
4099 skeleton.muscles[i].rotate1 = skeleton.muscles[i].oldrotate1 * (1 - target) + skeleton.muscles[i].newrotate1 * (target);
4100 skeleton.muscles[i].rotate2 = skeleton.muscles[i].oldrotate2 * (1 - target) + skeleton.muscles[i].newrotate2 * (target);
4101 skeleton.muscles[i].rotate3 = skeleton.muscles[i].oldrotate3 * (1 - target) + skeleton.muscles[i].newrotate3 * (target);
4106 if (isLanding() && landhard) {
4109 animTarget = getLandhard();
4116 //skeleton.DoConstraints();
4123 void Person::DoStuff()
4125 static XYZ terrainnormal;
4126 static XYZ flatfacing;
4127 static XYZ flatvelocity;
4128 static float flatvelspeed;
4132 static int bloodsize;
4133 static int startx, starty, endx, endy;
4134 static GLubyte color;
4135 static XYZ bloodvel;
4137 onfiredelay -= multiplier;
4138 if (onfiredelay < 0 && onfire) {
4139 if (Random() % 2 == 0) {
4145 crouchkeydowntime += multiplier;
4147 crouchkeydowntime = 0;
4148 jumpkeydowntime += multiplier;
4149 if (!jumpkeydown && skeleton.free)
4150 jumpkeydowntime = 0;
4152 if (hostile || damage > 0 || bloodloss > 0)
4155 if (isIdle() || isRun())
4158 if (num_weapons == 1 && weaponactive != -1)
4162 blooddimamount -= multiplier * .3;
4163 speechdelay -= multiplier;
4164 texupdatedelay -= multiplier;
4165 interestdelay -= multiplier;
4166 flamedelay -= multiplier;
4167 parriedrecently -= multiplier;
4169 victim = this->shared_from_this();
4174 speed = 1.1 * speedmult;
4176 speed = 1.0 * speedmult;
4178 rabbitkickragdoll = 0;
4182 if (id != 0 && (creature == rabbittype || difficulty != 2))
4184 if (id != 0 && creature == wolftype && difficulty == 2) {
4186 if (aitype != passivetype) {
4188 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) {
4194 if (animTarget == wolfrunninganim && !superruntoggle) {
4195 animTarget = getRun();
4199 if (weaponactive == -1 && num_weapons > 0) {
4200 if (weapons[weaponids[0]].getType() == staff) {
4206 burnt += multiplier;
4207 /*if(aitype!=playercontrolled)*///deathbleeding=5;
4208 /*if(aitype!=playercontrolled)*/
4212 OPENAL_SetVolume(channels[stream_firesound], 256 + 256 * findLength(&velocity) / 3);
4214 if (animTarget == jumpupanim || animTarget == jumpdownanim || isFlip()) {
4220 vel[0] = velocity.x;
4221 vel[1] = velocity.y;
4222 vel[2] = velocity.z;
4225 OPENAL_3D_SetAttributes(channels[whooshsound], gLoc, vel);
4226 OPENAL_SetVolume(channels[whooshsound], 64 * findLength(&velocity) / 5);
4230 while (flamedelay < 0 && onfire) {
4232 howmany = abs(Random() % (skeleton.num_joints));
4234 flatvelocity = (coords - oldcoords) / multiplier / 2; //velocity/2;
4236 flatvelocity = skeleton.joints[howmany].velocity * scale / 2;
4238 flatfacing = DoRotation(DoRotation(DoRotation(skeleton.joints[howmany].position, 0, 0, tilt), tilt2, 0, 0), 0, yaw, 0) * scale + coords;
4240 flatfacing = skeleton.joints[howmany].position * scale + coords;
4241 Sprite::MakeSprite(flamesprite, flatfacing, flatvelocity, 1, 1, 1, .6 + (float)abs(Random() % 100) / 200 - .25, 1);
4244 while (flamedelay < 0 && !onfire && tutoriallevel == 1 && id != 0) {
4246 howmany = abs(Random() % (skeleton.num_joints));
4248 flatvelocity = (coords - oldcoords) / multiplier / 2; //velocity/2;
4250 flatvelocity = skeleton.joints[howmany].velocity * scale / 2;
4252 flatfacing = DoRotation(DoRotation(DoRotation(skeleton.joints[howmany].position, 0, 0, tilt), tilt2, 0, 0), 0, yaw, 0) * scale + coords;
4254 flatfacing = skeleton.joints[howmany].position * scale + coords;
4255 Sprite::MakeSprite(breathsprite, flatfacing, flatvelocity, 1, 1, 1, .6 + (float)abs(Random() % 100) / 200 - .25, .3);
4259 bleeding -= multiplier * .3;
4260 if (bloodtoggle == 2) {
4261 skeleton.drawmodel.textureptr.bind();
4262 if (bleeding <= 0 && (detail != 2 || osx))
4267 if (neckspurtamount > 0) {
4268 neckspurtamount -= multiplier;
4269 neckspurtdelay -= multiplier * 3;
4270 neckspurtparticledelay -= multiplier * 3;
4271 if (neckspurtparticledelay < 0 && neckspurtdelay > 2) {
4274 if (!skeleton.free) {
4275 bloodvel.z = 5 * neckspurtamount;
4276 bloodvel = DoRotation(bloodvel, ((float)(Random() % 100)) / 40, yaw + ((float)(Random() % 100)) / 40, 0) * scale;
4278 if (skeleton.free) {
4279 bloodvel -= DoRotation(skeleton.forward * 10 * scale, ((float)(Random() % 100)) / 40, ((float)(Random() % 100)) / 40, 0);
4282 bloodvel += DoRotation(jointVel(head), ((float)(Random() % 100)) / 40, yaw + ((float)(Random() % 100)) / 40, 0) * scale;
4284 bloodvel += DoRotation(velocity, ((float)(Random() % 100)) / 40, ((float)(Random() % 100)) / 40, 0) * scale;
4286 Sprite::MakeSprite(bloodsprite, (jointPos(neck) + (jointPos(neck) - jointPos(head)) / 5)*scale + coords, bloodvel, 1, 1, 1, .05, .9);
4288 Sprite::MakeSprite(bloodsprite, DoRotation(jointPos(neck) + (jointPos(neck) - jointPos(head)) / 5, 0, yaw, 0)*scale + coords, bloodvel, 1, 1, 1, .05, .9);
4289 neckspurtparticledelay = .05;
4291 if (neckspurtdelay < 0) {
4296 if (deathbleeding > 0 && dead != 2) {
4297 if (deathbleeding < 5)
4298 bleeddelay -= deathbleeding * multiplier / 4;
4300 bleeddelay -= 5 * multiplier / 4;
4301 if (bleeddelay < 0 && bloodtoggle) {
4307 bloodvel += DoRotation(jointVel(abdomen), ((float)(Random() % 100)) / 4, yaw + ((float)(Random() % 100)) / 4, 0) * scale;
4309 bloodvel += DoRotation(velocity, ((float)(Random() % 100)) / 4, ((float)(Random() % 100)) / 4, 0) * scale;
4311 Sprite::MakeSprite(bloodsprite, jointPos(abdomen) * scale + coords, bloodvel, 1, 1, 1, .05, 1);
4313 Sprite::MakeSprite(bloodsprite, DoRotation((jointPos(abdomen) + jointPos(abdomen)) / 2, 0, yaw, 0)*scale + coords, bloodvel, 1, 1, 1, .05, 1);
4316 bloodloss += deathbleeding * multiplier * 80;
4317 deathbleeding -= multiplier * 1.6;
4318 //if(id==0)deathbleeding-=multiplier*.2;
4319 if (deathbleeding < 0)
4321 if (bloodloss > damagetolerance && animation[animTarget].attack == neutral) {
4322 if (weaponactive != -1) {
4323 weapons[weaponids[0]].owner = -1;
4324 weapons[weaponids[0]].velocity = velocity * scale * -.3;
4325 weapons[weaponids[0]].velocity.x += .01;
4326 weapons[weaponids[0]].tipvelocity = velocity * scale;
4327 weapons[weaponids[0]].missed = 1;
4328 weapons[weaponids[0]].hitsomething = 0;
4329 weapons[weaponids[0]].freetime = 0;
4330 weapons[weaponids[0]].firstfree = 1;
4331 weapons[weaponids[0]].physics = 1;
4334 weaponids[0] = weaponids[num_weapons];
4335 if (weaponstuck == num_weapons)
4339 for (unsigned i = 0; i < Person::players.size(); i++) {
4340 Person::players[i]->wentforweapon = 0;
4352 if (!dead && creature == wolftype) {
4353 award_bonus(0, Wolfbonus);
4356 if (animTarget == knifefollowedanim && !skeleton.free) {
4357 for (int i = 0; i < skeleton.num_joints; i++) {
4358 skeleton.joints[i].velocity = 0;
4359 skeleton.joints[i].velocity.y = -2;
4362 if (id != 0 && unconscioustime > .1) {
4370 if (texupdatedelay < 0 && bleeding > 0 && bloodtoggle == 2 && distsq(&viewer, &coords) < 9) {
4371 texupdatedelay = .12;
4373 bloodsize = 5 - realtexdetail;
4377 startx = bleedy; //abs(Random()%(skeleton.skinsize-bloodsize-1));
4378 starty = bleedx; //abs(Random()%(skeleton.skinsize-bloodsize-1));
4379 endx = startx + bloodsize;
4380 endy = starty + bloodsize;
4390 if (endx > skeleton.skinsize - 1) {
4391 endx = skeleton.skinsize - 1;
4394 if (endy > skeleton.skinsize - 1) {
4395 endy = skeleton.skinsize - 1;
4403 for (i = startx; i < endx; i++) {
4404 for (j = starty; j < endy; j++) {
4405 if (Random() % 2 == 0) {
4406 color = Random() % 85 + 170;
4407 if (skeleton.skinText[i * skeleton.skinsize * 3 + j * 3 + 0] > color / 2)
4408 skeleton.skinText[i * skeleton.skinsize * 3 + j * 3 + 0] = color / 2;
4409 skeleton.skinText[i * skeleton.skinsize * 3 + j * 3 + 1] = 0;
4410 skeleton.skinText[i * skeleton.skinsize * 3 + j * 3 + 2] = 0;
4414 if (!osx && detail > 1) {
4415 skeleton.drawmodel.textureptr.bind();
4419 if (!skeleton.free) {
4420 bleedy -= 4 / realtexdetail;
4422 bleedx += (abs(Random() % 3) - 1) * 2 / realtexdetail;
4424 bleedx += (abs(Random() % 3) - 1) * 4 / realtexdetail;
4426 if (skeleton.free) {
4427 bleedx += 4 * direction / realtexdetail;
4429 bleedy += (abs(Random() % 3) - 1) * 2 / realtexdetail;
4431 bleedy += (abs(Random() % 3) - 1) * 4 / realtexdetail;
4435 if (abs(righthandmorphness - targetrighthandmorphness) < multiplier * 4) {
4436 righthandmorphness = targetrighthandmorphness;
4437 righthandmorphstart = righthandmorphend;
4438 } else if (righthandmorphness > targetrighthandmorphness) {
4439 righthandmorphness -= multiplier * 4;
4440 } else if (righthandmorphness < targetrighthandmorphness) {
4441 righthandmorphness += multiplier * 4;
4444 if (abs(lefthandmorphness - targetlefthandmorphness) < multiplier * 4) {
4445 lefthandmorphness = targetlefthandmorphness;
4446 lefthandmorphstart = lefthandmorphend;
4447 } else if (lefthandmorphness > targetlefthandmorphness) {
4448 lefthandmorphness -= multiplier * 4;
4449 } else if (lefthandmorphness < targetlefthandmorphness) {
4450 lefthandmorphness += multiplier * 4;
4453 if (creature == rabbittype || targettailmorphness == 5 || targettailmorphness == 0) {
4454 if (abs(tailmorphness - targettailmorphness) < multiplier * 10) {
4455 tailmorphness = targettailmorphness;
4456 tailmorphstart = tailmorphend;
4457 } else if (tailmorphness > targettailmorphness) {
4458 tailmorphness -= multiplier * 10;
4459 } else if (tailmorphness < targettailmorphness) {
4460 tailmorphness += multiplier * 10;
4464 if (creature == wolftype) {
4465 if (abs(tailmorphness - targettailmorphness) < multiplier * 4) {
4466 tailmorphness = targettailmorphness;
4467 tailmorphstart = tailmorphend;
4468 } else if (tailmorphness > targettailmorphness) {
4469 tailmorphness -= multiplier * 2;
4470 } else if (tailmorphness < targettailmorphness) {
4471 tailmorphness += multiplier * 2;
4475 if (headmorphend == 3 || headmorphstart == 3) {
4476 if (abs(headmorphness - targetheadmorphness) < multiplier * 7) {
4477 headmorphness = targetheadmorphness;
4478 headmorphstart = headmorphend;
4479 } else if (headmorphness > targetheadmorphness) {
4480 headmorphness -= multiplier * 7;
4481 } else if (headmorphness < targetheadmorphness) {
4482 headmorphness += multiplier * 7;
4484 } else if (headmorphend == 5 || headmorphstart == 5) {
4485 if (abs(headmorphness - targetheadmorphness) < multiplier * 10) {
4486 headmorphness = targetheadmorphness;
4487 headmorphstart = headmorphend;
4488 } else if (headmorphness > targetheadmorphness) {
4489 headmorphness -= multiplier * 10;
4490 } else if (headmorphness < targetheadmorphness) {
4491 headmorphness += multiplier * 10;
4494 if (abs(headmorphness - targetheadmorphness) < multiplier * 4) {
4495 headmorphness = targetheadmorphness;
4496 headmorphstart = headmorphend;
4497 } else if (headmorphness > targetheadmorphness) {
4498 headmorphness -= multiplier * 4;
4499 } else if (headmorphness < targetheadmorphness) {
4500 headmorphness += multiplier * 4;
4504 if (abs(chestmorphness - targetchestmorphness) < multiplier) {
4505 chestmorphness = targetchestmorphness;
4506 chestmorphstart = chestmorphend;
4507 } else if (chestmorphness > targetchestmorphness) {
4508 chestmorphness -= multiplier;
4509 } else if (chestmorphness < targetchestmorphness) {
4510 chestmorphness += multiplier;
4513 if (dead != 2 && howactive <= typesleeping) {
4514 if (chestmorphstart == 0 && chestmorphend == 0) {
4516 targetchestmorphness = 1;
4519 if (chestmorphstart != 0 && chestmorphend != 0) {
4521 targetchestmorphness = 1;
4523 if (environment == snowyenvironment) {
4527 footvel = DoRotation(skeleton.specialforward[0], 0, yaw, 0) * -1;
4529 footvel = skeleton.specialforward[0] * -1;
4531 footpoint = DoRotation((jointPos(head) + jointPos(neck)) / 2, 0, yaw, 0) * scale + coords;
4533 footpoint = ((jointPos(head) + jointPos(neck)) / 2) * scale + coords;
4534 if (animTarget == sleepanim)
4535 footvel = DoRotation(footvel, 0, 90, 0);
4536 Sprite::MakeSprite(breathsprite, footpoint + footvel * .2, footvel * .4, 1, 1, 1, .4, .3);
4540 if (!dead && howactive < typesleeping) {
4541 blinkdelay -= multiplier * 2;
4542 if (headmorphstart == 0 && headmorphend == 0 && blinkdelay <= 0) {
4544 targetheadmorphness = 1;
4546 blinkdelay = (float)(abs(Random() % 40)) / 5;
4548 if (headmorphstart == 3 && headmorphend == 3) {
4550 targetheadmorphness = 1;
4555 twitchdelay -= multiplier * 1.5;
4556 if (animTarget != hurtidleanim) {
4557 if (headmorphstart == 0 && headmorphend == 0 && twitchdelay <= 0) {
4559 targetheadmorphness = 1;
4561 twitchdelay = (float)(abs(Random() % 40)) / 5;
4563 if (headmorphstart == 5 && headmorphend == 5) {
4565 targetheadmorphness = 1;
4569 if ((isIdle() || isCrouch()) && animTarget != hurtidleanim) {
4570 twitchdelay3 -= multiplier * 1;
4571 if (Random() % 2 == 0) {
4572 if (righthandmorphstart == 0 && righthandmorphend == 0 && twitchdelay3 <= 0) {
4573 righthandmorphness = 0;
4574 targetrighthandmorphness = 1;
4575 righthandmorphend = 1;
4576 if (Random() % 2 == 0)twitchdelay3 = (float)(abs(Random() % 40)) / 5;
4578 if (righthandmorphstart == 1 && righthandmorphend == 1) {
4579 righthandmorphness = 0;
4580 targetrighthandmorphness = 1;
4581 righthandmorphend = 0;
4584 if (Random() % 2 == 0) {
4585 if (lefthandmorphstart == 0 && lefthandmorphend == 0 && twitchdelay3 <= 0) {
4586 lefthandmorphness = 0;
4587 targetlefthandmorphness = 1;
4588 lefthandmorphend = 1;
4589 twitchdelay3 = (float)(abs(Random() % 40)) / 5;
4591 if (lefthandmorphstart == 1 && lefthandmorphend == 1) {
4592 lefthandmorphness = 0;
4593 targetlefthandmorphness = 1;
4594 lefthandmorphend = 0;
4600 if (creature == rabbittype) {
4601 if (howactive < typesleeping)
4602 twitchdelay2 -= multiplier * 1.5;
4604 twitchdelay2 -= multiplier * 0.5;
4605 if (howactive <= typesleeping) {
4606 if (tailmorphstart == 0 && tailmorphend == 0 && twitchdelay2 <= 0) {
4608 targettailmorphness = 1;
4610 twitchdelay2 = (float)(abs(Random() % 40)) / 5;
4612 if (tailmorphstart == 1 && tailmorphend == 1) {
4614 targettailmorphness = 1;
4617 if (tailmorphstart == 2 && tailmorphend == 2) {
4619 targettailmorphness = 1;
4626 if (creature == wolftype) {
4627 twitchdelay2 -= multiplier * 1.5;
4628 if (tailmorphend != 0)
4629 if ((isRun() || animTarget == jumpupanim || animTarget == jumpdownanim || animTarget == backflipanim) && !skeleton.free) {
4631 targettailmorphness = 1;
4635 if (tailmorphend != 5)
4636 if (animTarget == flipanim || animTarget == frontflipanim || animTarget == rollanim || skeleton.free) {
4638 targettailmorphness = 1;
4642 if (twitchdelay2 <= 0) {
4643 if (((tailmorphstart == 0 && tailmorphend == 0) || (tailmorphstart == 5 && tailmorphend == 5))) {
4645 targettailmorphness = 1;
4648 if (tailmorphstart == 1 && tailmorphend == 1) {
4650 targettailmorphness = 1;
4653 if (tailmorphstart == 2 && tailmorphend == 2) {
4655 targettailmorphness = 1;
4658 if (tailmorphstart == 3 && tailmorphend == 3) {
4660 targettailmorphness = 1;
4663 if (tailmorphstart == 4 && tailmorphend == 4) {
4665 targettailmorphness = 1;
4672 unconscioustime = 0;
4674 if (dead == 1 || howactive == typesleeping) {
4675 unconscioustime += multiplier;
4676 //If unconscious, close eyes and mouth
4677 if (righthandmorphend != 0)
4678 righthandmorphness = 0;
4679 righthandmorphend = 0;
4680 targetrighthandmorphness = 1;
4682 if (lefthandmorphend != 0)
4683 lefthandmorphness = 0;
4684 lefthandmorphend = 0;
4685 targetlefthandmorphness = 1;
4687 if (headmorphend != 3 && headmorphend != 5)
4690 targetheadmorphness = 1;
4694 if (howactive > typesleeping) {
4697 if (bloodtoggle && !bled) {
4698 terrain.MakeDecal(blooddecalslow, headpoint, .8, .5, 0);
4700 if (bloodtoggle && !bled)
4701 for (l = 0; l < terrain.patchobjectnum[whichpatchx][whichpatchz]; l++) {
4702 j = terrain.patchobjects[whichpatchx][whichpatchz][l];
4703 XYZ point = DoRotation(headpoint - objects.position[j], 0, -objects.yaw[j], 0);
4707 objects.model[j].MakeDecal(blooddecalslow, &point, &size, &opacity, &yaw);
4712 if (dead == 2 || howactive > typesleeping) {
4713 //If dead, open mouth and hands
4714 if (righthandmorphend != 0)
4715 righthandmorphness = 0;
4716 righthandmorphend = 0;
4717 targetrighthandmorphness = 1;
4719 if (lefthandmorphend != 0)
4720 lefthandmorphness = 0;
4721 lefthandmorphend = 0;
4722 targetlefthandmorphness = 1;
4724 if (headmorphend != 2)
4727 targetheadmorphness = 1;
4730 if (stunned > 0 && !dead && headmorphend != 2) {
4731 if (headmorphend != 4)
4734 targetheadmorphness = 1;
4737 if (damage > damagetolerance && !dead) {
4740 unconscioustime = 0;
4742 if (creature == wolftype) {
4743 award_bonus(0, Wolfbonus);
4748 if (weaponactive != -1) {
4749 weapons[weaponids[0]].owner = -1;
4750 weapons[weaponids[0]].velocity = velocity * scale * -.3;
4751 weapons[weaponids[0]].velocity.x += .01;
4752 weapons[weaponids[0]].tipvelocity = velocity * scale;
4753 weapons[weaponids[0]].missed = 1;
4754 weapons[weaponids[0]].hitsomething = 0;
4755 weapons[weaponids[0]].freetime = 0;
4756 weapons[weaponids[0]].firstfree = 1;
4757 weapons[weaponids[0]].physics = 1;
4760 weaponids[0] = weaponids[num_weapons];
4761 if (weaponstuck == num_weapons)
4765 for (unsigned i = 0; i < Person::players.size(); i++) {
4766 Person::players[i]->wentforweapon = 0;
4772 if ((id == 0 || distsq(&coords, &viewer) < 50) && autoslomo) {
4780 //if(dead)damage-=multiplier/4;
4782 damage -= multiplier * 13;
4783 //if(!dead&&deathbleeding<=0&&id==0)bloodloss-=multiplier*4;
4785 permanentdamage -= multiplier * 4;
4786 if (isIdle() || isCrouch()) {
4788 permanentdamage -= multiplier * 4;
4789 //if(!dead&&deathbleeding<=0&&id==0)bloodloss-=multiplier*4;
4793 if (permanentdamage < 0)
4794 permanentdamage = 0;
4795 if (superpermanentdamage < 0)
4796 superpermanentdamage = 0;
4797 if (permanentdamage < superpermanentdamage) {
4798 permanentdamage = superpermanentdamage;
4800 if (damage < permanentdamage) {
4801 damage = permanentdamage;
4803 if (dead == 1 && damage < damagetolerance) {
4807 for (int i = 0; i < skeleton.num_joints; i++) {
4808 skeleton.joints[i].velocity = 0;
4811 if (permanentdamage > damagetolerance && dead != 2) {
4814 if (weaponactive != -1) {
4815 weapons[weaponids[0]].owner = -1;
4816 weapons[weaponids[0]].velocity = velocity * scale * -.3;
4817 weapons[weaponids[0]].velocity.x += .01;
4818 weapons[weaponids[0]].tipvelocity = velocity * scale;
4819 weapons[weaponids[0]].missed = 1;
4820 weapons[weaponids[0]].hitsomething = 0;
4821 weapons[weaponids[0]].freetime = 0;
4822 weapons[weaponids[0]].firstfree = 1;
4823 weapons[weaponids[0]].physics = 1;
4826 weaponids[0] = weaponids[num_weapons];
4827 if (weaponstuck == num_weapons)
4831 for (unsigned i = 0; i < Person::players.size(); i++) {
4832 Person::players[i]->wentforweapon = 0;
4838 if (!dead && creature == wolftype) {
4839 award_bonus(0, Wolfbonus);
4842 if (unconscioustime < .1 && (bonus != spinecrusher || bonustime > 1) && (bonus != FinishedBonus || bonustime > 1) && bloodloss < damagetolerance)
4843 award_bonus(id, touchofdeath);
4844 if (id != 0 && unconscioustime > .1) {
4852 emit_sound_at(breaksound, coords);
4855 if (skeleton.free == 1) {
4857 pause_sound(whooshsound);
4860 //If knocked over, open hands and close mouth
4861 if (righthandmorphend != 0)
4862 righthandmorphness = 0;
4863 righthandmorphend = 0;
4864 targetrighthandmorphness = 1;
4866 if (lefthandmorphend != 0)
4867 lefthandmorphness = 0;
4868 lefthandmorphend = 0;
4869 targetlefthandmorphness = 1;
4871 if (headmorphend != 3 && headmorphend != 5 && headmorphstart != 3 && headmorphstart != 5) {
4872 if (headmorphend != 0)
4875 targetheadmorphness = 1;
4879 skeleton.DoGravity(&scale);
4881 damageamount = skeleton.DoConstraints(&coords, &scale) * 5;
4882 if (damage > damagetolerance - damageamount && !dead && (bonus != spinecrusher || bonustime > 1) && (bonus != style || bonustime > 1) && (bonus != cannon || bonustime > 1))
4883 award_bonus(id, deepimpact);
4884 DoDamage(damageamount / ((protectionhigh + protectionhead + protectionlow) / 3));
4888 for (j = 0; j < skeleton.num_joints; j++) {
4889 average += skeleton.joints[j].position;
4893 coords += average * scale;
4894 for (j = 0; j < skeleton.num_joints; j++) {
4895 skeleton.joints[j].position -= average;
4897 average /= multiplier;
4899 //velocity=jointVel(groin)*scale;
4901 for (int i = 0; i < skeleton.num_joints; i++) {
4902 velocity += skeleton.joints[i].velocity * scale;
4904 velocity /= skeleton.num_joints;
4906 if (!isnormal(velocity.x) && velocity.x) {
4910 if (findLength(&average) < 10 && dead && skeleton.free) {
4911 skeleton.longdead += (2000 - findLength(&average)) * multiplier + multiplier;
4912 if (skeleton.longdead > 2000) {
4913 if (skeleton.longdead > 6000) {
4915 pause_sound(whooshsound);
4920 if (dead == 2 && bloodloss < damagetolerance) {
4922 headpoint = (jointPos(head) + jointPos(neck)) / 2 * scale + coords;
4924 if (bloodtoggle && !bled) {
4925 terrain.MakeDecal(blooddecal, headpoint, .2 * 1.2, .5, 0);
4927 if (bloodtoggle && !bled)
4928 for (l = 0; l < terrain.patchobjectnum[whichpatchx][whichpatchz]; l++) {
4929 j = terrain.patchobjects[whichpatchx][whichpatchz][l];
4930 XYZ point = DoRotation(headpoint - objects.position[j], 0, -objects.yaw[j], 0);
4931 float size = .2 * 1.2;
4934 objects.model[j].MakeDecal(blooddecal, &point, &size, &opacity, &yaw);
4938 if (dead == 2 && bloodloss >= damagetolerance) {
4940 headpoint = (jointPos(abdomen) + jointPos(neck)) / 2 * scale + coords;
4943 if (bloodtoggle && !bled) {
4944 terrain.MakeDecal(blooddecalslow, headpoint, .8, .5, 0);
4946 if (bloodtoggle && !bled)
4947 for (l = 0; l < terrain.patchobjectnum[whichpatchx][whichpatchz]; l++) {
4948 j = terrain.patchobjects[whichpatchx][whichpatchz][l];
4949 XYZ point = DoRotation(headpoint - objects.position[j], 0, -objects.yaw[j], 0);
4953 objects.model[j].MakeDecal(blooddecalslow, &point, &size, &opacity, &yaw);
4960 if (!dead && crouchkeydown && skeleton.freetime > .5 && id == 0 && skeleton.free) {
4961 bool canrecover = 1;
4962 XYZ startpoint, endpoint, colpoint, colviewer, coltarget;
4963 startpoint = coords;
4966 if (terrain.lineTerrain(startpoint, endpoint, &colpoint) != -1)
4968 if (velocity.y < -30)
4970 for (i = 0; i < objects.numobjects; i++) {
4971 if (objects.type[i] != treeleavestype && objects.type[i] != bushtype && objects.type[i] != firetype) {
4972 colviewer = startpoint;
4973 coltarget = endpoint;
4974 if (objects.model[i].LineCheck(&colviewer, &coltarget, &colpoint, &objects.position[i], &objects.yaw[i]) != -1)
4983 terrainnormal = jointPos(groin) - jointPos(abdomen);
4984 if (joint(groin).locked && joint(abdomen).locked) {
4985 terrainnormal = jointPos(groin) - jointPos(abdomen);
4986 middle = (jointPos(groin) + jointPos(abdomen)) / 2;
4988 if (joint(abdomen).locked && joint(neck).locked) {
4989 terrainnormal = jointPos(abdomen) - jointPos(neck);
4990 middle = (jointPos(neck) + jointPos(abdomen)) / 2;
4992 if (joint(groin).locked && joint(neck).locked) {
4993 terrainnormal = jointPos(groin) - jointPos(neck);
4994 middle = (jointPos(groin) + jointPos(neck)) / 2;
4996 Normalise(&terrainnormal);
4998 targetyaw = -asin(0 - terrainnormal.x);
4999 targetyaw *= 360 / 6.28;
5000 if (terrainnormal.z < 0)
5001 targetyaw = 180 - targetyaw;
5006 animTarget = flipanim;
5007 crouchtogglekeydown = 1;
5012 animCurrent = tempanim;
5015 //tilt2=targettilt2;
5017 //if(middle.y>0)targetoffset.y=middle.y+1;
5019 for (int i = 0; i < skeleton.num_joints; i++) {
5020 tempanimation.position[i][0] = skeleton.joints[i].position;
5021 tempanimation.position[i][0] = DoRotation(tempanimation.position[i][0], 0, -yaw, 0);
5026 if (findLength(&average) < 10 && !dead && skeleton.free) {
5027 skeleton.longdead += (2000 - findLength(&average)) * multiplier + multiplier;
5028 if (skeleton.longdead > (damage + 500) * 1.5) {
5030 pause_sound(whooshsound);
5036 terrainnormal = jointPos(groin) - jointPos(abdomen);
5037 if (joint(groin).locked && joint(abdomen).locked) {
5038 terrainnormal = jointPos(groin) - jointPos(abdomen);
5039 middle = (jointPos(groin) + jointPos(abdomen)) / 2;
5041 if (joint(abdomen).locked && joint(neck).locked) {
5042 terrainnormal = jointPos(abdomen) - jointPos(neck);
5043 middle = (jointPos(neck) + jointPos(abdomen)) / 2;
5045 if (joint(groin).locked && joint(neck).locked) {
5046 terrainnormal = jointPos(groin) - jointPos(neck);
5047 middle = (jointPos(groin) + jointPos(neck)) / 2;
5049 Normalise(&terrainnormal);
5051 targetyaw = -asin(0 - terrainnormal.x);
5052 targetyaw *= 360 / 6.28;
5053 if (terrainnormal.z < 0)
5054 targetyaw = 180 - targetyaw;
5057 targettilt2 = asin(terrainnormal.y) * 180 / 3.14 * -1;
5060 if (skeleton.forward.y < 0) {
5061 animTarget = getupfrombackanim;
5065 if (skeleton.forward.y > -.3) {
5066 animTarget = getupfromfrontanim;
5074 if ((Random() % 8 == 0 && id != 0 && creature == rabbittype) || (Random() % 2 == 0 && id != 0 && creature == wolftype) || (id == 0 && crouchkeydown && (forwardkeydown || backkeydown || leftkeydown || rightkeydown))) {
5075 animTarget = rollanim;
5076 targetyaw = lookyaw;
5093 if ( !leftkeydown && !rightkeydown)
5100 if (abs(targettilt2) > 50)
5102 animCurrent = tempanim;
5105 tilt2 = targettilt2;
5107 if (middle.y > 0 && animTarget != rollanim)
5108 targetoffset.y = middle.y + 1;
5110 for (int i = 0; i < skeleton.num_joints; i++) {
5111 tempanimation.position[i][0] = skeleton.joints[i].position;
5112 tempanimation.position[i][0] = DoRotation(tempanimation.position[i][0], 0, -yaw, 0);
5119 if (num_weapons > 0)
5120 if (weapons[0].getType() == staff)
5122 if (!skeleton.freefall && freefall && ((jumpkeydown && jumpkeydowntime < .2) || (hasstaff && rabbitkickragdoll)) && !dead) {
5123 if (velocity.y > -30) {
5125 tempvelocity = velocity;
5126 Normalise(&tempvelocity);
5127 targetyaw = -asin(0 - tempvelocity.x);
5128 targetyaw *= 360 / 6.28;
5130 targetyaw = 180 - targetyaw;
5134 if (dotproduct(&skeleton.forward, &tempvelocity) < 0) {
5135 animTarget = rollanim;
5138 animTarget = backhandspringanim;
5144 emit_sound_at(movewhooshsound, coords, 128.);
5146 animCurrent = animTarget;
5147 frameCurrent = frameTarget - 1;
5159 if (skeleton.freefall == 0)
5164 if (aitype != passivetype || skeleton.free == 1)
5165 if (findLengthfast(&velocity) > .1)
5166 for (i = 0; i < objects.numobjects; i++) {
5167 if (objects.type[i] == firetype)
5168 if (distsqflat(&coords, &objects.position[i]) < objects.scale[i]*objects.scale[i] * 12 && distsq(&coords, &objects.position[i]) < objects.scale[i]*objects.scale[i] * 49) {
5170 if (!objects.onfire[i]) {
5171 emit_sound_at(firestartsound, objects.position[i]);
5173 objects.onfire[i] = 1;
5176 if (objects.onfire[i]) {
5181 if (objects.type[i] == bushtype)
5182 if (distsqflat(&coords, &objects.position[i]) < objects.scale[i]*objects.scale[i] * 12 && distsq(&coords, &objects.position[i]) < objects.scale[i]*objects.scale[i] * 49) {
5184 if (!objects.onfire[i]) {
5185 emit_sound_at(firestartsound, objects.position[i]);
5187 objects.onfire[i] = 1;
5191 if (objects.onfire[i]) {
5195 if (objects.messedwith[i] <= 0) {
5199 emit_sound_at(bushrustle, coords, 40 * findLength(&velocity));
5202 envsound[numenvsounds] = coords;
5203 envsoundvol[numenvsounds] = 4 * findLength(&velocity);
5204 envsoundlife[numenvsounds] = .4;
5209 if (environment == grassyenvironment)
5210 howmany = findLength(&velocity) * 4;
5211 if (environment == snowyenvironment)
5212 howmany = findLength(&velocity) * 2;
5214 if (environment != desertenvironment)
5215 for (j = 0; j < howmany; j++) {
5216 tempvel.x = float(abs(Random() % 100) - 50) / 20;
5217 tempvel.y = float(abs(Random() % 100) - 50) / 20;
5218 tempvel.z = float(abs(Random() % 100) - 50) / 20;
5221 pos.x += float(abs(Random() % 100) - 50) / 200;
5222 pos.y += float(abs(Random() % 100) - 50) / 200;
5223 pos.z += float(abs(Random() % 100) - 50) / 200;
5224 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);
5225 Sprite::setLastSpriteSpecial(1);
5227 howmany = findLength(&velocity) * 4;
5229 if (environment == snowyenvironment)
5230 for (j = 0; j < howmany; j++) {
5231 tempvel.x = float(abs(Random() % 100) - 50) / 20;
5232 tempvel.y = float(abs(Random() % 100) - 50) / 20;
5233 tempvel.z = float(abs(Random() % 100) - 50) / 20;
5236 pos.x += float(abs(Random() % 100) - 50) / 200;
5237 pos.y += float(abs(Random() % 100) - 50) / 200;
5238 pos.z += float(abs(Random() % 100) - 50) / 200;
5239 Sprite::MakeSprite(splintersprite, pos, tempvel * .3 + velocity * float(abs(Random() % 100)) / 100 / 2, 1, 1, 1, .1, 1);
5240 Sprite::setLastSpriteSpecial(2);
5243 objects.rotx[i] += velocity.x * multiplier * 6;
5244 objects.roty[i] += velocity.z * multiplier * 6;
5245 objects.messedwith[i] = .5;
5248 if (objects.type[i] == treeleavestype && environment != desertenvironment) {
5249 if (objects.pitch[i] == 0)
5252 tempcoord = coords - objects.position[i];
5253 tempcoord = DoRotation(tempcoord, 0, -objects.yaw[i], 0);
5254 tempcoord = DoRotation(tempcoord, -objects.pitch[i], 0, 0);
5255 tempcoord += objects.position[i];
5257 if (distsqflat(&tempcoord, &objects.position[i]) < objects.scale[i]*objects.scale[i] * 8 && distsq(&tempcoord, &objects.position[i]) < objects.scale[i]*objects.scale[i] * 300 && tempcoord.y > objects.position[i].y + 3 * objects.scale[i]) {
5258 if (objects.messedwith[i] <= 0) {
5262 emit_sound_at(bushrustle, coords, 40 * findLength(&velocity));
5265 envsound[numenvsounds] = coords;
5266 envsoundvol[numenvsounds] = 4 * findLength(&velocity);
5267 envsoundlife[numenvsounds] = .4;
5272 if (environment == grassyenvironment)
5273 howmany = findLength(&velocity) * 4;
5274 if (environment == snowyenvironment)
5275 howmany = findLength(&velocity) * 2;
5277 if (environment != desertenvironment)
5278 for (j = 0; j < howmany; j++) {
5279 tempvel.x = float(abs(Random() % 100) - 50) / 20;
5280 tempvel.y = float(abs(Random() % 100) - 50) / 20;
5281 tempvel.z = float(abs(Random() % 100) - 50) / 20;
5283 pos += velocity * .1;
5285 pos.x += float(abs(Random() % 100) - 50) / 150;
5286 pos.y += float(abs(Random() % 100) - 50) / 150;
5287 pos.z += float(abs(Random() % 100) - 50) / 150;
5288 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);
5289 Sprite::setLastSpriteSpecial(1);
5291 howmany = findLength(&velocity) * 4;
5293 if (environment == snowyenvironment)
5294 for (j = 0; j < howmany; j++) {
5295 tempvel.x = float(abs(Random() % 100) - 50) / 20;
5296 tempvel.y = float(abs(Random() % 100) - 50) / 20;
5297 tempvel.z = float(abs(Random() % 100) - 50) / 20;
5299 pos += velocity * .1;
5301 pos.x += float(abs(Random() % 100) - 50) / 150;
5302 pos.y += float(abs(Random() % 100) - 50) / 150;
5303 pos.z += float(abs(Random() % 100) - 50) / 150;
5304 Sprite::MakeSprite(splintersprite, pos, tempvel * .3 + velocity * float(abs(Random() % 100)) / 100 / 2, 1, 1, 1, .1, 1);
5305 Sprite::setLastSpriteSpecial(2);
5308 objects.messedwith[i] = .5;
5313 if (!skeleton.free) {
5316 if ((stunned > 0 || surprised > 0) && Person::players.size() > 2 && aitype != passivetype)
5319 if (aitype != passivetype && victim->skeleton.free && !victim->dead)
5321 if (tutoriallevel == 1 && id != 0)
5323 if (play && aitype != playercontrolled) {
5324 int whichsound = -1;
5325 i = abs(Random() % 4);
5326 if (speechdelay <= 0) {
5327 if (creature == rabbittype) {
5329 whichsound = rabbitchitter;
5331 whichsound = rabbitchitter2;
5333 if (creature == wolftype) {
5335 whichsound = growlsound;
5337 whichsound = growl2sound;
5342 if (whichsound != -1) {
5343 emit_sound_at(whichsound, coords);
5347 if (animTarget == staggerbackhighanim)
5349 if (animTarget == staggerbackhardanim)
5351 staggerdelay -= multiplier;
5352 if (animTarget != crouchstabanim && animTarget != swordgroundstabanim && animTarget != staffgroundsmashanim)
5354 if (velocity.y < -30 && animTarget == jumpdownanim)
5356 if (animCurrent != getIdle() && wasIdle() && animTarget != getIdle() && isIdle()) {
5357 animTarget = getIdle();
5361 weaponmissdelay -= multiplier;
5362 highreversaldelay -= multiplier;
5363 lowreversaldelay -= multiplier;
5364 lastcollide -= multiplier;
5365 skiddelay -= multiplier;
5366 if (!isnormal(velocity.x) && velocity.x) {
5369 if (!isnormal(targettilt) && targettilt) {
5372 if (!isnormal(targettilt2) && targettilt2) {
5375 if (!isnormal(targetyaw) && targetyaw) {
5379 if (animTarget == bounceidleanim || animTarget == wolfidle || animTarget == walkanim || animTarget == drawrightanim || animTarget == crouchdrawrightanim || animTarget == drawleftanim || animTarget == fightidleanim || animTarget == fightsidestep || animTarget == hanganim || isCrouch() || animTarget == backhandspringanim) {
5380 //open hands and close mouth
5381 if (righthandmorphend != 0 && righthandmorphness == targetrighthandmorphness) {
5382 righthandmorphness = 0;
5383 righthandmorphend = 0;
5384 targetrighthandmorphness = 1;
5387 if (lefthandmorphend != 0 && lefthandmorphness == targetlefthandmorphness) {
5388 lefthandmorphness = 0;
5389 lefthandmorphend = 0;
5390 targetlefthandmorphness = 1;
5393 if (headmorphend != 3 && headmorphend != 5 && headmorphstart != 3 && headmorphstart != 5 && headmorphend != 0 && headmorphness == targetheadmorphness) {
5396 targetheadmorphness = 1;
5400 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) {
5401 //open hands and mouth
5402 if (righthandmorphend != 0 && righthandmorphness == targetrighthandmorphness) {
5403 righthandmorphness = 0;
5404 righthandmorphend = 0;
5405 targetrighthandmorphness = 1;
5408 if (lefthandmorphend != 0 && lefthandmorphness == targetlefthandmorphness) {
5409 lefthandmorphness = 0;
5410 lefthandmorphend = 0;
5411 targetlefthandmorphness = 1;
5414 if (headmorphend != 1 && headmorphness == targetheadmorphness) {
5417 targetheadmorphness = 1;
5421 if (animTarget == jumpupanim || animTarget == crouchstabanim || animTarget == swordgroundstabanim || animTarget == swordfightidlebothanim || animTarget == blockhighleftanim || animTarget == blockhighleftanim) {
5422 //close hands and mouth
5423 if (righthandmorphend != 1 && righthandmorphness == targetrighthandmorphness) {
5424 righthandmorphness = 0;
5425 righthandmorphend = 1;
5426 targetrighthandmorphness = 1;
5429 if (lefthandmorphend != 1 && lefthandmorphness == targetlefthandmorphness) {
5430 lefthandmorphness = 0;
5431 lefthandmorphend = 1;
5432 targetlefthandmorphness = 1;
5435 if (headmorphend != 0 && headmorphness == targetheadmorphness) {
5438 targetheadmorphness = 1;
5442 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) {
5443 //close hands and yell
5444 if (righthandmorphend != 1 && righthandmorphness == targetrighthandmorphness) {
5445 righthandmorphness = 0;
5446 righthandmorphend = 1;
5447 targetrighthandmorphness = 1;
5450 if (lefthandmorphend != 1 && lefthandmorphness == targetlefthandmorphness) {
5451 lefthandmorphness = 0;
5452 lefthandmorphend = 1;
5453 targetlefthandmorphness = 1;
5456 if (headmorphend != 2 && headmorphness == targetheadmorphness) {
5459 targetheadmorphness = 1;
5466 if ((victim != this->shared_from_this()) && !victim->dead && (victim->aitype != passivetype) &&
5467 (victim->aitype != searchtype) && (aitype != passivetype) &&
5468 (aitype != searchtype) && (victim->id < Person::players.size()) && (aitype != passivetype)) {
5469 behind = (normaldotproduct(facing, coords - victim->coords) > 0);
5473 if (!dead && animTarget != hurtidleanim)
5474 if (behind || animTarget == killanim || animTarget == knifethrowanim || animTarget == knifefollowanim || animTarget == spinkickreversalanim || animTarget == rabbitkickreversedanim || animTarget == jumpreversedanim) {
5475 if (headmorphend != 4 || headmorphness == targetheadmorphness) {
5478 targetheadmorphness = 1;
5482 if (weaponactive != -1) {
5483 if (weapons[weaponids[weaponactive]].getType() != staff) {
5484 righthandmorphstart = 1;
5485 righthandmorphend = 1;
5487 if (weapons[weaponids[weaponactive]].getType() == staff) {
5488 righthandmorphstart = 2;
5489 righthandmorphend = 2;
5491 targetrighthandmorphness = 1;
5494 terrainnormal = terrain.getNormal(coords.x, coords.z);
5496 if (animation[animTarget].attack != reversal) {
5497 if (!isnormal(coords.x))
5505 flatfacing = DoRotation(flatfacing, 0, yaw, 0);
5506 facing = flatfacing;
5507 ReflectVector(&facing, terrainnormal);
5510 if (isRun() || animTarget == sneakanim || animTarget == rollanim || animTarget == walkanim) {
5512 targettilt2 = -facing.y * 20;
5517 if (!isRun() && !animation[animTarget].attack && animTarget != getupfromfrontanim && animTarget != getupfrombackanim && animTarget != sneakanim)
5519 if (animTarget == jumpupanim || animTarget == jumpdownanim || isFlip()) {
5520 flatvelocity = velocity;
5522 flatvelspeed = findLength(&flatvelocity);
5523 targettilt = flatvelspeed * fast_sqrt(abs(velocity.y) * .7) * normaldotproduct(DoRotation(flatfacing, 0, -90, 0), flatvelocity);
5524 targettilt2 = flatvelspeed * fast_sqrt(abs(velocity.y) * .7) * normaldotproduct(flatfacing, flatvelocity);
5529 if (targettilt > 25)
5531 if (targettilt < -25)
5535 if (targettilt2 > 45)
5537 if (targettilt2 < -45)
5539 if (abs(tilt2 - targettilt2) < multiplier * 400)
5540 tilt2 = targettilt2;
5541 else if (tilt2 > targettilt2) {
5542 tilt2 -= multiplier * 400;
5543 } else if (tilt2 < targettilt2) {
5544 tilt2 += multiplier * 400;
5546 if (!animation[animTarget].attack && animTarget != getupfrombackanim && animTarget != getupfromfrontanim) {
5553 if (!isnormal(targettilt) && targettilt) {
5556 if (!isnormal(targettilt2) && targettilt2) {
5561 //if(!creature==wolftype||animTarget==rabbitkickanim)
5562 if (animTarget == rabbittackleanim) {
5563 velocity += facing * multiplier * speed * 700 * scale;
5564 velspeed = findLength(&velocity);
5565 if (velspeed > speed * 65 * scale) {
5566 velocity /= velspeed;
5567 velspeed = speed * 65 * scale;
5568 velocity *= velspeed;
5570 velocity.y += gravity * multiplier * 20;
5571 ReflectVector(&velocity, terrain.getNormal(coords.x, coords.z));
5572 velspeed = findLength(&velocity);
5573 velocity = flatfacing * velspeed;
5575 if (animTarget != rabbitrunninganim && animTarget != wolfrunninganim) {
5576 if (isRun() || animTarget == rabbitkickanim) {
5577 velocity += facing * multiplier * speed * 700 * scale;
5578 velspeed = findLength(&velocity);
5579 if (velspeed > speed * 45 * scale) {
5580 velocity /= velspeed;
5581 velspeed = speed * 45 * scale;
5582 velocity *= velspeed;
5584 velocity.y += gravity * multiplier * 20;
5585 ReflectVector(&velocity, terrain.getNormal(coords.x, coords.z));
5586 velspeed = findLength(&velocity);
5587 if (velspeed < speed * 30 * scale)
5588 velspeed = speed * 30 * scale;
5589 velocity = flatfacing * velspeed;
5591 } else if (isRun()) {
5592 velocity += facing * multiplier * speed * 700 * scale;
5593 velspeed = findLength(&velocity);
5594 if (creature == rabbittype) {
5595 if (velspeed > speed * 55 * scale) {
5596 velocity /= velspeed;
5597 velspeed = speed * 55 * scale;
5598 velocity *= velspeed;
5601 if (creature == wolftype) {
5602 if (velspeed > speed * 75 * scale) {
5603 velocity /= velspeed;
5604 velspeed = speed * 75 * scale;
5605 velocity *= velspeed;
5608 velocity.y += gravity * multiplier * 20;
5609 ReflectVector(&velocity, terrain.getNormal(coords.x, coords.z));
5610 velspeed = findLength(&velocity);
5611 velocity = flatfacing * velspeed;
5614 if (animTarget == rollanim && animation[animTarget].label[frameTarget] != 6) {
5615 velocity += facing * multiplier * speed * 700 * scale;
5616 velspeed = findLength(&velocity);
5617 if (velspeed > speed * 45 * scale) {
5618 velocity /= velspeed;
5619 velspeed = speed * 45 * scale;
5620 velocity *= velspeed;
5622 velocity.y += gravity * multiplier * 20;
5623 ReflectVector(&velocity, terrain.getNormal(coords.x, coords.z));
5624 velspeed = findLength(&velocity);
5625 velocity = flatfacing * velspeed;
5629 /*if(animCurrent==rollanim&&(isCrouch()||isIdle())){
5630 velocity+=facing*multiplier*speed*700*scale;
5631 velspeed=findLength(&velocity);
5632 if(velspeed>speed*25*scale){
5634 velspeed=speed*25*scale;
5637 velocity.y+=gravity*multiplier*20;
5638 ReflectVector(&velocity,terrain.getNormal(coords.x,coords.z));
5639 velspeed=findLength(&velocity);
5640 velocity=flatfacing*velspeed;
5643 if (animTarget == sneakanim || animTarget == walkanim) {
5644 velocity += facing * multiplier * speed * 700 * scale;
5645 velspeed = findLength(&velocity);
5646 if (velspeed > speed * 12 * scale) {
5647 velocity /= velspeed;
5648 velspeed = speed * 12 * scale;
5649 velocity *= velspeed;
5651 velocity.y += gravity * multiplier * 20;
5652 ReflectVector(&velocity, terrain.getNormal(coords.x, coords.z));
5653 velspeed = findLength(&velocity);
5654 velocity = flatfacing * velspeed;
5657 if ((animTarget == fightidleanim || animTarget == knifefightidleanim) && (animCurrent == bounceidleanim || animCurrent == hurtidleanim)) {
5658 velocity += facing * multiplier * speed * 700 * scale;
5659 velspeed = findLength(&velocity);
5660 if (velspeed > speed * 2 * scale) {
5661 velocity /= velspeed;
5662 velspeed = speed * 2 * scale;
5663 velocity *= velspeed;
5665 velocity.y += gravity * multiplier * 20;
5666 ReflectVector(&velocity, terrain.getNormal(coords.x, coords.z));
5667 velspeed = findLength(&velocity);
5668 velocity = flatfacing * velspeed;
5672 if ((animTarget == bounceidleanim || animCurrent == hurtidleanim) && (animCurrent == fightidleanim || animCurrent == knifefightidleanim)) {
5673 velocity -= facing * multiplier * speed * 700 * scale;
5674 velspeed = findLength(&velocity);
5675 if (velspeed > speed * 2 * scale) {
5676 velocity /= velspeed;
5677 velspeed = speed * 2 * scale;
5678 velocity *= velspeed;
5680 velocity.y += gravity * multiplier * 20;
5681 ReflectVector(&velocity, terrain.getNormal(coords.x, coords.z));
5682 velspeed = findLength(&velocity);
5683 velocity = flatfacing * velspeed * -1;
5686 if (animTarget == fightsidestep) {
5687 velocity += DoRotation(facing * multiplier * speed * 700 * scale, 0, -90, 0);
5688 velspeed = findLength(&velocity);
5689 if (velspeed > speed * 12 * scale) {
5690 velocity /= velspeed;
5691 velspeed = speed * 12 * scale;
5692 velocity *= velspeed;
5694 velocity.y += gravity * multiplier * 20;
5695 ReflectVector(&velocity, terrain.getNormal(coords.x, coords.z));
5696 velspeed = findLength(&velocity);
5697 velocity = DoRotation(flatfacing * velspeed, 0, -90, 0);
5700 if (animTarget == staggerbackhighanim) {
5701 coords -= facing * multiplier * speed * 16 * scale;
5704 if (animTarget == staggerbackhardanim && animation[staggerbackhardanim].label[frameTarget] != 6) {
5705 coords -= facing * multiplier * speed * 20 * scale;
5709 if (animTarget == backhandspringanim) {
5710 //coords-=facing*multiplier*50*scale;
5711 velocity += facing * multiplier * speed * 700 * scale * -1;
5712 velspeed = findLength(&velocity);
5713 if (velspeed > speed * 50 * scale) {
5714 velocity /= velspeed;
5715 velspeed = speed * 50 * scale;
5716 velocity *= velspeed;
5718 velocity.y += gravity * multiplier * 20;
5719 ReflectVector(&velocity, terrain.getNormal(coords.x, coords.z));
5720 velspeed = findLength(&velocity);
5721 velocity = flatfacing * velspeed * -1;
5723 if (animTarget == dodgebackanim) {
5724 //coords-=facing*multiplier*50*scale;
5725 velocity += facing * multiplier * speed * 700 * scale * -1;
5726 velspeed = findLength(&velocity);
5727 if (velspeed > speed * 60 * scale) {
5728 velocity /= velspeed;
5729 velspeed = speed * 60 * scale;
5730 velocity *= velspeed;
5732 velocity.y += gravity * multiplier * 20;
5733 ReflectVector(&velocity, terrain.getNormal(coords.x, coords.z));
5734 velspeed = findLength(&velocity);
5735 velocity = flatfacing * velspeed * -1;
5738 if (animTarget == jumpupanim || animTarget == jumpdownanim || isFlip()) {
5739 velspeed = findLength(&velocity);
5743 if (animTarget == jumpupanim || animTarget == jumpdownanim || isFlip()) {
5744 velocity.y += gravity * multiplier;
5747 if (animTarget != climbanim && animTarget != hanganim && !isWallJump())
5748 coords += velocity * multiplier;
5750 if (coords.y < terrain.getHeight(coords.x, coords.z) && (animTarget == jumpdownanim || animTarget == jumpupanim || isFlip())) {
5751 if (isFlip() && animation[animTarget].label[frameTarget] == 7)
5754 if (animTarget == jumpupanim) {
5756 animTarget = getIdle();
5763 pause_sound(whooshsound);
5764 OPENAL_SetVolume(channels[whooshsound], 0);
5767 if (animTarget == jumpdownanim || isFlip()) {
5768 if (isFlip())jumppower = -4;
5769 animTarget = getLanding();
5770 emit_sound_at(landsound, coords, 128.);
5773 envsound[numenvsounds] = coords;
5774 envsoundvol[numenvsounds] = 16;
5775 envsoundlife[numenvsounds] = .4;
5781 if (animTarget != jumpupanim && animTarget != jumpdownanim && !isFlip() && animTarget != climbanim && animTarget != hanganim && !isWallJump())
5782 coords.y += gravity * multiplier * 2;
5783 if (animTarget != jumpupanim && animTarget != jumpdownanim && !isFlip() && coords.y < terrain.getHeight(coords.x, coords.z)) {
5784 coords.y = terrain.getHeight(coords.x, coords.z);
5789 if (isIdle() || animTarget == drawrightanim || animTarget == drawleftanim || animTarget == crouchdrawrightanim || animTarget == crouchstabanim || animTarget == swordgroundstabanim || isStop() || animTarget == removeknifeanim || animTarget == crouchremoveknifeanim || isLanding() || isCrouch() || animation[animTarget].attack || (animTarget == rollanim && animation[animTarget].label[frameTarget] == 6)) {
5790 velspeed = findLength(&velocity);
5792 if (velspeed < multiplier * 300 * scale) {
5795 velocity -= velocity / velspeed * multiplier * 300 * scale;
5796 if (velspeed > 5 && (isLanding() || isLandhard())) {
5797 skiddingdelay += multiplier;
5798 if (skiddelay <= 0) {
5808 velspeed = findLength(&velocity);
5810 if (velspeed < multiplier * 600 * scale) {
5813 velocity -= velocity / velspeed * multiplier * 600 * scale;
5815 if (velspeed > 5 && (isLanding() || isLandhard())) {
5816 skiddingdelay += multiplier;
5817 if (skiddelay <= 0) {
5826 if (skiddingdelay < 0)
5827 skiddingdelay += multiplier;
5828 if (skiddingdelay > .02 && !forwardkeydown && !backkeydown && !leftkeydown && !rightkeydown && !jumpkeydown && isLanding() && !landhard) {
5830 if (!onterrain || environment == grassyenvironment) {
5831 emit_sound_at(skidsound, coords, 128 * velspeed / 10);
5833 emit_sound_at(snowskidsound, coords, 128 * velspeed / 10);
5837 if (animation[animTarget].attack == normalattack && animTarget != rabbitkickanim && !victim->skeleton.free) {
5838 terrainnormal = victim->coords - coords;
5839 Normalise(&terrainnormal);
5840 targetyaw = -asin(0 - terrainnormal.x);
5841 targetyaw *= 360 / 6.28;
5842 if (terrainnormal.z < 0)
5843 targetyaw = 180 - targetyaw;
5844 targettilt2 = -asin(terrainnormal.y) * 360 / 6.28; //*-70;
5847 if (animation[animTarget].attack == reversal && animTarget != rabbittacklinganim) {
5848 targetyaw = victim->targetyaw;
5850 if (animTarget == rabbittacklinganim) {
5851 coords = victim->coords;
5854 skeleton.oldfree = skeleton.free;
5858 midterrain.x = terrain.size * terrain.scale / 2;
5859 midterrain.z = terrain.size * terrain.scale / 2;
5860 if (distsqflat(&coords, &midterrain) > (terrain.size * terrain.scale / 2 - viewdistance) * (terrain.size * terrain.scale / 2 - viewdistance)) {
5862 tempposit = coords - midterrain;
5864 Normalise(&tempposit);
5865 tempposit *= (terrain.size * terrain.scale / 2 - viewdistance);
5866 coords.x = tempposit.x + midterrain.x;
5867 coords.z = tempposit.z + midterrain.z;
5873 * inverse kinematics helper function
5875 void IKHelper(Person *p, float interp)
5877 XYZ point, newpoint, change, change2;
5878 float heightleft, heightright;
5880 // TODO: implement localToWorld and worldToLocal
5881 // but keep in mind it won't be the same math if player is ragdolled or something
5882 // - localToWorldStanding / worldToLocalStanding (or crouching or...?)
5883 // then comb through code for places where to use it
5885 // point = localToWorld(jointPos(leftfoot))
5886 point = DoRotation(p->jointPos(leftfoot), 0, p->yaw, 0) * p->scale + p->coords;
5887 // adjust height of foot
5888 heightleft = terrain.getHeight(point.x, point.z) + .04;
5889 point.y = heightleft;
5890 change = p->jointPos(leftankle) - p->jointPos(leftfoot);
5891 change2 = p->jointPos(leftknee) - p->jointPos(leftfoot);
5892 // jointPos(leftfoot) = interpolate(worldToLocal(point), jointPos(leftfoot), interp)
5893 p->jointPos(leftfoot) = DoRotation((point - p->coords) / p->scale, 0, -p->yaw, 0) * interp + p->jointPos(leftfoot) * (1 - interp);
5894 // move ankle along with foot
5895 p->jointPos(leftankle) = p->jointPos(leftfoot) + change;
5896 // average knee pos between old and new pos
5897 p->jointPos(leftknee) = (p->jointPos(leftfoot) + change2) / 2 + (p->jointPos(leftknee)) / 2;
5899 // do same as above for right leg
5900 point = DoRotation(p->jointPos(rightfoot), 0, p->yaw, 0) * p->scale + p->coords;
5901 heightright = terrain.getHeight(point.x, point.z) + .04;
5902 point.y = heightright;
5903 change = p->jointPos(rightankle) - p->jointPos(rightfoot);
5904 change2 = p->jointPos(rightknee) - p->jointPos(rightfoot);
5905 p->jointPos(rightfoot) = DoRotation((point - p->coords) / p->scale, 0, -p->yaw, 0) * interp + p->jointPos(rightfoot) * (1 - interp);
5906 p->jointPos(rightankle) = p->jointPos(rightfoot) + change;
5907 p->jointPos(rightknee) = (p->jointPos(rightfoot) + change2) / 2 + (p->jointPos(rightknee)) / 2;
5909 // fix up skeleton now that we've moved body parts?
5910 p->skeleton.DoConstraints(&p->coords, &p->scale);
5917 int Person::DrawSkeleton()
5919 int oldplayerdetail;
5920 if ((frustum.SphereInFrustum(coords.x, coords.y + scale * 3, coords.z, scale * 8) && distsq(&viewer, &coords) < viewdistance * viewdistance) || skeleton.free == 3) {
5921 if (onterrain && (isIdle() || isCrouch() || wasIdle() || wasCrouch()) && !skeleton.free) {
5931 glAlphaFunc(GL_GREATER, 0.0001);
5933 float terrainheight;
5937 if (!isnormal(tilt))
5939 if (!isnormal(tilt2))
5941 oldplayerdetail = playerdetail;
5943 if (distsq(&viewer, &coords) < viewdistance * viewdistance / 32 && detail == 2) {
5946 if (distsq(&viewer, &coords) < viewdistance * viewdistance / 128 && detail == 1) {
5949 if (distsq(&viewer, &coords) < viewdistance * viewdistance / 256 && (detail != 1 && detail != 2)) {
5954 if (playerdetail != oldplayerdetail) {
5956 normalsupdatedelay = 0;
5958 static float updatedelaychange;
5959 static float morphness;
5960 static float framemult;
5962 skeleton.FindForwards();
5963 if (howactive == typesittingwall) {
5964 skeleton.specialforward[1] = 0;
5965 skeleton.specialforward[1].z = 1;
5971 static int weaponattachmuscle;
5972 static int weaponrotatemuscle;
5973 static XYZ weaponpoint;
5974 static int start, endthing;
5975 if ((dead != 2 || skeleton.free != 2) && updatedelay <= 0) {
5976 if (!isSleeping() && !isSitting()) {
5977 // TODO: give these meaningful names
5978 const bool cond1 = (isIdle() || isCrouch() || isLanding() || isLandhard()
5979 || animTarget == drawrightanim || animTarget == drawleftanim || animTarget == crouchdrawrightanim);
5980 const bool cond2 = (wasIdle() || wasCrouch() || wasLanding() || wasLandhard()
5981 || animCurrent == drawrightanim || animCurrent == drawleftanim || animCurrent == crouchdrawrightanim);
5983 if (onterrain && (cond1 && cond2) && !skeleton.free) {
5985 if (creature == wolftype)
5989 if (onterrain && (cond1 && !cond2) && !skeleton.free) {
5990 IKHelper(this, target);
5991 if (creature == wolftype)
5992 IKHelper(this, target);
5995 if (onterrain && (!cond1 && cond2) && !skeleton.free) {
5996 IKHelper(this, 1 - target);
5997 if (creature == wolftype)
5998 IKHelper(this, 1 - target);
6002 if (!skeleton.free && (!animation[animTarget].attack && animTarget != getupfrombackanim && ((animTarget != rollanim && !isFlip()) || animation[animTarget].label[frameTarget] == 6) && animTarget != getupfromfrontanim && animTarget != wolfrunninganim && animTarget != rabbitrunninganim && animTarget != backhandspringanim && animTarget != walljumpfrontanim && animTarget != hurtidleanim && !isLandhard() && !isSleeping()))
6005 targetheadyaw = -targetyaw;
6006 targetheadpitch = 0;
6007 if (animation[animTarget].attack == 3)
6008 targetheadyaw += 180;
6010 for (i = 0; i < skeleton.drawmodel.vertexNum; i++) {
6011 skeleton.drawmodel.vertex[i] = 0;
6012 skeleton.drawmodel.vertex[i].y = 999;
6014 for (i = 0; i < skeleton.drawmodellow.vertexNum; i++) {
6015 skeleton.drawmodellow.vertex[i] = 0;
6016 skeleton.drawmodellow.vertex[i].y = 999;
6018 for (i = 0; i < skeleton.drawmodelclothes.vertexNum; i++) {
6019 skeleton.drawmodelclothes.vertex[i] = 0;
6020 skeleton.drawmodelclothes.vertex[i].y = 999;
6022 for (int i = 0; i < skeleton.num_muscles; i++) {
6023 // convenience renames
6024 const int p1 = skeleton.muscles[i].parent1->label;
6025 const int p2 = skeleton.muscles[i].parent2->label;
6027 if ((skeleton.muscles[i].numvertices > 0 && playerdetail) || (skeleton.muscles[i].numverticeslow > 0 && !playerdetail)) {
6032 if (p1 == righthand || p2 == righthand) {
6033 morphness = righthandmorphness;
6034 start = righthandmorphstart;
6035 endthing = righthandmorphend;
6037 if (p1 == lefthand || p2 == lefthand) {
6038 morphness = lefthandmorphness;
6039 start = lefthandmorphstart;
6040 endthing = lefthandmorphend;
6042 if (p1 == head || p2 == head) {
6043 morphness = headmorphness;
6044 start = headmorphstart;
6045 endthing = headmorphend;
6047 if ((p1 == neck && p2 == abdomen) || (p2 == neck && p1 == abdomen)) {
6048 morphness = chestmorphness;
6049 start = chestmorphstart;
6050 endthing = chestmorphend;
6052 if ((p1 == groin && p2 == abdomen) || (p2 == groin && p1 == abdomen)) {
6053 morphness = tailmorphness;
6054 start = tailmorphstart;
6055 endthing = tailmorphend;
6058 skeleton.FindRotationMuscle(i, animTarget);
6059 mid = (skeleton.muscles[i].parent1->position + skeleton.muscles[i].parent2->position) / 2;
6060 glMatrixMode(GL_MODELVIEW);
6064 glRotatef(tilt2, 1, 0, 0);
6066 glRotatef(tilt, 0, 0, 1);
6069 glTranslatef(mid.x, mid.y, mid.z);
6071 skeleton.muscles[i].lastrotate1 = skeleton.muscles[i].rotate1;
6072 glRotatef(-skeleton.muscles[i].lastrotate1 + 90, 0, 1, 0);
6074 skeleton.muscles[i].lastrotate2 = skeleton.muscles[i].rotate2;
6075 glRotatef(-skeleton.muscles[i].lastrotate2 + 90, 0, 0, 1);
6077 skeleton.muscles[i].lastrotate3 = skeleton.muscles[i].rotate3;
6078 glRotatef(-skeleton.muscles[i].lastrotate3, 0, 1, 0);
6080 if (playerdetail || skeleton.free == 3) {
6081 for (j = 0; j < skeleton.muscles[i].numvertices; j++) {
6082 XYZ &v0 = skeleton.model[start].vertex[skeleton.muscles[i].vertices[j]];
6083 XYZ &v1 = skeleton.model[endthing].vertex[skeleton.muscles[i].vertices[j]];
6084 glMatrixMode(GL_MODELVIEW);
6086 if (p1 == abdomen || p2 == abdomen)
6087 glTranslatef((v0.x * (1 - morphness) + v1.x * morphness) * proportionbody.x,
6088 (v0.y * (1 - morphness) + v1.y * morphness) * proportionbody.y,
6089 (v0.z * (1 - morphness) + v1.z * morphness) * proportionbody.z);
6090 if (p1 == lefthand || p1 == righthand || p1 == leftwrist || p1 == rightwrist || p1 == leftelbow || p1 == rightelbow || p2 == leftelbow || p2 == rightelbow)
6091 glTranslatef((v0.x * (1 - morphness) + v1.x * morphness) * proportionarms.x,
6092 (v0.y * (1 - morphness) + v1.y * morphness) * proportionarms.y,
6093 (v0.z * (1 - morphness) + v1.z * morphness) * proportionarms.z);
6094 if (p1 == leftfoot || p1 == rightfoot || p1 == leftankle || p1 == rightankle || p1 == leftknee || p1 == rightknee || p2 == leftknee || p2 == rightknee)
6095 glTranslatef((v0.x * (1 - morphness) + v1.x * morphness) * proportionlegs.x,
6096 (v0.y * (1 - morphness) + v1.y * morphness) * proportionlegs.y,
6097 (v0.z * (1 - morphness) + v1.z * morphness) * proportionlegs.z);
6098 if (p1 == head || p2 == head)
6099 glTranslatef((v0.x * (1 - morphness) + v1.x * morphness) * proportionhead.x,
6100 (v0.y * (1 - morphness) + v1.y * morphness) * proportionhead.y,
6101 (v0.z * (1 - morphness) + v1.z * morphness) * proportionhead.z);
6102 glGetFloatv(GL_MODELVIEW_MATRIX, M);
6103 //if(!isnormal(M[12])||!isnormal(M[13])||!isnormal(M[14]))test=0;
6104 //if(!isnormal(scale))test=1;
6105 skeleton.drawmodel.vertex[skeleton.muscles[i].vertices[j]].x = M[12] * scale;
6106 skeleton.drawmodel.vertex[skeleton.muscles[i].vertices[j]].y = M[13] * scale;
6107 skeleton.drawmodel.vertex[skeleton.muscles[i].vertices[j]].z = M[14] * scale;
6112 if (!playerdetail || skeleton.free == 3) {
6113 for (j = 0; j < skeleton.muscles[i].numverticeslow; j++) {
6114 XYZ &v0 = skeleton.modellow.vertex[skeleton.muscles[i].verticeslow[j]];
6115 glMatrixMode(GL_MODELVIEW);
6117 if (p1 == abdomen || p2 == abdomen)
6118 glTranslatef(v0.x * proportionbody.x,
6119 v0.y * proportionbody.y,
6120 v0.z * proportionbody.z);
6121 if (p1 == lefthand || p1 == righthand || p1 == leftwrist || p1 == rightwrist || p1 == leftelbow || p1 == rightelbow || p2 == leftelbow || p2 == rightelbow)
6122 glTranslatef(v0.x * proportionarms.x,
6123 v0.y * proportionarms.y,
6124 v0.z * proportionarms.z);
6125 if (p1 == leftfoot || p1 == rightfoot || p1 == leftankle || p1 == rightankle || p1 == leftknee || p1 == rightknee || p2 == leftknee || p2 == rightknee)
6126 glTranslatef(v0.x * proportionlegs.x,
6127 v0.y * proportionlegs.y,
6128 v0.z * proportionlegs.z);
6129 if (p1 == head || p2 == head)
6130 glTranslatef(v0.x * proportionhead.x,
6131 v0.y * proportionhead.y,
6132 v0.z * proportionhead.z);
6134 glGetFloatv(GL_MODELVIEW_MATRIX, M);
6135 skeleton.drawmodellow.vertex[skeleton.muscles[i].verticeslow[j]].x = M[12] * scale;
6136 skeleton.drawmodellow.vertex[skeleton.muscles[i].verticeslow[j]].y = M[13] * scale;
6137 skeleton.drawmodellow.vertex[skeleton.muscles[i].verticeslow[j]].z = M[14] * scale;
6143 if (skeleton.clothes && skeleton.muscles[i].numverticesclothes > 0) {
6144 mid = (skeleton.muscles[i].parent1->position + skeleton.muscles[i].parent2->position) / 2;
6146 glMatrixMode(GL_MODELVIEW);
6150 glRotatef(tilt2, 1, 0, 0);
6152 glRotatef(tilt, 0, 0, 1);
6153 glTranslatef(mid.x, mid.y, mid.z);
6154 skeleton.muscles[i].lastrotate1 = skeleton.muscles[i].rotate1;
6155 glRotatef(-skeleton.muscles[i].lastrotate1 + 90, 0, 1, 0);
6157 skeleton.muscles[i].lastrotate2 = skeleton.muscles[i].rotate2;
6158 glRotatef(-skeleton.muscles[i].lastrotate2 + 90, 0, 0, 1);
6160 skeleton.muscles[i].lastrotate3 = skeleton.muscles[i].rotate3;
6161 glRotatef(-skeleton.muscles[i].lastrotate3, 0, 1, 0);
6163 for (j = 0; j < skeleton.muscles[i].numverticesclothes; j++) {
6164 XYZ &v0 = skeleton.modelclothes.vertex[skeleton.muscles[i].verticesclothes[j]];
6165 glMatrixMode(GL_MODELVIEW);
6167 if (p1 == abdomen || p2 == abdomen)
6168 glTranslatef(v0.x * proportionbody.x,
6169 v0.y * proportionbody.y,
6170 v0.z * proportionbody.z);
6171 if (p1 == lefthand || p1 == righthand || p1 == leftwrist || p1 == rightwrist || p1 == leftelbow || p1 == rightelbow || p2 == leftelbow || p2 == rightelbow)
6172 glTranslatef(v0.x * proportionarms.x,
6173 v0.y * proportionarms.y,
6174 v0.z * proportionarms.z);
6175 if (p1 == leftfoot || p1 == rightfoot || p1 == leftankle || p1 == rightankle || p1 == leftknee || p1 == rightknee || p2 == leftknee || p2 == rightknee)
6176 glTranslatef(v0.x * proportionlegs.x,
6177 v0.y * proportionlegs.y,
6178 v0.z * proportionlegs.z);
6179 if (p1 == head || p2 == head)
6180 glTranslatef(v0.x * proportionhead.x,
6181 v0.y * proportionhead.y,
6182 v0.z * proportionhead.z);
6183 glGetFloatv(GL_MODELVIEW_MATRIX, M);
6184 skeleton.drawmodelclothes.vertex[skeleton.muscles[i].verticesclothes[j]].x = M[12] * scale;
6185 skeleton.drawmodelclothes.vertex[skeleton.muscles[i].verticesclothes[j]].y = M[13] * scale;
6186 skeleton.drawmodelclothes.vertex[skeleton.muscles[i].verticesclothes[j]].z = M[14] * scale;
6191 updatedelay = 1 + (float)(Random() % 100) / 1000;
6193 if (skeleton.free != 2 && (skeleton.free == 1 || skeleton.free == 3 || id == 0 || (normalsupdatedelay <= 0) || animTarget == getupfromfrontanim || animTarget == getupfrombackanim || animCurrent == getupfromfrontanim || animCurrent == getupfrombackanim)) {
6194 normalsupdatedelay = 1;
6195 if (playerdetail || skeleton.free == 3)
6196 skeleton.drawmodel.CalculateNormals(0);
6197 if (!playerdetail || skeleton.free == 3)
6198 skeleton.drawmodellow.CalculateNormals(0);
6199 if (skeleton.clothes)
6200 skeleton.drawmodelclothes.CalculateNormals(0);
6202 if (playerdetail || skeleton.free == 3)
6203 skeleton.drawmodel.UpdateVertexArrayNoTexNoNorm();
6204 if (!playerdetail || skeleton.free == 3)
6205 skeleton.drawmodellow.UpdateVertexArrayNoTexNoNorm();
6206 if (skeleton.clothes) {
6207 skeleton.drawmodelclothes.UpdateVertexArrayNoTexNoNorm();
6212 updatedelaychange = -framemult * 4 * (45 - findDistance(&viewer, &coords) * 1);
6213 if (updatedelaychange > -realmultiplier * 30)
6214 updatedelaychange = -realmultiplier * 30;
6215 if (updatedelaychange > -framemult * 4)
6216 updatedelaychange = -framemult * 4;
6217 if (skeleton.free == 1)
6218 updatedelaychange *= 6;
6220 updatedelaychange *= 8;
6221 updatedelay += updatedelaychange;
6223 glMatrixMode(GL_MODELVIEW);
6226 glTranslatef(coords.x, coords.y - .02, coords.z);
6228 glTranslatef(coords.x, coords.y - .02, coords.z);
6230 glTranslatef(offset.x * scale, offset.y * scale, offset.z * scale);
6232 glRotatef(yaw, 0, 1, 0);
6235 glColor4f(.4, 1, .4, 1);
6236 glDisable(GL_LIGHTING);
6237 glDisable(GL_TEXTURE_2D);
6240 for (i = 0; i < skeleton.drawmodel.vertexNum; i++) {
6241 XYZ &v0 = skeleton.drawmodel.vertex[i];
6242 glVertex3f(v0.x, v0.y, v0.z);
6248 for (i = 0; i < skeleton.drawmodel.TriangleNum; i++) {
6249 XYZ &v0 = skeleton.drawmodel.vertex[skeleton.drawmodel.Triangles[i].vertex[0]];
6250 XYZ &v1 = skeleton.drawmodel.vertex[skeleton.drawmodel.Triangles[i].vertex[1]];
6251 XYZ &v2 = skeleton.drawmodel.vertex[skeleton.drawmodel.Triangles[i].vertex[2]];
6252 glVertex3f(v0.x, v0.y, v0.z);
6253 glVertex3f(v1.x, v1.y, v1.z);
6254 glVertex3f(v1.x, v1.y, v1.z);
6255 glVertex3f(v2.x, v2.y, v2.z);
6256 glVertex3f(v2.x, v2.y, v2.z);
6257 glVertex3f(v0.x, v0.y, v0.z);
6263 terrainlight = terrain.getLighting(coords.x, coords.z);
6264 distance = distsq(&viewer, &coords);
6265 distance = (viewdistance * viewdistance - (distance - (viewdistance * viewdistance * fadestart)) * (1 / (1 - fadestart))) / viewdistance / viewdistance;
6269 terrainheight = (coords.y - terrain.getHeight(coords.x, coords.z)) / 3 + 1;
6270 if (terrainheight < 1)
6272 if (terrainheight > 1.7)
6273 terrainheight = 1.7;
6276 glColor4f((1 - (1 - terrainlight.x) / terrainheight) - burnt, (1 - (1 - terrainlight.y) / terrainheight) - burnt, (1 - (1 - terrainlight.z) / terrainheight) - burnt, distance);
6277 glDisable(GL_BLEND);
6278 glAlphaFunc(GL_GREATER, 0.0001);
6279 glEnable(GL_TEXTURE_2D);
6281 glDisable(GL_TEXTURE_2D);
6282 glColor4f(.7, .35, 0, .5);
6284 glEnable(GL_LIGHTING);
6287 if (tutoriallevel && id != 0) {
6288 //glDisable(GL_TEXTURE_2D);
6289 glColor4f(.7, .7, .7, 0.6);
6291 glEnable(GL_LIGHTING);
6293 if (canattack && cananger)
6294 if (animation[animTarget].attack == normalattack || animation[animTarget].attack == reversed) {
6295 glDisable(GL_TEXTURE_2D);
6296 glColor4f(1, 0, 0, 0.8);
6298 glMatrixMode(GL_TEXTURE);
6300 glTranslatef(0, -smoketex, 0);
6301 glTranslatef(-smoketex, 0, 0);
6305 if ((tutoriallevel && id != 0))
6306 skeleton.drawmodel.drawdifftex(Sprite::cloudimpacttexture);
6308 skeleton.drawmodel.draw();
6311 if (!playerdetail) {
6312 if ((tutoriallevel && id != 0))
6313 skeleton.drawmodellow.drawdifftex(Sprite::cloudimpacttexture);
6315 skeleton.drawmodellow.drawdifftex(skeleton.drawmodel.textureptr);
6318 if (!(animation[animTarget].attack == normalattack || animation[animTarget].attack == reversed))
6319 if (tutoriallevel && id != 0) {
6321 glMatrixMode(GL_MODELVIEW);
6322 glEnable(GL_TEXTURE_2D);
6323 glColor4f(.7, .7, .7, 0.6);
6325 glEnable(GL_LIGHTING);
6327 if (canattack && cananger)
6328 if (animation[animTarget].attack == normalattack || animation[animTarget].attack == reversed) {
6329 glDisable(GL_TEXTURE_2D);
6330 glColor4f(1, 0, 0, 0.8);
6332 glMatrixMode(GL_TEXTURE);
6334 glTranslatef(0, -smoketex * .6, 0);
6335 glTranslatef(smoketex * .6, 0, 0);
6338 if ((tutoriallevel && id != 0))
6339 skeleton.drawmodel.drawdifftex(Sprite::cloudimpacttexture);
6341 skeleton.drawmodel.draw();
6344 if (!playerdetail) {
6345 if ((tutoriallevel && id != 0))
6346 skeleton.drawmodellow.drawdifftex(Sprite::cloudimpacttexture);
6348 skeleton.drawmodellow.drawdifftex(skeleton.drawmodel.textureptr);
6353 if (tutoriallevel && id != 0) {
6355 glMatrixMode(GL_MODELVIEW);
6356 glEnable(GL_TEXTURE_2D);
6358 if (skeleton.clothes) {
6362 skeleton.drawmodelclothes.draw();
6364 skeleton.drawmodelclothes.drawimmediate();
6370 if (num_weapons > 0) {
6371 for (k = 0; k < num_weapons; k++) {
6373 if (weaponactive == k) {
6374 if (weapons[i].getType() != staff) {
6375 for (j = 0; j < skeleton.num_muscles; j++) {
6376 if ((skeleton.muscles[j].parent1->label == righthand || skeleton.muscles[j].parent2->label == righthand) && skeleton.muscles[j].numvertices > 0) {
6377 weaponattachmuscle = j;
6380 for (j = 0; j < skeleton.num_muscles; j++) {
6381 if ((skeleton.muscles[j].parent1->label == rightwrist || skeleton.muscles[j].parent2->label == rightwrist) && (skeleton.muscles[j].parent1->label != righthand && skeleton.muscles[j].parent2->label != righthand) && skeleton.muscles[j].numvertices > 0) {
6382 weaponrotatemuscle = j;
6385 weaponpoint = (skeleton.muscles[weaponattachmuscle].parent1->position + skeleton.muscles[weaponattachmuscle].parent2->position) / 2;
6386 if (creature == wolftype)
6387 weaponpoint = (jointPos(rightwrist) * .7 + jointPos(righthand) * .3);
6389 if (weapons[i].getType() == staff) {
6390 for (j = 0; j < skeleton.num_muscles; j++) {
6391 if ((skeleton.muscles[j].parent1->label == righthand || skeleton.muscles[j].parent2->label == righthand) && skeleton.muscles[j].numvertices > 0) {
6392 weaponattachmuscle = j;
6395 for (j = 0; j < skeleton.num_muscles; j++) {
6396 if ((skeleton.muscles[j].parent1->label == rightelbow || skeleton.muscles[j].parent2->label == rightelbow) && (skeleton.muscles[j].parent1->label != rightshoulder && skeleton.muscles[j].parent2->label != rightshoulder) && skeleton.muscles[j].numvertices > 0) {
6397 weaponrotatemuscle = j;
6400 //weaponpoint=jointPos(rightwrist);
6401 weaponpoint = (skeleton.muscles[weaponattachmuscle].parent1->position + skeleton.muscles[weaponattachmuscle].parent2->position) / 2;
6402 //weaponpoint+=skeleton.specialforward[1]*.1+(jointPos(rightwrist)-jointPos(rightelbow));
6403 XYZ tempnormthing, vec1, vec2;
6404 vec1 = (jointPos(rightwrist) - jointPos(rightelbow));
6405 vec2 = (jointPos(rightwrist) - jointPos(rightshoulder));
6406 CrossProduct(&vec1, &vec2, &tempnormthing);
6407 Normalise(&tempnormthing);
6408 if (animTarget != staffhitanim && animCurrent != staffhitanim && animTarget != staffgroundsmashanim && animCurrent != staffgroundsmashanim && animTarget != staffspinhitanim && animCurrent != staffspinhitanim)
6409 weaponpoint += tempnormthing * .1 - skeleton.specialforward[1] * .3 + (jointPos(rightwrist) - jointPos(rightelbow));
6412 if (weaponactive != k && weaponstuck != k) {
6413 if (weapons[i].getType() == knife)
6414 weaponpoint = jointPos(abdomen) + (jointPos(righthip) - jointPos(lefthip)) * .1 + (jointPos(rightshoulder) - jointPos(leftshoulder)) * .35;
6415 if (weapons[i].getType() == sword)
6416 weaponpoint = jointPos(abdomen) + (jointPos(lefthip) - jointPos(righthip)) * .09 + (jointPos(leftshoulder) - jointPos(rightshoulder)) * .33;
6417 if (weapons[i].getType() == staff)
6418 weaponpoint = jointPos(abdomen) + (jointPos(lefthip) - jointPos(righthip)) * .09 + (jointPos(leftshoulder) - jointPos(rightshoulder)) * .33;
6419 for (j = 0; j < skeleton.num_muscles; j++) {
6420 if ((skeleton.muscles[j].parent1->label == abdomen || skeleton.muscles[j].parent2->label == abdomen) && (skeleton.muscles[j].parent1->label == neck || skeleton.muscles[j].parent2->label == neck) && skeleton.muscles[j].numvertices > 0) {
6421 weaponrotatemuscle = j;
6425 if (weaponstuck == k) {
6426 if (weaponstuckwhere == 0)
6427 weaponpoint = jointPos(abdomen) * .5 + jointPos(neck) * .5 - skeleton.forward * .8;
6429 weaponpoint = jointPos(abdomen) * .5 + jointPos(neck) * .5 + skeleton.forward * .8;
6430 for (j = 0; j < skeleton.num_muscles; j++) {
6431 if ((skeleton.muscles[j].parent1->label == abdomen || skeleton.muscles[j].parent2->label == abdomen) && (skeleton.muscles[j].parent1->label == neck || skeleton.muscles[j].parent2->label == neck) && skeleton.muscles[j].numvertices > 0) {
6432 weaponrotatemuscle = j;
6436 if (skeleton.free) {
6437 weapons[i].position = weaponpoint * scale + coords;
6438 weapons[i].bigrotation = 0;
6439 weapons[i].bigtilt = 0;
6440 weapons[i].bigtilt2 = 0;
6442 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;
6443 weapons[i].bigrotation = yaw;
6444 weapons[i].bigtilt = tilt;
6445 weapons[i].bigtilt2 = tilt2;
6447 weapons[i].rotation1 = skeleton.muscles[weaponrotatemuscle].lastrotate1;
6448 weapons[i].rotation2 = skeleton.muscles[weaponrotatemuscle].lastrotate2;
6449 weapons[i].rotation3 = skeleton.muscles[weaponrotatemuscle].lastrotate3;
6450 if (weaponactive == k) {
6451 if (weapons[i].getType() == knife) {
6452 weapons[i].smallrotation = 180;
6453 weapons[i].smallrotation2 = 0;
6454 if (isCrouch() || wasCrouch()) {
6455 weapons[i].smallrotation2 = 20;
6457 if (animTarget == hurtidleanim) {
6458 weapons[i].smallrotation2 = 50;
6460 if ((animCurrent == crouchstabanim && animTarget == crouchstabanim) || (animCurrent == backhandspringanim && animTarget == backhandspringanim)) {
6461 XYZ temppoint1, temppoint2, tempforward;
6464 temppoint1 = jointPos(righthand);
6465 temppoint2 = animation[animCurrent].weapontarget[frameCurrent] * (1 - target) + animation[animTarget].weapontarget[frameTarget] * (target);
6466 distance = findDistance(&temppoint1, &temppoint2);
6467 weapons[i].rotation2 = asin((temppoint1.y - temppoint2.y) / distance);
6468 weapons[i].rotation2 *= 360 / 6.28;
6471 weapons[i].rotation1 = acos((temppoint1.z - temppoint2.z) / findDistance(&temppoint1, &temppoint2));
6472 weapons[i].rotation1 *= 360 / 6.28;
6473 weapons[i].rotation3 = 0;
6474 weapons[i].smallrotation = -90;
6475 weapons[i].smallrotation2 = 0;
6476 if (temppoint1.x > temppoint2.x)
6477 weapons[i].rotation1 = 360 - weapons[i].rotation1;
6479 if ((animCurrent == knifeslashreversalanim && animTarget == knifeslashreversalanim) || (animCurrent == knifeslashreversedanim && animTarget == knifeslashreversedanim)) {
6480 XYZ temppoint1, temppoint2, tempforward;
6483 temppoint1 = jointPos(righthand);
6484 temppoint2 = animation[animCurrent].weapontarget[frameCurrent] * (1 - target) + animation[animTarget].weapontarget[frameTarget] * (target);
6485 distance = findDistance(&temppoint1, &temppoint2);
6486 weapons[i].rotation2 = asin((temppoint1.y - temppoint2.y) / distance);
6487 weapons[i].rotation2 *= 360 / 6.28;
6490 weapons[i].rotation1 = acos((temppoint1.z - temppoint2.z) / findDistance(&temppoint1, &temppoint2));
6491 weapons[i].rotation1 *= 360 / 6.28;
6492 weapons[i].rotation3 = 0;
6493 weapons[i].smallrotation = 90;
6494 weapons[i].smallrotation2 = 0;
6495 if (temppoint1.x > temppoint2.x)
6496 weapons[i].rotation1 = 360 - weapons[i].rotation1;
6498 if (animTarget == knifethrowanim) {
6499 weapons[i].smallrotation = 90;
6500 //weapons[i].smallrotation2=-90;
6501 weapons[i].smallrotation2 = 0;
6502 weapons[i].rotation1 = 0;
6503 weapons[i].rotation2 = 0;
6504 weapons[i].rotation3 = 0;
6506 if (animTarget == knifesneakattackanim && frameTarget < 5) {
6507 weapons[i].smallrotation = -90;
6508 weapons[i].rotation1 = 0;
6509 weapons[i].rotation2 = 0;
6510 weapons[i].rotation3 = 0;
6513 if (weapons[i].getType() == sword) {
6514 weapons[i].smallrotation = 0;
6515 weapons[i].smallrotation2 = 0;
6516 if (animTarget == knifethrowanim) {
6517 weapons[i].smallrotation = -90;
6518 weapons[i].smallrotation2 = 0;
6519 weapons[i].rotation1 = 0;
6520 weapons[i].rotation2 = 0;
6521 weapons[i].rotation3 = 0;
6523 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)) {
6524 XYZ temppoint1, temppoint2, tempforward;
6527 temppoint1 = animation[animCurrent].position[skeleton.jointlabels[righthand]][frameCurrent] * (1 - target) + animation[animTarget].position[skeleton.jointlabels[righthand]][frameTarget] * (target); //jointPos(righthand);
6528 temppoint2 = animation[animCurrent].weapontarget[frameCurrent] * (1 - target) + animation[animTarget].weapontarget[frameTarget] * (target);
6529 distance = findDistance(&temppoint1, &temppoint2);
6530 weapons[i].rotation2 = asin((temppoint1.y - temppoint2.y) / distance);
6531 weapons[i].rotation2 *= 360 / 6.28;
6534 weapons[i].rotation1 = acos((temppoint1.z - temppoint2.z) / findDistance(&temppoint1, &temppoint2));
6535 weapons[i].rotation1 *= 360 / 6.28;
6536 weapons[i].rotation3 = 0;
6537 weapons[i].smallrotation = 90;
6538 weapons[i].smallrotation2 = 0;
6539 if (temppoint1.x > temppoint2.x)
6540 weapons[i].rotation1 = 360 - weapons[i].rotation1;
6543 if (weapons[i].getType() == staff) {
6544 weapons[i].smallrotation = 100;
6545 weapons[i].smallrotation2 = 0;
6546 if ((animTarget == staffhitanim && animCurrent == staffhitanim) || (animTarget == staffhitreversedanim && animCurrent == staffhitreversedanim) || (animTarget == staffspinhitreversedanim && animCurrent == staffspinhitreversedanim) || (animTarget == staffgroundsmashanim && animCurrent == staffgroundsmashanim) || (animTarget == staffspinhitanim && animCurrent == staffspinhitanim)) {
6547 XYZ temppoint1, temppoint2, tempforward;
6550 temppoint1 = animation[animCurrent].position[skeleton.jointlabels[righthand]][frameCurrent] * (1 - target) + animation[animTarget].position[skeleton.jointlabels[righthand]][frameTarget] * (target); //jointPos(righthand);
6551 temppoint2 = animation[animCurrent].weapontarget[frameCurrent] * (1 - target) + animation[animTarget].weapontarget[frameTarget] * (target);
6552 distance = findDistance(&temppoint1, &temppoint2);
6553 weapons[i].rotation2 = asin((temppoint1.y - temppoint2.y) / distance);
6554 weapons[i].rotation2 *= 360 / 6.28;
6557 weapons[i].rotation1 = acos((temppoint1.z - temppoint2.z) / findDistance(&temppoint1, &temppoint2));
6558 weapons[i].rotation1 *= 360 / 6.28;
6559 weapons[i].rotation3 = 0;
6560 weapons[i].smallrotation = 90;
6561 weapons[i].smallrotation2 = 0;
6562 if (temppoint1.x > temppoint2.x)
6563 weapons[i].rotation1 = 360 - weapons[i].rotation1;
6567 if (weaponactive != k && weaponstuck != k) {
6568 if (weapons[i].getType() == knife) {
6569 weapons[i].smallrotation = -70;
6570 weapons[i].smallrotation2 = 10;
6572 if (weapons[i].getType() == sword) {
6573 weapons[i].smallrotation = -100;
6574 weapons[i].smallrotation2 = -8;
6576 if (weapons[i].getType() == staff) {
6577 weapons[i].smallrotation = -100;
6578 weapons[i].smallrotation2 = -8;
6581 if (weaponstuck == k) {
6582 if (weaponstuckwhere == 0)
6583 weapons[i].smallrotation = 180;
6585 weapons[i].smallrotation = 0;
6586 weapons[i].smallrotation2 = 10;
6595 if (animation[animTarget].attack || isRun() || animTarget == staggerbackhardanim || isFlip() || animTarget == climbanim || animTarget == sneakanim || animTarget == rollanim || animTarget == walkanim || animTarget == backhandspringanim || isFlip() || isWallJump())
6597 if (animCurrent != animTarget)
6599 //if(id==0)calcrot=1;
6600 if (skeleton.free == 2)
6609 int Person::SphereCheck(XYZ *p1, float radius, XYZ *p, XYZ *move, float *rotate, Model *model)
6612 static float distance;
6613 static float olddistance;
6614 static int intersecting;
6615 static int firstintersecting;
6618 static XYZ start, end;
6619 static float slopethreshold = -.4;
6621 firstintersecting = -1;
6625 if (distsq(p1, &model->boundingspherecenter) > radius * radius + model->boundingsphereradius * model->boundingsphereradius)
6628 *p1 = DoRotation(*p1, 0, -*rotate, 0);
6629 for (i = 0; i < 4; i++) {
6630 for (j = 0; j < model->TriangleNum; j++) {
6631 if (model->facenormals[j].y <= slopethreshold) {
6633 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)));
6634 if (distance < radius) {
6635 point = *p1 - model->facenormals[j] * distance;
6636 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]]))
6639 intersecting = sphere_line_intersection(&model->vertex[model->Triangles[j].vertex[0]],
6640 &model->vertex[model->Triangles[j].vertex[1]],
6643 intersecting = sphere_line_intersection(&model->vertex[model->Triangles[j].vertex[1]],
6644 &model->vertex[model->Triangles[j].vertex[2]],
6647 intersecting = sphere_line_intersection(&model->vertex[model->Triangles[j].vertex[0]],
6648 &model->vertex[model->Triangles[j].vertex[2]],
6651 if (dotproduct(&model->facenormals[j], &end) > 0 && intersecting) {
6655 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)) {
6656 p1->y = point.y + radius;
6657 if ((animTarget == jumpdownanim || isFlip())) {
6658 if (isFlip() && (frameTarget < 5 || animation[animTarget].label[frameTarget] == 7 || animation[animTarget].label[frameTarget] == 4))
6661 if (animTarget == jumpupanim) {
6663 animTarget = getIdle();
6670 pause_sound(whooshsound);
6671 OPENAL_SetVolume(channels[whooshsound], 0);
6674 if ((animTarget == jumpdownanim || isFlip()) && !wasLanding() && !wasLandhard()) {
6677 animTarget = getLanding();
6678 emit_sound_at(landsound, coords, 128.);
6681 envsound[numenvsounds] = coords;
6682 envsoundvol[numenvsounds] = 16;
6683 envsoundlife[numenvsounds] = .4;
6691 if ((distance < olddistance || firstintersecting == -1) && intersecting) {
6692 olddistance = distance;
6693 firstintersecting = j;
6698 for (j = 0; j < model->TriangleNum; j++) {
6699 if (model->facenormals[j].y > slopethreshold) {
6702 start.y -= radius / 4;
6703 XYZ &v0 = model->vertex[model->Triangles[j].vertex[0]];
6704 XYZ &v1 = model->vertex[model->Triangles[j].vertex[1]];
6705 XYZ &v2 = model->vertex[model->Triangles[j].vertex[2]];
6706 distance = abs((model->facenormals[j].x * start.x)
6707 + (model->facenormals[j].y * start.y)
6708 + (model->facenormals[j].z * start.z)
6709 - ((model->facenormals[j].x * v0.x)
6710 + (model->facenormals[j].y * v0.y)
6711 + (model->facenormals[j].z * v0.z)));
6712 if (distance < radius * .5) {
6713 point = start - model->facenormals[j] * distance;
6714 if (PointInTriangle( &point, model->facenormals[j], &v0, &v1, &v2))
6717 intersecting = sphere_line_intersection(v0.x, v0.y, v0.z, v1.x, v1.y, v1.z, p1->x, p1->y, p1->z, radius / 2);
6719 intersecting = sphere_line_intersection(v1.x, v1.y, v1.z, v2.x, v2.y, v2.z, p1->x, p1->y, p1->z, radius / 2);
6721 intersecting = sphere_line_intersection(v0.x, v0.y, v0.z, v2.x, v2.y, v2.z, p1->x, p1->y, p1->z, radius / 2);
6723 if (dotproduct(&model->facenormals[j], &end) > 0 && intersecting) {
6724 if ((animTarget == jumpdownanim || animTarget == jumpupanim || isFlip())) {
6726 velocity -= DoRotation(model->facenormals[j], 0, *rotate, 0) * findLength(&velocity) * abs(normaldotproduct(velocity, DoRotation(model->facenormals[j], 0, *rotate, 0))); //(distance-radius*.5)/multiplier;
6727 if (findLengthfast(&start) < findLengthfast(&velocity))
6730 *p1 += model->facenormals[j] * (distance - radius * .5);
6733 if ((distance < olddistance || firstintersecting == -1) && intersecting) {
6734 olddistance = distance;
6735 firstintersecting = j;
6742 *p = DoRotation(*p, 0, *rotate, 0);
6745 *p1 = DoRotation(*p1, 0, *rotate, 0);
6747 return firstintersecting;