]> git.jsancho.org Git - lugaru.git/blob - Source/Person.cpp
beautified Person.cpp with AStyle
[lugaru.git] / Source / Person.cpp
1 /*
2 Copyright (C) 2003, 2010 - Wolfire Games
3
4 This file is part of Lugaru.
5
6 Lugaru is free software; you can redistribute it and/or
7 modify it under the terms of the GNU General Public License
8 as published by the Free Software Foundation; either version 2
9 of the License, or (at your option) any later version.
10
11 This program is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
14
15 See the GNU General Public License for more details.
16
17 You should have received a copy of the GNU General Public License
18 along with this program; if not, write to the Free Software
19 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
20 */
21
22 /**> HEADER FILES <**/
23 #include "Person.h"
24 #include "openal_wrapper.h"
25 #include "Animation.h"
26 #include "Sounds.h"
27 #include "Awards.h"
28 #include "Game.h"
29
30 extern float multiplier;
31 extern Terrain terrain;
32 extern float gravity;
33 extern int environment;
34 extern int detail;
35 extern FRUSTUM frustum;
36 extern XYZ viewer;
37 extern float realmultiplier;
38 extern int slomo;
39 extern float slomodelay;
40 extern bool cellophane;
41 extern float texdetail;
42 extern float realtexdetail;
43 extern GLubyte bloodText[512 * 512 * 3];
44 extern GLubyte wolfbloodText[512 * 512 * 3];
45 extern int bloodtoggle;
46 extern Objects objects;
47 extern bool osx;
48 extern bool autoslomo;
49 extern float camerashake;
50 extern float woozy;
51 extern float viewdistance;
52 extern float blackout;
53 extern int difficulty;
54 extern bool decals;
55 extern float fadestart;
56 extern bool freeze;
57 extern bool winfreeze;
58 extern float flashamount, flashr, flashg, flashb;
59 extern int flashdelay;
60 extern bool showpoints;
61 extern bool immediate;
62 extern int test;
63 extern bool tilt2weird;
64 extern bool tiltweird;
65 extern bool midweird;
66 extern bool proportionweird;
67 extern bool vertexweird[6];
68 extern XYZ envsound[30];
69 extern float envsoundvol[30];
70 extern float envsoundlife[30];
71 extern int numenvsounds;
72 extern int tutoriallevel;
73 extern float smoketex;
74 extern int tutorialstage;
75 extern bool reversaltrain;
76 extern bool canattack;
77 extern bool cananger;
78 extern float damagedealt;
79 extern int hostile;
80 extern float hostiletime;
81
82 extern int indialogue;
83
84 extern bool gamestarted;
85
86 Person player[maxplayers];
87
88 void Person::CheckKick()
89 {
90     if (!(hasvictim
91             && (animTarget == rabbitkickanim
92                 && victim
93                 && victim != this
94                 && frameCurrent >= 2
95                 && animCurrent == rabbitkickanim)
96             && (distsq(&coords, &victim->coords) < 1.2)
97             && (!victim->skeleton.free)))
98         return;
99
100     if (animation[victim->animTarget].height != lowheight) {
101         float damagemult = (creature == wolftype ? 2.5 : 1.) * power * power;
102         XYZ relative = velocity;
103         relative.y = 0;
104         Normalise(&relative);
105
106         victim->spurt = 1;
107         DoBlood(.2, 250);
108         if (tutoriallevel != 1)
109             emit_sound_at(heavyimpactsound, victim->coords);
110         victim->RagDoll(0);
111         for (int i = 0; i < victim->skeleton.num_joints; i++) {
112             victim->skeleton.joints[i].velocity += relative * 120 * damagemult;
113         }
114         victim->Puff(neck);
115         victim->DoDamage(100 * damagemult / victim->protectionhigh);
116         if (id == 0)camerashake += .4;
117
118         target = 0;
119         frameCurrent = 3;
120         animTarget = backflipanim;
121         frameTarget = 4;
122         velocity = facing * -10;
123         velocity.y = 5;
124         skeleton.free = 0;
125         if (id == 0)
126             resume_stream(whooshsound);
127
128         award_bonus(id, cannon);
129     } else if (victim->isCrouch()) {
130         animTarget = rabbitkickreversedanim;
131         animCurrent = rabbitkickreversedanim;
132         victim->animCurrent = rabbitkickreversalanim;
133         victim->animTarget = rabbitkickreversalanim;
134         targettilt2 = 0;
135         frameCurrent = 0;
136         frameTarget = 1;
137         target = 0;
138         velocity = 0;
139         victim->oldcoords = victim->coords;
140         coords = victim->coords;
141         victim->targetyaw = targetyaw;
142         victim->victim = this;
143     }
144 }
145
146 void Person::CatchFire()
147 {
148     XYZ flatfacing, flatvelocity;
149     int howmany;
150     for (int i = 0; i < 10; i++) {
151         howmany = abs(Random() % (skeleton.num_joints));
152         if (!skeleton.free)flatvelocity = velocity;
153         if (skeleton.free)flatvelocity = skeleton.joints[howmany].velocity;
154         if (!skeleton.free)flatfacing = DoRotation(DoRotation(DoRotation(skeleton.joints[howmany].position, 0, 0, tilt), tilt2, 0, 0), 0, yaw, 0) * scale + coords;
155         if (skeleton.free)flatfacing = skeleton.joints[howmany].position * scale + coords;
156         Sprite::MakeSprite(flamesprite, flatfacing, flatvelocity, 1, 1, 1, 2, 1);
157     }
158
159     onfiredelay = 0.5;
160
161     emit_sound_at(firestartsound, coords);
162
163     emit_stream_at(stream_firesound, coords);
164
165     flamedelay = 0;
166
167     onfire = 1;
168 }
169
170 int Person::getIdle()
171 {
172     if (indialogue != -1 && howactive == typeactive && creature == rabbittype)return talkidleanim;
173     if (hasvictim && victim != this/*||(id==0&&attackkeydown)*/)if (/*(id==0&&attackkeydown)||*/(!victim->dead && victim->aitype != passivetype && victim->aitype != searchtype && aitype != passivetype && aitype != searchtype && victim->id < numplayers)) {
174             if ((aitype == playercontrolled && stunned <= 0 && weaponactive == -1) || pause) {
175                 if (creature == rabbittype)return fightidleanim;
176                 if (creature == wolftype)return wolfidle;
177             }
178             if (aitype == playercontrolled && stunned <= 0 && weaponactive != -1) {
179                 if (weapons[weaponids[weaponactive]].getType() == knife)
180                     return knifefightidleanim;
181                 if (weapons[weaponids[weaponactive]].getType() == sword && victim->weaponactive != -1)
182                     return swordfightidlebothanim;
183                 if (weapons[weaponids[weaponactive]].getType() == sword)
184                     return swordfightidleanim;
185                 if (weapons[weaponids[weaponactive]].getType() == staff)
186                     return swordfightidleanim;
187             }
188             if (aitype != playercontrolled && stunned <= 0 && creature != wolftype && !pause)return fightsidestep;
189         }
190     if ((damage > permanentdamage || damage > damagetolerance * .8 || deathbleeding > 0) && creature != wolftype)return hurtidleanim;
191     if (howactive == typesitting)return sitanim;
192     if (howactive == typesittingwall)return sitwallanim;
193     if (howactive == typesleeping)return sleepanim;
194     if (howactive == typedead1)return dead1anim;
195     if (howactive == typedead2)return dead2anim;
196     if (howactive == typedead3)return dead3anim;
197     if (howactive == typedead4)return dead4anim;
198     if (creature == rabbittype)return bounceidleanim;
199     if (creature == wolftype)return wolfidle;
200     return 0;
201 }
202
203 int Person::getCrouch()
204 {
205     if (creature == rabbittype)return crouchanim;
206     if (creature == wolftype)return wolfcrouchanim;
207     return 0;
208 }
209
210 int Person::getRun()
211 {
212     if (creature == rabbittype && (!superruntoggle || weaponactive != -1))return runanim;
213     if (creature == wolftype && (!superruntoggle))return wolfrunanim;
214
215     if (creature == rabbittype && (superruntoggle && weaponactive == -1))return rabbitrunninganim;
216     if (creature == wolftype && (superruntoggle))return wolfrunninganim;
217     return 0;
218 }
219
220 int Person::getStop()
221 {
222     if (creature == rabbittype)return stopanim;
223     if (creature == wolftype)return wolfstopanim;
224     return 0;
225 }
226
227 int Person::getLanding()
228 {
229     if (creature == rabbittype)return landanim;
230     if (creature == wolftype)return wolflandanim;
231     return 0;
232 }
233
234 int Person::getLandhard()
235 {
236     if (creature == rabbittype)return landhardanim;
237     if (creature == wolftype)return wolflandhardanim;
238     return 0;
239 }
240
241 static void
242 SolidHitBonus(int playerid)
243 {
244     if (bonustime < 1.5 && bonus >= solidhit && bonus <= megacombo)
245         award_bonus(playerid, bonus == megacombo ? bonus : bonus + 1);
246     else
247         award_bonus(playerid, solidhit);
248 }
249
250 void Person::DoBlood(float howmuch, int which)
251 {
252     static int bleedxint, bleedyint;
253     static XYZ bloodvel;
254     //if(howmuch&&id==0)blooddimamount=1;
255     if (bloodtoggle && tutoriallevel != 1) {
256         if (bleeding <= 0 && spurt) {
257             spurt = 0;
258             for (int i = 0; i < 3; i++) {
259                 bloodvel = 0;
260                 if (!skeleton.free) {
261                     bloodvel.z = 10;
262                     bloodvel = DoRotation(bloodvel, ((float)(Random() % 100)) / 4, yaw + ((float)(Random() % 100)) / 4, 0) * scale;
263                 }
264                 if (skeleton.free) {
265                     bloodvel -= DoRotation(skeleton.forward * 10 * scale, ((float)(Random() % 100)) / 4, ((float)(Random() % 100)) / 4, 0);
266                 }
267                 if (skeleton.free)bloodvel += DoRotation(skeleton.joints[skeleton.jointlabels[head]].velocity, ((float)(Random() % 100)) / 4, yaw + ((float)(Random() % 100)) / 4, 0) * scale;
268                 if (!skeleton.free)bloodvel += DoRotation(velocity, ((float)(Random() % 100)) / 4, ((float)(Random() % 100)) / 4, 0) * scale;
269                 if (skeleton.free) {
270                     Sprite::MakeSprite(bloodsprite, skeleton.joints[skeleton.jointlabels[head]].position * scale + coords, bloodvel, 1, 1, 1, .05, 1);
271                     Sprite::MakeSprite(bloodflamesprite, skeleton.joints[skeleton.jointlabels[head]].position * scale + coords, bloodvel, 1, 1, 1, .3, 1);
272                 }
273                 if (!skeleton.free) {
274                     Sprite::MakeSprite(bloodsprite, DoRotation((skeleton.joints[skeleton.jointlabels[head]].position + skeleton.joints[skeleton.jointlabels[neck]].position) / 2, 0, yaw, 0)*scale + coords, bloodvel, 1, 1, 1, .05, 1);
275                     Sprite::MakeSprite(bloodflamesprite, DoRotation((skeleton.joints[skeleton.jointlabels[head]].position + skeleton.joints[skeleton.jointlabels[neck]].position) / 2, 0, yaw, 0)*scale + coords, bloodvel, 1, 1, 1, .3, 1);
276                 }
277             }
278             if (Random() % 2 == 0)
279                 for (int i = 0; i < 3; i++) {
280                     if (Random() % 2 != 0) {
281                         bloodvel = 0;
282                         if (skeleton.free) {
283                             bloodvel -= DoRotation(skeleton.forward * 10 * scale, ((float)(Random() % 100)) / 4, ((float)(Random() % 100)) / 4, 0);
284                             bloodvel += DoRotation(skeleton.joints[skeleton.jointlabels[head]].velocity, ((float)(Random() % 100)) / 4, yaw + ((float)(Random() % 100)) / 4, 0) * scale;
285                         } else {
286                             bloodvel.z = 10;
287                             bloodvel = DoRotation(bloodvel, ((float)(Random() % 100)) / 4, yaw + ((float)(Random() % 100)) / 4, 0) * scale;
288                             bloodvel += DoRotation(velocity, ((float)(Random() % 100)) / 4, ((float)(Random() % 100)) / 4, 0) * scale;
289                         }
290                         bloodvel *= .2;
291                         if (skeleton.free) {
292                             Sprite::MakeSprite(splintersprite, skeleton.joints[skeleton.jointlabels[head]].position * scale + coords, bloodvel, 1, 1, 1, .05, 1);
293                         } else {
294                             Sprite::MakeSprite(splintersprite, DoRotation((skeleton.joints[skeleton.jointlabels[head]].position + skeleton.joints[skeleton.jointlabels[neck]].position) / 2, 0, yaw, 0)*scale + coords, bloodvel, 1, 1, 1, .05, 1);
295                         }
296                         Sprite::setLastSpriteSpecial(3);
297                     }
298                 }
299         }
300         if (decals) {
301             bleeding = howmuch + (float)abs(Random() % 100) / 200 - .25;
302             bleedxint = 0;
303             bleedyint = 0;
304             if (creature == rabbittype)
305                 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) {
306                     bleedxint = abs(Random() % 512);
307                     bleedyint = abs(Random() % 512);
308                 }
309             if (creature == wolftype)
310                 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) {
311                     bleedxint = abs(Random() % 512);
312                     bleedyint = abs(Random() % 512);
313                 }
314             bleedy = bleedxint;
315             bleedx = bleedyint;
316             bleedy /= realtexdetail;
317             bleedx /= realtexdetail;
318             direction = abs(Random() % 2) * 2 - 1;
319         }
320
321     }
322     if (bleeding > 2)bleeding = 2;
323 }
324
325 void Person::DoBloodBig(float howmuch, int which)
326 {
327     static int bleedxint, bleedyint, i, j;
328     static XYZ bloodvel;
329     if (howmuch && id == 0)blooddimamount = 1;
330
331     if (tutoriallevel != 1 || id == 0)
332         if (aitype != playercontrolled && howmuch > 0) {
333             int whichsound = -1;
334
335             if (creature == wolftype) {
336                 int i = abs(Random() % 2);
337                 if (i == 0)whichsound = snarlsound;
338                 if (i == 1)whichsound = snarl2sound;
339                 envsound[numenvsounds] = coords;
340                 envsoundvol[numenvsounds] = 16;
341                 envsoundlife[numenvsounds] = .4;
342                 numenvsounds++;
343             }
344             if (creature == rabbittype) {
345                 int i = abs(Random() % 2);
346                 if (i == 0)whichsound = rabbitpainsound;
347                 if (i == 1 && howmuch >= 2)whichsound = rabbitpain1sound;
348                 envsound[numenvsounds] = coords;
349                 envsoundvol[numenvsounds] = 16;
350                 envsoundlife[numenvsounds] = .4;
351                 numenvsounds++;
352                 //if(i==2)whichsound=rabbitpain2sound;
353             }
354
355             if (whichsound != -1)
356                 emit_sound_at(whichsound, coords);
357         }
358
359     if (id == 0 && howmuch > 0) {
360         flashamount = .5;
361         flashr = 1;
362         flashg = 0;
363         flashb = 0;
364         flashdelay = 0;
365     }
366
367     if (bloodtoggle && decals && tutoriallevel != 1) {
368         if (bleeding <= 0 && spurt) {
369             spurt = 0;
370             for (int i = 0; i < 3; i++) {
371                 bloodvel = 0;
372                 if (!skeleton.free) {
373                     bloodvel.z = 10;
374                     bloodvel = DoRotation(bloodvel, ((float)(Random() % 100)) / 4, yaw + ((float)(Random() % 100)) / 4, 0) * scale;
375                 }
376                 if (skeleton.free) {
377                     bloodvel -= DoRotation(skeleton.forward * 10 * scale, ((float)(Random() % 100)) / 4, ((float)(Random() % 100)) / 4, 0);
378                 }
379                 if (skeleton.free)bloodvel += DoRotation(skeleton.joints[skeleton.jointlabels[head]].velocity, ((float)(Random() % 100)) / 4, yaw + ((float)(Random() % 100)) / 4, 0) * scale;
380                 if (!skeleton.free)bloodvel += DoRotation(velocity, ((float)(Random() % 100)) / 4, ((float)(Random() % 100)) / 4, 0) * scale;
381                 if (skeleton.free) {
382                     Sprite::MakeSprite(bloodsprite, skeleton.joints[skeleton.jointlabels[head]].position * scale + coords, bloodvel, 1, 1, 1, .05, 1);
383                     Sprite::MakeSprite(bloodflamesprite, skeleton.joints[skeleton.jointlabels[head]].position * scale + coords, bloodvel, 1, 1, 1, .3, 1);
384                 }
385                 if (!skeleton.free) {
386                     Sprite::MakeSprite(bloodsprite, DoRotation((skeleton.joints[skeleton.jointlabels[head]].position + skeleton.joints[skeleton.jointlabels[neck]].position) / 2, 0, yaw, 0)*scale + coords, bloodvel, 1, 1, 1, .05, 1);
387                     Sprite::MakeSprite(bloodflamesprite, DoRotation((skeleton.joints[skeleton.jointlabels[head]].position + skeleton.joints[skeleton.jointlabels[neck]].position) / 2, 0, yaw, 0)*scale + coords, bloodvel, 1, 1, 1, .3, 1);
388                 }
389             }
390         }
391         int offsetx = 0, offsety = 0;
392         if (which == 225) {
393             offsety = Random() % 40;
394             offsetx = abs(Random() % 60);
395         }
396         if (which == 190 || which == 185) {
397             offsety = Random() % 40;
398             offsetx = abs(Random() % 100) - 20;
399         }
400         if (which == 175) {
401             offsety = Random() % 10;
402             offsetx = Random() % 10;
403         }
404         if (which == 170) {
405             offsety = Random() % 20;
406             offsetx = Random() % 20;
407         }
408         if (which == 220 || which == 215) {
409             offsetx = 20;
410         }
411
412
413         int startx = 512;
414         int starty = 512;
415         int endx = 0;
416         int endy = 0;
417         GLubyte color;
418         if (creature == rabbittype)
419             for (i = 0; i < 512; i++) {
420                 for (j = 0; j < 512; j++) {
421                     if (bloodText[i * 512 * 3 + j * 3 + 0] <= which + 4 && bloodText[i * 512 * 3 + j * 3 + 0] >= which - 4) {
422                         if (i < startx)startx = i;
423                         if (j < starty)starty = j;
424                         if (i > endx)endx = i;
425                         if (j > endy)endy = j;
426                     }
427                 }
428             }
429         if (creature == wolftype)
430             for (i = 0; i < 512; i++) {
431                 for (j = 0; j < 512; j++) {
432                     if (wolfbloodText[i * 512 * 3 + j * 3 + 0] <= which + 4 && wolfbloodText[i * 512 * 3 + j * 3 + 0] >= which - 4) {
433                         if (i < startx)startx = i;
434                         if (j < starty)starty = j;
435                         if (i > endx)endx = i;
436                         if (j > endy)endy = j;
437                     }
438                 }
439             }
440
441         startx += offsetx;
442         endx += offsetx;
443         starty += offsety;
444         endy += offsety;
445
446         if (startx < 0)startx = 0;
447         if (starty < 0)starty = 0;
448         if (endx > 512 - 1)endx = 512 - 1;
449         if (endy > 512 - 1)endy = 512 - 1;
450         if (endx < startx)endx = startx;
451         if (endy < starty)endy = starty;
452
453         startx /= realtexdetail;
454         starty /= realtexdetail;
455         endx /= realtexdetail;
456         endy /= realtexdetail;
457
458         int texdetailint = realtexdetail;
459         int where;
460         if (creature == rabbittype)
461             for (i = startx; i < endx; i++) {
462                 for (j = starty; j < endy; j++) {
463                     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) {
464                         color = Random() % 85 + 170;
465                         where = i * skeleton.skinsize * 3 + j * 3;
466                         if (skeleton.skinText[where + 0] > color / 2)skeleton.skinText[where + 0] = color / 2;
467                         skeleton.skinText[where + 1] = 0;
468                         skeleton.skinText[where + 2] = 0;
469                     }
470                 }
471             }
472         if (creature == wolftype)
473             for (i = startx; i < endx; i++) {
474                 for (j = starty; j < endy; j++) {
475                     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) {
476                         color = Random() % 85 + 170;
477                         where = i * skeleton.skinsize * 3 + j * 3;
478                         if (skeleton.skinText[where + 0] > color / 2)skeleton.skinText[where + 0] = color / 2;
479                         skeleton.skinText[where + 1] = 0;
480                         skeleton.skinText[where + 2] = 0;
481                     }
482                 }
483             }
484         skeleton.drawmodel.textureptr.bind();
485         DoMipmaps();
486
487         bleedxint = 0;
488         bleedyint = 0;
489         if (creature == rabbittype)
490             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) {
491                 bleedxint = abs(Random() % 512);
492                 bleedyint = abs(Random() % 512);
493             }
494         if (creature == wolftype)
495             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) {
496                 bleedxint = abs(Random() % 512);
497                 bleedyint = abs(Random() % 512);
498             }
499         bleedy = bleedxint + offsetx;
500         bleedx = bleedyint + offsety;
501         bleedy /= realtexdetail;
502         bleedx /= realtexdetail;
503         if (bleedx < 0)bleedx = 0;
504         if (bleedy < 0)bleedy = 0;
505         if (bleedx > skeleton.skinsize - 1)bleedx = skeleton.skinsize - 1;
506         if (bleedy > skeleton.skinsize - 1)bleedy = skeleton.skinsize - 1;
507         direction = abs(Random() % 2) * 2 - 1;
508
509     }
510     bleeding = howmuch + (float)abs(Random() % 100) / 200 - .25;
511     deathbleeding += bleeding;
512     bloodloss += bleeding * 3;
513
514     if (tutoriallevel != 1 && aitype != playercontrolled && bloodloss > damagetolerance * 2 / 3 && bloodloss < damagetolerance && creature == rabbittype) {
515         if (abs(Random() % 2) == 0) {
516             aitype = gethelptype;
517             lastseentime = 12;
518         } else aitype = attacktypecutoff;
519         ally = 0;
520     }
521     if (bleeding > 2)bleeding = 2;
522 }
523
524 bool Person::DoBloodBigWhere(float howmuch, int which, XYZ where)
525 {
526     static int i, j;
527     static XYZ bloodvel;
528     static XYZ startpoint, endpoint, colpoint, movepoint;
529     static float rotationpoint;
530     static int whichtri;
531     static XYZ p1, p2, p3, p0;
532     static XYZ N, temp;
533     XYZ bary;
534     XYZ gxx, gyy;
535     float coordsx, coordsy;
536     float total;
537
538     if (bloodtoggle && decals && tutoriallevel != 1) {
539         where -= coords;
540         if (!skeleton.free)where = DoRotation(where, 0, -yaw, 0);
541         //where=scale;
542         startpoint = where;
543         startpoint.y += 100;
544         endpoint = where;
545         endpoint.y -= 100;
546         movepoint = 0;
547         rotationpoint = 0;
548         whichtri = skeleton.drawmodel.LineCheck(&startpoint, &endpoint, &colpoint, &movepoint, &rotationpoint);
549         if (whichtri != -1) {
550             p0 = colpoint;
551             p1 = skeleton.drawmodel.vertex[skeleton.drawmodel.Triangles[whichtri].vertex[0]];
552             p2 = skeleton.drawmodel.vertex[skeleton.drawmodel.Triangles[whichtri].vertex[1]];
553             p3 = skeleton.drawmodel.vertex[skeleton.drawmodel.Triangles[whichtri].vertex[2]];
554             /*
555             CrossProduct(p2-p1,p3-p1,&N);
556             CrossProduct(p0-p1,p3-p1,&temp);
557             s =  dotproduct(&temp,&N)/findLength(&N);
558             CrossProduct(p2-p1,p1-p0,&temp);
559             t = dotproduct(&temp,&N)/findLength(&N);
560             r = 1 - (s + t);*/
561
562             bary.x = distsq(&p0, &p1);
563             bary.y = distsq(&p0, &p2);
564             bary.z = distsq(&p0, &p3);
565
566             total = bary.x + bary.y + bary.z;
567             bary.x /= total;
568             bary.y /= total;
569             bary.z /= total;
570
571             bary.x = 1 - bary.x;
572             bary.y = 1 - bary.y;
573             bary.z = 1 - bary.z;
574
575             total = bary.x + bary.y + bary.z;
576             bary.x /= total;
577             bary.y /= total;
578             bary.z /= total;
579
580
581             gxx.x = skeleton.drawmodel.Triangles[whichtri].gx[0];
582             gxx.y = skeleton.drawmodel.Triangles[whichtri].gx[1];
583             gxx.z = skeleton.drawmodel.Triangles[whichtri].gx[2];
584             gyy.x = skeleton.drawmodel.Triangles[whichtri].gy[0];
585             gyy.y = skeleton.drawmodel.Triangles[whichtri].gy[1];
586             gyy.z = skeleton.drawmodel.Triangles[whichtri].gy[2];
587             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;
588             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;
589
590             //coordsx=skeleton.drawmodel.Triangles[whichtri].gx[1];
591             //coordsy=skeleton.drawmodel.Triangles[whichtri].gy[1];
592
593             if (bleeding <= 0 && spurt) {
594                 spurt = 0;
595                 for (int i = 0; i < 3; i++) {
596                     bloodvel = 0;
597                     if (!skeleton.free) {
598                         bloodvel.z = 10;
599                         bloodvel = DoRotation(bloodvel, ((float)(Random() % 100)) / 4, yaw + ((float)(Random() % 100)) / 4, 0) * scale;
600                     }
601                     if (skeleton.free) {
602                         bloodvel -= DoRotation(skeleton.forward * 10 * scale, ((float)(Random() % 100)) / 4, ((float)(Random() % 100)) / 4, 0);
603                     }
604                     if (skeleton.free)bloodvel += DoRotation(skeleton.joints[skeleton.jointlabels[head]].velocity, ((float)(Random() % 100)) / 4, yaw + ((float)(Random() % 100)) / 4, 0) * scale;
605                     if (!skeleton.free)bloodvel += DoRotation(velocity, ((float)(Random() % 100)) / 4, ((float)(Random() % 100)) / 4, 0) * scale;
606                     if (skeleton.free) {
607                         Sprite::MakeSprite(bloodsprite, skeleton.joints[skeleton.jointlabels[head]].position * scale + coords, bloodvel, 1, 1, 1, .05, 1);
608                         Sprite::MakeSprite(bloodflamesprite, skeleton.joints[skeleton.jointlabels[head]].position * scale + coords, bloodvel, 1, 1, 1, .3, 1);
609                     }
610                     if (!skeleton.free) {
611                         Sprite::MakeSprite(bloodsprite, DoRotation((skeleton.joints[skeleton.jointlabels[head]].position + skeleton.joints[skeleton.jointlabels[neck]].position) / 2, 0, yaw, 0)*scale + coords, bloodvel, 1, 1, 1, .05, 1);
612                         Sprite::MakeSprite(bloodflamesprite, DoRotation((skeleton.joints[skeleton.jointlabels[head]].position + skeleton.joints[skeleton.jointlabels[neck]].position) / 2, 0, yaw, 0)*scale + coords, bloodvel, 1, 1, 1, .3, 1);
613                     }
614                 }
615             }
616             int offsetx = 0, offsety = 0;
617             /*if(which==225){
618             offsety=Random()%40;
619             offsetx=abs(Random()%120);
620             }
621             if(which==220||which==215){
622             offsety=Random()%20;
623             offsetx=abs(Random()%80);
624             }*/
625             //which=220;
626             offsetx = (1 + coordsy) * 512 - 291;
627             offsety = coordsx * 512 - 437;
628
629             int startx = 512;
630             int starty = 512;
631             int endx = 0;
632             int endy = 0;
633             GLubyte color;
634             if (creature == rabbittype)
635                 for (i = 0; i < 512; i++) {
636                     for (j = 0; j < 512; j++) {
637                         if (bloodText[i * 512 * 3 + j * 3 + 0] <= which + 4 && bloodText[i * 512 * 3 + j * 3 + 0] >= which - 4) {
638                             if (i < startx)startx = i;
639                             if (j < starty)starty = j;
640                             if (i > endx)endx = i;
641                             if (j > endy)endy = j;
642                         }
643                     }
644                 }
645             if (creature == wolftype)
646                 for (i = 0; i < 512; i++) {
647                     for (j = 0; j < 512; j++) {
648                         if (wolfbloodText[i * 512 * 3 + j * 3 + 0] <= which + 4 && wolfbloodText[i * 512 * 3 + j * 3 + 0] >= which - 4) {
649                             if (i < startx)startx = i;
650                             if (j < starty)starty = j;
651                             if (i > endx)endx = i;
652                             if (j > endy)endy = j;
653                         }
654                     }
655                 }
656             startx += offsetx;
657             endx += offsetx;
658             starty += offsety;
659             endy += offsety;
660
661             if (startx < 0)startx = 0;
662             if (starty < 0)starty = 0;
663             if (endx > 512 - 1)endx = 512 - 1;
664             if (endy > 512 - 1)endy = 512 - 1;
665             if (endx < startx)endx = startx;
666             if (endy < starty)endy = starty;
667
668             startx /= realtexdetail;
669             starty /= realtexdetail;
670             endx /= realtexdetail;
671             endy /= realtexdetail;
672
673             int texdetailint = realtexdetail;
674             int where;
675             if (creature == rabbittype)
676                 for (i = startx; i < endx; i++) {
677                     for (j = starty; j < endy; j++) {
678                         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) {
679                             color = Random() % 85 + 170;
680                             where = i * skeleton.skinsize * 3 + j * 3;
681                             if (skeleton.skinText[where + 0] > color / 2)skeleton.skinText[where + 0] = color / 2;
682                             skeleton.skinText[where + 1] = 0;
683                             skeleton.skinText[where + 2] = 0;
684                         } 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) {
685                             color = Random() % 85 + 170;
686                             where = i * skeleton.skinsize * 3 + j * 3;
687                             if (skeleton.skinText[where + 0] > color / 2)skeleton.skinText[where + 0] = color / 2;
688                             skeleton.skinText[where + 1] = 0;
689                             skeleton.skinText[where + 2] = 0;
690                         }
691                     }
692                 }
693             if (creature == wolftype)
694                 for (i = startx; i < endx; i++) {
695                     for (j = starty; j < endy; j++) {
696                         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) {
697                             color = Random() % 85 + 170;
698                             where = i * skeleton.skinsize * 3 + j * 3;
699                             if (skeleton.skinText[where + 0] > color / 2)skeleton.skinText[where + 0] = color / 2;
700                             skeleton.skinText[where + 1] = 0;
701                             skeleton.skinText[where + 2] = 0;
702                         } 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) {
703                             color = Random() % 85 + 170;
704                             where = i * skeleton.skinsize * 3 + j * 3;
705                             if (skeleton.skinText[where + 0] > color / 2)skeleton.skinText[where + 0] = color / 2;
706                             skeleton.skinText[where + 1] = 0;
707                             skeleton.skinText[where + 2] = 0;
708                         }
709                     }
710                 }
711             skeleton.drawmodel.textureptr.bind();
712             DoMipmaps();
713
714             bleedy = (1 + coordsy) * 512;
715             bleedx = coordsx * 512;
716             bleedy /= realtexdetail;
717             bleedx /= realtexdetail;
718             if (bleedx < 0)bleedx = 0;
719             if (bleedy < 0)bleedy = 0;
720             if (bleedx > skeleton.skinsize - 1)bleedx = skeleton.skinsize - 1;
721             if (bleedy > skeleton.skinsize - 1)bleedy = skeleton.skinsize - 1;
722             direction = abs(Random() % 2) * 2 - 1;
723         }
724         if (whichtri == -1)return 0;
725     }
726     bleeding = howmuch + (float)abs(Random() % 100) / 200 - .25;
727     deathbleeding += bleeding;
728     bloodloss += bleeding * 3;
729
730     if (tutoriallevel != 1 && aitype != playercontrolled && bloodloss > damagetolerance * 2 / 3 && bloodloss < damagetolerance && creature == rabbittype) {
731         if (abs(Random() % 2) == 0) {
732             aitype = gethelptype;
733             lastseentime = 12;
734         } else aitype = attacktypecutoff;
735         ally = 0;
736     }
737     if (bleeding > 2)bleeding = 2;
738     return 1;
739 }
740
741
742
743 void Person::Reverse()
744 {
745     if (!((victim->aitype == playercontrolled
746             || hostiletime > 1
747             || staggerdelay <= 0)
748             && victim->animTarget != jumpupanim
749             && victim->animTarget != jumpdownanim
750             && (tutoriallevel != 1 || cananger)
751             && hostile))
752         return;
753
754     if (normaldotproduct (victim->facing, victim->coords - coords) > 0
755             && (victim->id != 0 || difficulty >= 2)
756             && (creature != wolftype || victim->creature == wolftype))
757         return;
758
759     if (animTarget == sweepanim) {
760         animTarget = sweepreversedanim;
761         animCurrent = sweepreversedanim;
762         victim->animCurrent = sweepreversalanim;
763         victim->animTarget = sweepreversalanim;
764     }
765     if (animTarget == spinkickanim) {
766         animTarget = spinkickreversedanim;
767         animCurrent = spinkickreversedanim;
768         victim->animCurrent = spinkickreversalanim;
769         victim->animTarget = spinkickreversalanim;
770     }
771     if (animTarget == upunchanim || animTarget == rabbittacklinganim) {
772         if (animTarget == rabbittacklinganim) {
773             frameCurrent = 6;
774             frameTarget = 7;
775             victim->frameCurrent = 6;
776             victim->frameTarget = 7;
777         }
778         animTarget = upunchreversedanim;
779         animCurrent = upunchreversedanim;
780         victim->animCurrent = upunchreversalanim;
781         victim->animTarget = upunchreversalanim;
782     }
783     if (animTarget == staffhitanim && distsq(&victim->coords, &coords) < 2 && ((victim->id == 0 && victim->crouchkeydown) || Random() % 4 == 0)) {
784         if (victim->weaponactive != -1) {
785             victim->throwtogglekeydown = 1;
786             weapons[victim->weaponids[0]].owner = -1;
787             weapons[victim->weaponids[0]].velocity = victim->velocity * .2;
788             if (weapons[victim->weaponids[0]].velocity.x == 0)weapons[victim->weaponids[0]].velocity.x = .1;
789             weapons[victim->weaponids[0]].tipvelocity = weapons[victim->weaponids[0]].velocity;
790             weapons[victim->weaponids[0]].missed = 1;
791             weapons[victim->weaponids[0]].freetime = 0;
792             weapons[victim->weaponids[0]].firstfree = 1;
793             weapons[victim->weaponids[0]].physics = 1;
794             victim->num_weapons--;
795             if (victim->num_weapons) {
796                 victim->weaponids[0] = victim->weaponids[victim->num_weapons];
797                 if (victim->weaponstuck == victim->num_weapons)victim->weaponstuck = 0;
798             }
799
800             victim->weaponactive = -1;
801             for (int j = 0; j < numplayers; j++) {
802                 player[j].wentforweapon = 0;
803             }
804         }
805
806         animTarget = staffhitreversedanim;
807         animCurrent = staffhitreversedanim;
808         victim->animCurrent = staffhitreversalanim;
809         victim->animTarget = staffhitreversalanim;
810     }
811     if (animTarget == staffspinhitanim && distsq(&victim->coords, &coords) < 2 && ((victim->id == 0 && victim->crouchkeydown) || Random() % 2 == 0)) {
812         if (victim->weaponactive != -1) {
813             victim->throwtogglekeydown = 1;
814             weapons[victim->weaponids[0]].owner = -1;
815             weapons[victim->weaponids[0]].velocity = victim->velocity * .2;
816             if (weapons[victim->weaponids[0]].velocity.x == 0)weapons[victim->weaponids[0]].velocity.x = .1;
817             weapons[victim->weaponids[0]].tipvelocity = weapons[victim->weaponids[0]].velocity;
818             weapons[victim->weaponids[0]].missed = 1;
819             weapons[victim->weaponids[0]].freetime = 0;
820             weapons[victim->weaponids[0]].firstfree = 1;
821             weapons[victim->weaponids[0]].physics = 1;
822             victim->num_weapons--;
823             if (victim->num_weapons) {
824                 victim->weaponids[0] = victim->weaponids[victim->num_weapons];
825                 if (victim->weaponstuck == victim->num_weapons)victim->weaponstuck = 0;
826             }
827
828             victim->weaponactive = -1;
829             for (int j = 0; j < numplayers; j++) {
830                 player[j].wentforweapon = 0;
831             }
832         }
833         animTarget = staffspinhitreversedanim;
834         animCurrent = staffspinhitreversedanim;
835         victim->animCurrent = staffspinhitreversalanim;
836         victim->animTarget = staffspinhitreversalanim;
837     }
838     if (animTarget == swordslashanim && distsq(&victim->coords, &coords) < 2 && ((victim->id == 0 && victim->crouchkeydown) || Random() % 4 == 0)) {
839         if (victim->weaponactive != -1) {
840             victim->throwtogglekeydown = 1;
841             weapons[victim->weaponids[0]].owner = -1;
842             weapons[victim->weaponids[0]].velocity = victim->velocity * .2;
843             if (weapons[victim->weaponids[0]].velocity.x == 0)weapons[victim->weaponids[0]].velocity.x = .1;
844             weapons[victim->weaponids[0]].tipvelocity = weapons[victim->weaponids[0]].velocity;
845             weapons[victim->weaponids[0]].missed = 1;
846             weapons[victim->weaponids[0]].freetime = 0;
847             weapons[victim->weaponids[0]].firstfree = 1;
848             weapons[victim->weaponids[0]].physics = 1;
849             victim->num_weapons--;
850             if (victim->num_weapons) {
851                 victim->weaponids[0] = victim->weaponids[victim->num_weapons];
852                 if (victim->weaponstuck == victim->num_weapons)victim->weaponstuck = 0;
853             }
854
855             victim->weaponactive = -1;
856             for (int j = 0; j < numplayers; j++) {
857                 player[j].wentforweapon = 0;
858             }
859         }
860         animTarget = swordslashreversedanim;
861         animCurrent = swordslashreversedanim;
862         victim->animCurrent = swordslashreversalanim;
863         victim->animTarget = swordslashreversalanim;
864     }
865     if (animTarget == knifeslashstartanim && distsq(&victim->coords, &coords) < 2 && (victim->id == 0 || Random() % 4 == 0)) {
866         if (victim->weaponactive != -1) {
867             victim->throwtogglekeydown = 1;
868             weapons[victim->weaponids[0]].owner = -1;
869             weapons[victim->weaponids[0]].velocity = victim->velocity * .2;
870             if (weapons[victim->weaponids[0]].velocity.x == 0)weapons[victim->weaponids[0]].velocity.x = .1;
871             weapons[victim->weaponids[0]].tipvelocity = weapons[victim->weaponids[0]].velocity;
872             weapons[victim->weaponids[0]].missed = 1;
873             weapons[victim->weaponids[0]].freetime = 0;
874             weapons[victim->weaponids[0]].firstfree = 1;
875             weapons[victim->weaponids[0]].physics = 1;
876             victim->num_weapons--;
877             if (victim->num_weapons) {
878                 victim->weaponids[0] = victim->weaponids[victim->num_weapons];
879                 if (victim->weaponstuck == victim->num_weapons)victim->weaponstuck = 0;
880             }
881
882             victim->weaponactive = -1;
883             for (int j = 0; j < numplayers; j++) {
884                 player[j].wentforweapon = 0;
885             }
886         }
887         animTarget = knifeslashreversedanim;
888         animCurrent = knifeslashreversedanim;
889         victim->animCurrent = knifeslashreversalanim;
890         victim->animTarget = knifeslashreversalanim;
891     }
892     if (animTarget != knifeslashstartanim && animTarget != staffhitanim && animTarget != staffspinhitanim && animTarget != winduppunchanim && animTarget != wolfslapanim && animTarget != swordslashanim && animTarget != swordslashanim) {
893         victim->targettilt2 = targettilt2;
894         victim->frameCurrent = frameCurrent;
895         victim->frameTarget = frameTarget;
896         victim->target = target;
897         victim->velocity = 0;
898         victim->oldcoords = victim->coords;
899         victim->coords = coords;
900         victim->targetyaw = targetyaw;
901         victim->yaw = targetyaw;
902         victim->victim = this;
903     }
904     if (animTarget == winduppunchanim) {
905         animTarget = winduppunchblockedanim;
906         victim->animTarget = blockhighleftanim;
907         victim->frameTarget = 1;
908         victim->target = .5;
909         victim->victim = this;
910         victim->targetyaw = targetyaw + 180;
911     }
912     if (animTarget == wolfslapanim) {
913         animTarget = winduppunchblockedanim;
914         victim->animTarget = blockhighleftanim;
915         victim->frameTarget = 1;
916         victim->target = .5;
917         victim->victim = this;
918         victim->targetyaw = targetyaw + 180;
919     }
920     if ((animTarget == swordslashanim || animTarget == staffhitanim || animTarget == staffspinhitanim) && victim->weaponactive != -1) {
921         animTarget = swordslashparriedanim;
922         parriedrecently = .4;
923         victim->parriedrecently = 0;
924         victim->animTarget = swordslashparryanim;
925         victim->frameTarget = 1;
926         victim->target = .5;
927         victim->victim = this;
928         victim->targetyaw = targetyaw + 180;
929
930         if (abs(Random() % 20) == 0 || weapons[victim->weaponids[victim->weaponactive]].getType() == knife) {
931             if (victim->weaponactive != -1) {
932                 if (weapons[victim->weaponids[0]].getType() == staff || weapons[weaponids[0]].getType() == staff) {
933                     if (weapons[victim->weaponids[0]].getType() == staff)
934                         weapons[victim->weaponids[0]].damage += .2 + float(abs(Random() % 100) - 50) / 250;
935                     if (weapons[weaponids[0]].getType() == staff)
936                         weapons[weaponids[0]].damage += .2 + float(abs(Random() % 100) - 50) / 250;
937                     emit_sound_at(swordstaffsound, victim->coords);
938                 } else {
939                     emit_sound_at(metalhitsound, victim->coords);
940                 }
941             }
942             XYZ aim;
943             victim->Puff(righthand);
944             victim->target = 0;
945             victim->frameTarget = 0;
946             victim->animTarget = staggerbackhighanim;
947             victim->targetyaw = targetyaw + 180;
948             victim->target = 0;
949             weapons[victim->weaponids[0]].owner = -1;
950             aim = DoRotation(facing, 0, 90, 0) * 21;
951             aim.y += 7;
952             weapons[victim->weaponids[0]].velocity = aim * -.2;
953             weapons[victim->weaponids[0]].tipvelocity = aim;
954             weapons[victim->weaponids[0]].missed = 1;
955             weapons[victim->weaponids[0]].hitsomething = 0;
956             weapons[victim->weaponids[0]].freetime = 0;
957             weapons[victim->weaponids[0]].firstfree = 1;
958             weapons[victim->weaponids[0]].physics = 1;
959             victim->num_weapons--;
960             if (victim->num_weapons) {
961                 victim->weaponids[0] = victim->weaponids[num_weapons];
962                 if (victim->weaponstuck == victim->num_weapons)victim->weaponstuck = 0;
963             }
964             victim->weaponactive = -1;
965             for (int i = 0; i < numplayers; i++) {
966                 player[i].wentforweapon = 0;
967             }
968         }
969
970         if (abs(Random() % 20) == 0) {
971             if (weaponactive != -1) {
972                 if (weapons[victim->weaponids[0]].getType() == staff || weapons[weaponids[0]].getType() == staff) {
973                     if (weapons[victim->weaponids[0]].getType() == staff)weapons[victim->weaponids[0]].damage += .2 + float(abs(Random() % 100) - 50) / 250;
974                     if (weapons[weaponids[0]].getType() == staff)weapons[weaponids[0]].damage += .2 + float(abs(Random() % 100) - 50) / 250;
975
976                     emit_sound_at(swordstaffsound, coords);
977                 } else {
978                     emit_sound_at(metalhitsound, coords);
979                 }
980             }
981
982             XYZ aim;
983             Puff(righthand);
984             target = 0;
985             frameTarget = 0;
986             animTarget = staggerbackhighanim;
987             targetyaw = targetyaw + 180;
988             target = 0;
989             weapons[weaponids[0]].owner = -1;
990             aim = DoRotation(facing, 0, 90, 0) * 21;
991             aim.y += 7;
992             weapons[weaponids[0]].velocity = aim * -.2;
993             weapons[weaponids[0]].tipvelocity = aim;
994             weapons[weaponids[0]].hitsomething = 0;
995             weapons[weaponids[0]].missed = 1;
996             weapons[weaponids[0]].freetime = 0;
997             weapons[weaponids[0]].firstfree = 1;
998             weapons[weaponids[0]].physics = 1;
999             num_weapons--;
1000             if (num_weapons) {
1001                 weaponids[0] = weaponids[num_weapons];
1002                 if (weaponstuck == num_weapons)weaponstuck = 0;
1003             }
1004             weaponactive = -1;
1005             for (int i = 0; i < numplayers; i++) {
1006                 player[i].wentforweapon = 0;
1007             }
1008
1009
1010         }
1011     }
1012     if (hasvictim)
1013         if (animTarget == knifeslashstartanim || animTarget == swordslashanim || animTarget == staffhitanim || animTarget == staffspinhitanim) {
1014             if ((animTarget != staffhitanim && animTarget != staffspinhitanim) || distsq(&coords, &victim->coords) > .2) {
1015                 victim->animTarget = dodgebackanim;
1016                 victim->frameTarget = 0;
1017                 victim->target = 0;
1018
1019                 XYZ rotatetarget;
1020                 rotatetarget = coords - victim->coords;
1021                 Normalise(&rotatetarget);
1022                 victim->targetyaw = -asin(0 - rotatetarget.x);
1023                 victim->targetyaw *= 360 / 6.28;
1024                 if (rotatetarget.z < 0)victim->targetyaw = 180 - victim->targetyaw;
1025
1026                 victim->targettilt2 = -asin(rotatetarget.y) * 360 / 6.28; //*-70;
1027
1028                 victim->lastattack3 = victim->lastattack2;
1029                 victim->lastattack2 = victim->lastattack;
1030                 victim->lastattack = victim->animTarget;
1031             } else {
1032                 victim->animTarget = sweepanim;
1033                 victim->frameTarget = 0;
1034                 victim->target = 0;
1035
1036                 XYZ rotatetarget;
1037                 rotatetarget = coords - victim->coords;
1038                 Normalise(&rotatetarget);
1039                 victim->targetyaw = -asin(0 - rotatetarget.x);
1040                 victim->targetyaw *= 360 / 6.28;
1041                 if (rotatetarget.z < 0)victim->targetyaw = 180 - victim->targetyaw;
1042
1043                 victim->targettilt2 = -asin(rotatetarget.y) * 360 / 6.28; //*-70;
1044
1045                 victim->lastattack3 = victim->lastattack2;
1046                 victim->lastattack2 = victim->lastattack;
1047                 victim->lastattack = victim->animTarget;
1048             }
1049         }
1050
1051     velocity = 0;
1052     victim->velocity = 0;
1053
1054     if (aitype != playercontrolled)feint = 0;
1055     if (aitype != playercontrolled && Random() % 3 == 0 && escapednum < 2 && difficulty == 2)feint = 1;
1056     if (aitype != playercontrolled && Random() % 5 == 0 && escapednum < 2 && difficulty == 1)feint = 1;
1057     if (aitype != playercontrolled && Random() % 10 == 0 && escapednum < 2 && difficulty == 0)feint = 1;
1058
1059     if (victim->id == 0 && animation[victim->animTarget].attack == reversal)numreversals++;
1060 }
1061
1062 void Person::DoDamage(float howmuch)
1063 {
1064     if (tutoriallevel != 1)damage += howmuch / power;
1065     if (id != 0)damagedealt += howmuch / power;
1066     if (id == 0)damagetaken += howmuch / power;
1067
1068     if (id == 0 && (bonus == solidhit || bonus == twoxcombo || bonus == threexcombo || bonus == fourxcombo || bonus == megacombo))bonus = 0;
1069     if (tutoriallevel != 1)permanentdamage += howmuch / 2 / power;
1070     if (tutoriallevel != 1)superpermanentdamage += howmuch / 4 / power;
1071     if (permanentdamage > damagetolerance / 2 && permanentdamage - howmuch < damagetolerance / 2 && Random() % 2)DoBlood(1, 255);
1072     if ((permanentdamage > damagetolerance * .8 && Random() % 2 && !deathbleeding) || spurt)DoBlood(1, 255);
1073     spurt = 0;
1074     if (id == 0)camerashake += howmuch / 100;
1075     if (id == 0 && ((howmuch > 50 && damage > damagetolerance / 2)))blackout = damage / damagetolerance;
1076     if (blackout > 1)blackout = 1;
1077
1078     if (aitype == passivetype && damage < damagetolerance && ((tutoriallevel != 1 || cananger) && hostile))aitype = attacktypecutoff;
1079     if (tutoriallevel != 1 && aitype != playercontrolled && damage < damagetolerance && damage > damagetolerance * 2 / 3 && creature == rabbittype) {
1080         if (abs(Random() % 2) == 0) {
1081             aitype = gethelptype;
1082             lastseentime = 12;
1083         } else aitype = attacktypecutoff;
1084         ally = 0;
1085     }
1086
1087     if (howmuch > damagetolerance * 50 && skeleton.free != 2) {
1088         XYZ flatvelocity2;
1089         XYZ flatfacing2;
1090         for (int i = 0; i < skeleton.num_joints; i++) {
1091             if (!skeleton.free)flatvelocity2 = velocity;
1092             if (skeleton.free)flatvelocity2 = skeleton.joints[i].velocity;
1093             if (!skeleton.free)flatfacing2 = DoRotation(DoRotation(DoRotation(skeleton.joints[i].position, 0, 0, tilt), tilt2, 0, 0), 0, yaw, 0) * scale + coords;
1094             if (skeleton.free)flatfacing2 = skeleton.joints[i].position * scale + coords;
1095             flatvelocity2.x += (float)(abs(Random() % 100) - 50) / 10;
1096             flatvelocity2.y += (float)(abs(Random() % 100) - 50) / 10;
1097             flatvelocity2.z += (float)(abs(Random() % 100) - 50) / 10;
1098             Sprite::MakeSprite(bloodflamesprite, flatfacing2, flatvelocity2, 1, 1, 1, 3, 1);
1099             Sprite::MakeSprite(bloodsprite, flatfacing2, flatvelocity2, 1, 1, 1, .4, 1);
1100             Sprite::MakeSprite(cloudsprite, flatfacing2, flatvelocity2 * 0, .6, 0, 0, 1, .5);
1101         }
1102
1103         emit_sound_at(splattersound, coords);
1104
1105         skeleton.free = 2;
1106         DoDamage(10000);
1107         RagDoll(0);
1108         /*if(autoslomo){
1109         slomo=1;
1110         slomodelay=.2;
1111         }*/
1112         if (!dead && creature == wolftype) {
1113             award_bonus(0, Wolfbonus);
1114         }
1115         dead = 2;
1116         coords = 20;
1117     }
1118
1119     if (tutoriallevel != 1 || id == 0)
1120         if (speechdelay <= 0 && !dead && aitype != playercontrolled) {
1121             int whichsound = -1;
1122
1123             if (creature == wolftype) {
1124                 int i = abs(Random() % 2);
1125                 if (i == 0)whichsound = snarlsound;
1126                 if (i == 1)whichsound = snarl2sound;
1127                 envsound[numenvsounds] = coords;
1128                 envsoundvol[numenvsounds] = 16;
1129                 envsoundlife[numenvsounds] = .4;
1130                 numenvsounds++;
1131             }
1132             if (creature == rabbittype) {
1133                 int i = abs(Random() % 2);
1134                 if (i == 0)whichsound = rabbitpainsound;
1135                 if (i == 1 && damage > damagetolerance)whichsound = rabbitpain1sound;
1136                 envsound[numenvsounds] = coords;
1137                 envsoundvol[numenvsounds] = 16;
1138                 envsoundlife[numenvsounds] = .4;
1139                 numenvsounds++;
1140                 //if(i==2)whichsound=rabbitpain2sound;
1141             }
1142
1143             if (whichsound != -1) {
1144                 emit_sound_at(whichsound, coords);
1145             }
1146         }
1147     speechdelay = .3;
1148
1149     //if(permanentdamage>=damagetolerance&&howmuch<50)permanentdamage=damagetolerance-1;
1150     //if(damage>=damagetolerance&&howmuch<30&&!dead)damage=damagetolerance-1;
1151 }
1152
1153 void Person::DoHead()
1154 {
1155     static XYZ rotatearound;
1156     static XYZ facing;
1157     static float lookspeed = 500;
1158
1159     if (!freeze && !winfreeze) {
1160
1161         //head facing
1162         targetheadyaw = (float)((int)((0 - yaw - targetheadyaw + 180) * 100) % 36000) / 100;
1163         targetheadpitch = (float)((int)(targetheadpitch * 100) % 36000) / 100;
1164
1165         while (targetheadyaw > 180)targetheadyaw -= 360;
1166         while (targetheadyaw < -180)targetheadyaw += 360;
1167
1168         if (targetheadyaw > 160)targetheadpitch = targetheadpitch * -1;
1169         if (targetheadyaw < -160)targetheadpitch = targetheadpitch * -1;
1170         if (targetheadyaw > 160)targetheadyaw = targetheadyaw - 180;
1171         if (targetheadyaw < -160)targetheadyaw = targetheadyaw + 180;
1172
1173         if (targetheadpitch > 120)targetheadpitch = 120;
1174         if (targetheadpitch < -120)targetheadpitch = -120;
1175         if (targetheadyaw > 120)targetheadyaw = 120;
1176         if (targetheadyaw < -120)targetheadyaw = -120;
1177
1178         if (!isIdle())targetheadpitch = 0;
1179         if (isIdle()) {
1180             if (targetheadyaw > 80)targetheadyaw = 80;
1181             if (targetheadyaw < -80)targetheadyaw = -80;
1182             if (targetheadpitch > 50)targetheadpitch = 50;
1183             if (targetheadpitch < -50)targetheadpitch = -50;
1184         }
1185
1186         if (abs(headyaw - targetheadyaw) < multiplier * lookspeed)headyaw = targetheadyaw;
1187         else if (headyaw > targetheadyaw) {
1188             headyaw -= multiplier * lookspeed;
1189         } else if (headyaw < targetheadyaw) {
1190             headyaw += multiplier * lookspeed;
1191         }
1192
1193         if (abs(headpitch - targetheadpitch) < multiplier * lookspeed / 2)headpitch = targetheadpitch;
1194         else if (headpitch > targetheadpitch) {
1195             headpitch -= multiplier * lookspeed / 2;
1196         } else if (headpitch < targetheadpitch) {
1197             headpitch += multiplier * lookspeed / 2;
1198         }
1199
1200         rotatearound = skeleton.joints[skeleton.jointlabels[neck]].position;
1201         skeleton.joints[skeleton.jointlabels[head]].position = rotatearound + DoRotation(skeleton.joints[skeleton.jointlabels[head]].position - rotatearound, headpitch, 0, 0);
1202
1203         facing = 0;
1204         facing.z = -1;
1205         if (animTarget != bounceidleanim && animTarget != fightidleanim && animTarget != wolfidle && animTarget != knifefightidleanim && animTarget != drawrightanim && animTarget != drawleftanim && animTarget != walkanim) {
1206             facing = DoRotation(facing, headpitch * .4, 0, 0);
1207             facing = DoRotation(facing, 0, headyaw * .4, 0);
1208         }
1209
1210         if (animTarget == bounceidleanim || animTarget == fightidleanim || animTarget == wolfidle || animTarget == knifefightidleanim || animTarget == drawrightanim || animTarget == drawleftanim) {
1211             facing = DoRotation(facing, headpitch * .8, 0, 0);
1212             facing = DoRotation(facing, 0, headyaw * .8, 0);
1213         }
1214
1215         if (animTarget == walkanim) {
1216             facing = DoRotation(facing, headpitch * .6, 0, 0);
1217             facing = DoRotation(facing, 0, headyaw * .6, 0);
1218         }
1219
1220         skeleton.specialforward[0] = facing;
1221         //skeleton.specialforward[0]=DoRotation(facing,0,yaw,0);
1222         static int i;
1223         for (i = 0; i < skeleton.num_muscles; i++) {
1224             if (skeleton.muscles[i].visible && (skeleton.muscles[i].parent1->label == head || skeleton.muscles[i].parent2->label == head)) {
1225                 skeleton.FindRotationMuscle(i, animTarget);
1226             }
1227         }
1228     }
1229 }
1230
1231 void Person::RagDoll(bool checkcollision)
1232 {
1233     static XYZ change;
1234     static int l, i, j;
1235     static float speed;
1236     if (!skeleton.free) {
1237         if (id == 0)numfalls++;
1238         if (id == 0 && isFlip())numflipfail++;
1239
1240         escapednum = 0;
1241
1242         facing = 0;
1243         facing.z = 1;
1244         facing = DoRotation(facing, 0, yaw, 0);
1245
1246         skeleton.freetime = 0;
1247
1248         skeleton.longdead = 0;
1249
1250         skeleton.free = 1;
1251         skeleton.broken = 0;
1252         skeleton.spinny = 1;
1253         freefall = 1;
1254         skeleton.freefall = 1;
1255
1256         if (!isnormal(velocity.x))velocity.x = 0;
1257         if (!isnormal(velocity.y))velocity.y = 0;
1258         if (!isnormal(velocity.z))velocity.z = 0;
1259         if (!isnormal(yaw))yaw = 0;
1260         if (!isnormal(coords.x))coords = 0;
1261         if (!isnormal(tilt))tilt = 0;
1262         if (!isnormal(tilt2))tilt2 = 0;
1263
1264         for (i = 0; i < skeleton.num_joints; i++) {
1265             skeleton.joints[i].delay = 0;
1266             skeleton.joints[i].locked = 0;
1267             skeleton.joints[i].position = DoRotation(DoRotation(DoRotation(skeleton.joints[i].position, 0, 0, tilt), tilt2, 0, 0), 0, yaw, 0);
1268             if (!isnormal(skeleton.joints[i].position.x))skeleton.joints[i].position = DoRotation(skeleton.joints[i].position, 0, yaw, 0);
1269             if (!isnormal(skeleton.joints[i].position.x))skeleton.joints[i].position = skeleton.joints[i].position;
1270             if (!isnormal(skeleton.joints[i].position.x))skeleton.joints[i].position = coords;
1271             skeleton.joints[i].position.y += .1;
1272             skeleton.joints[i].oldposition = skeleton.joints[i].position;
1273             skeleton.joints[i].realoldposition = skeleton.joints[i].position * scale + coords;
1274         }
1275
1276         for (i = 0; i < skeleton.num_joints; i++) {
1277             skeleton.joints[i].velocity = 0;
1278             skeleton.joints[i].velchange = 0;
1279         }
1280         skeleton.DoConstraints(&coords, &scale);
1281         if (animation[animCurrent].height == lowheight || animation[animTarget].height == lowheight) {
1282             skeleton.DoConstraints(&coords, &scale);
1283             skeleton.DoConstraints(&coords, &scale);
1284             skeleton.DoConstraints(&coords, &scale);
1285             skeleton.DoConstraints(&coords, &scale);
1286         }
1287
1288         speed = animation[animTarget].speed[frameTarget] * 2;
1289         if (animation[animCurrent].speed[frameCurrent] > animation[animTarget].speed[frameTarget]) {
1290             speed = animation[animCurrent].speed[frameCurrent] * 2;
1291         }
1292         if (transspeed)speed = transspeed * 2;
1293
1294         speed *= speedmult;
1295
1296         for (i = 0; i < skeleton.num_joints; i++) {
1297             if ((animation[animCurrent].attack != reversed || animCurrent == swordslashreversedanim) && animCurrent != rabbitkickanim && !isLanding() && !wasLanding() && animation[animCurrent].height == animation[animTarget].height)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);
1298             else skeleton.joints[i].velocity = velocity / scale + facing * 5;
1299             change.x = (float)(Random() % 100) / 100;
1300             change.y = (float)(Random() % 100) / 100;
1301             change.z = (float)(Random() % 100) / 100;
1302             skeleton.joints[i].velocity += change;
1303             skeleton.joints[abs(Random() % skeleton.num_joints)].velocity -= change;
1304
1305             change.x = (float)(Random() % 100) / 100;
1306             change.y = (float)(Random() % 100) / 100;
1307             change.z = (float)(Random() % 100) / 100;
1308             skeleton.joints[i].velchange += change;
1309             skeleton.joints[abs(Random() % skeleton.num_joints)].velchange -= change;
1310         }
1311
1312         if (checkcollision) {
1313             XYZ average;
1314             XYZ lowpoint;
1315             XYZ colpoint;
1316             int howmany;
1317             average = 0;
1318             howmany = 0;
1319             for (j = 0; j < skeleton.num_joints; j++) {
1320                 average += skeleton.joints[j].position;
1321                 howmany++;
1322             }
1323             average /= howmany;
1324             coords += average * scale;
1325             for (j = 0; j < skeleton.num_joints; j++) {
1326                 skeleton.joints[j].position -= average;
1327             }
1328
1329             whichpatchx = coords.x / (terrain.size / subdivision * terrain.scale);
1330             whichpatchz = coords.z / (terrain.size / subdivision * terrain.scale);
1331             if (terrain.patchobjectnum[whichpatchx][whichpatchz])
1332                 for (l = 0; l < terrain.patchobjectnum[whichpatchx][whichpatchz]; l++) {
1333                     i = terrain.patchobjects[whichpatchx][whichpatchz][l];
1334                     lowpoint = coords;
1335                     lowpoint.y += 1;
1336                     if (SphereCheck(&lowpoint, 3, &colpoint, &objects.position[i], &objects.yaw[i], &objects.model[i]) != -1) {
1337                         coords.x = lowpoint.x;
1338                         coords.z = lowpoint.z;
1339                     }
1340                 }
1341         }
1342
1343         yaw = 0;
1344         updatedelay = 0;
1345
1346         velocity = 0;
1347         for (i = 0; i < skeleton.num_joints; i++) {
1348             velocity += skeleton.joints[i].velocity * scale;
1349         }
1350         velocity /= skeleton.num_joints;
1351
1352         if (Random() % 2 == 0) {
1353             if (weaponactive != -1 && animTarget != rabbitkickanim && num_weapons > 0) {
1354                 weapons[weaponids[0]].owner = -1;
1355                 weapons[weaponids[0]].hitsomething = 0;
1356                 weapons[weaponids[0]].velocity = skeleton.joints[skeleton.jointlabels[righthand]].velocity * scale * -.3;
1357                 weapons[weaponids[0]].velocity.x += .01;
1358                 weapons[weaponids[0]].tipvelocity = skeleton.joints[skeleton.jointlabels[righthand]].velocity * scale;
1359                 weapons[weaponids[0]].missed = 1;
1360                 weapons[weaponids[0]].freetime = 0;
1361                 weapons[weaponids[0]].firstfree = 1;
1362                 weapons[weaponids[0]].physics = 1;
1363                 num_weapons--;
1364                 if (num_weapons) {
1365                     weaponids[0] = weaponids[num_weapons];
1366                     if (weaponstuck == num_weapons)weaponstuck = 0;
1367                 }
1368                 weaponactive = -1;
1369                 for (i = 0; i < numplayers; i++) {
1370                     player[i].wentforweapon = 0;
1371                 }
1372             }
1373         }
1374
1375         animTarget = bounceidleanim;
1376         animCurrent = bounceidleanim;
1377         frameTarget = 0;
1378         frameCurrent = 0;
1379     }
1380 }
1381
1382
1383
1384 void Person::FootLand(int which, float opacity)
1385 {
1386     static XYZ terrainlight;
1387     static XYZ footvel, footpoint;
1388     if (opacity >= 1 || skiddelay <= 0)
1389         if (opacity > 1) {
1390             footvel = 0;
1391             if (which == 0)footpoint = DoRotation(skeleton.joints[skeleton.jointlabels[leftfoot]].position, 0, yaw, 0) * scale + coords;
1392             if (which == 1)footpoint = DoRotation(skeleton.joints[skeleton.jointlabels[rightfoot]].position, 0, yaw, 0) * scale + coords;
1393             //footpoint.y=coords.y;
1394             if (distsq(&footpoint, &viewer))Sprite::MakeSprite(cloudsprite, footpoint, footvel, 1, 1, 1, .5, .2 * opacity);
1395         } else if (environment == snowyenvironment && onterrain && terrain.getOpacity(coords.x, coords.z) < .2) {
1396             footvel = velocity / 5;
1397             if (footvel.y < .8)footvel.y = .8;
1398             if (which == 0)footpoint = DoRotation(skeleton.joints[skeleton.jointlabels[leftfoot]].position, 0, yaw, 0) * scale + coords;
1399             if (which == 1)footpoint = DoRotation(skeleton.joints[skeleton.jointlabels[rightfoot]].position, 0, yaw, 0) * scale + coords;
1400             footpoint.y = terrain.getHeight(footpoint.x, footpoint.z);
1401             terrainlight = terrain.getLighting(footpoint.x, footpoint.z);
1402             if (distsq(&footpoint, &viewer) < viewdistance * viewdistance / 4)Sprite::MakeSprite(cloudsprite, footpoint, footvel * .6, terrainlight.x, terrainlight.y, terrainlight.z, .5, .7 * opacity);
1403             if (opacity >= 1 || detail == 2)if (detail == 2)if (distsq(&footpoint, &viewer) < viewdistance * viewdistance / 4)terrain.MakeDecal(footprintdecal, footpoint, .2, 1 * opacity, yaw);
1404         } else if (environment == grassyenvironment && onterrain && terrain.getOpacity(coords.x, coords.z) < .2) {
1405             footvel = velocity / 5;
1406             if (footvel.y < .8)footvel.y = .8;
1407             if (which == 0)footpoint = DoRotation(skeleton.joints[skeleton.jointlabels[leftfoot]].position, 0, yaw, 0) * scale + coords;
1408             if (which == 1)footpoint = DoRotation(skeleton.joints[skeleton.jointlabels[rightfoot]].position, 0, yaw, 0) * scale + coords;
1409             footpoint.y = terrain.getHeight(footpoint.x, footpoint.z);
1410             terrainlight = terrain.getLighting(footpoint.x, footpoint.z);
1411             if (distsq(&footpoint, &viewer) < viewdistance * viewdistance / 4)Sprite::MakeSprite(cloudsprite, footpoint, footvel * .6, terrainlight.x * 90 / 255, terrainlight.y * 70 / 255, terrainlight.z * 8 / 255, .5, .5 * opacity);
1412         } else if (environment == desertenvironment && onterrain && terrain.getOpacity(coords.x, coords.z) < .2) {
1413             footvel = velocity / 5;
1414             if (footvel.y < .8)footvel.y = .8;
1415             if (which == 0)footpoint = DoRotation(skeleton.joints[skeleton.jointlabels[leftfoot]].position, 0, yaw, 0) * scale + coords;
1416             if (which == 1)footpoint = DoRotation(skeleton.joints[skeleton.jointlabels[rightfoot]].position, 0, yaw, 0) * scale + coords;
1417             footpoint.y = terrain.getHeight(footpoint.x, footpoint.z);
1418             terrainlight = terrain.getLighting(footpoint.x, footpoint.z);
1419             if (distsq(&footpoint, &viewer) < viewdistance * viewdistance / 4)Sprite::MakeSprite(cloudsprite, footpoint, footvel * .6, terrainlight.x * 190 / 255, terrainlight.y * 170 / 255, terrainlight.z * 108 / 255, .5, .7 * opacity);
1420             if (opacity >= 1 || detail == 2)if (detail == 2)if (distsq(&footpoint, &viewer) < viewdistance * viewdistance / 4)terrain.MakeDecal(footprintdecal, footpoint, .2, .25 * opacity, yaw);
1421         } else if (isLanding() || animTarget == jumpupanim || isLandhard()) {
1422             footvel = velocity / 5;
1423             if (footvel.y < .8)footvel.y = .8;
1424             if (which == 0)footpoint = DoRotation(skeleton.joints[skeleton.jointlabels[leftfoot]].position, 0, yaw, 0) * scale + coords;
1425             if (which == 1)footpoint = DoRotation(skeleton.joints[skeleton.jointlabels[rightfoot]].position, 0, yaw, 0) * scale + coords;
1426             //footpoint.y=coords.y;
1427             if (distsq(&footpoint, &viewer) < viewdistance * viewdistance / 4)Sprite::MakeSprite(cloudsprite, footpoint, footvel * .6, 1, 1, 1, .5, .2 * opacity);
1428         }
1429 }
1430
1431 void Person::Puff(int whichlabel)
1432 {
1433     static XYZ footvel, footpoint;
1434
1435     footvel = 0;
1436     footpoint = DoRotation(skeleton.joints[skeleton.jointlabels[whichlabel]].position, 0, yaw, 0) * scale + coords;
1437     Sprite::MakeSprite(cloudimpactsprite, footpoint, footvel, 1, 1, 1, .9, .3);
1438 }
1439
1440 Joint& Person::getJointFor(int bodypart)
1441 {
1442     return skeleton.joints[skeleton.jointlabels[bodypart]];
1443 }
1444
1445 void Person::setAnimation(int animation)
1446 {
1447     animTarget = animation;
1448     frameTarget = 0;
1449     target = 0;
1450 }
1451
1452 void    Person::DoAnimations()
1453 {
1454     if (!skeleton.free) {
1455         int i = 0;
1456         static float oldtarget;
1457
1458         if (isIdle() && animCurrent != getIdle())normalsupdatedelay = 0;
1459
1460         if (animTarget == tempanim || animCurrent == tempanim) {
1461             animation[tempanim] = tempanimation;
1462         }
1463         if (animTarget == jumpupanim || animTarget == jumpdownanim || isFlip()) {
1464             float gLoc[3];
1465             float vel[3];
1466             gLoc[0] = coords.x;
1467             gLoc[1] = coords.y;
1468             gLoc[2] = coords.z;
1469             vel[0] = velocity.x;
1470             vel[1] = velocity.y;
1471             vel[2] = velocity.z;
1472
1473             if (id == 0) {
1474                 OPENAL_3D_SetAttributes(channels[whooshsound], gLoc, vel);
1475                 OPENAL_SetVolume(channels[whooshsound], 64 * findLength(&velocity) / 5);
1476             }
1477             if (((velocity.y < -15) || (crouchkeydown && velocity.y < -8)) && abs(velocity.y) * 4 > fast_sqrt(velocity.x * velocity.x * velocity.z * velocity.z))landhard = 1;
1478             if (!crouchkeydown && velocity.y >= -15)landhard = 0;
1479         }
1480         if ((animCurrent == jumpupanim || animTarget == jumpdownanim)/*&&velocity.y<40*/ && !isFlip() && (!isLanding() && !isLandhard()) && ((crouchkeydown && !crouchtogglekeydown))) {
1481             XYZ targfacing;
1482             targfacing = 0;
1483             targfacing.z = 1;
1484
1485             targfacing = DoRotation(targfacing, 0, targetyaw, 0);
1486
1487             if (normaldotproduct(targfacing, velocity) >= -.3)animTarget = flipanim;
1488             else animTarget = backflipanim;
1489             crouchtogglekeydown = 1;
1490             frameTarget = 0;
1491             target = 0;
1492
1493             if (id == 0)numflipped++;
1494         }
1495
1496         if (animation[animTarget].attack != reversed)feint = 0;
1497         if (!crouchkeydown || (isLanding() || isLandhard()) || (wasLanding() || wasLandhard())) {
1498             crouchtogglekeydown = 0;
1499             if (aitype == playercontrolled)feint = 0;
1500         } else {
1501             if (!crouchtogglekeydown && animation[animTarget].attack == reversed && aitype == playercontrolled && (escapednum < 2 || reversaltrain))feint = 1;
1502             if (!isFlip())crouchtogglekeydown = 1;
1503         }
1504
1505
1506         if (animation[animTarget].attack || animCurrent == getupfrombackanim || animCurrent == getupfromfrontanim) {
1507             if (detail)normalsupdatedelay = 0;
1508         }
1509
1510         if (target >= 1) {
1511             if (animTarget == rollanim && frameTarget == 3 && onfire) {
1512                 onfire = 0;
1513                 emit_sound_at(fireendsound, coords);
1514                 pause_sound(stream_firesound);
1515                 deathbleeding = 0;
1516             }
1517
1518             if (animTarget == rabbittacklinganim && frameTarget == 1) {
1519                 //if(victim->aitype==attacktypecutoff&&Random()%2==0&&victim->stunned<=0&&animation[victim->animTarget].attack==neutral&&victim->id!=0)Reverse();
1520                 if (victim->aitype == attacktypecutoff && victim->stunned <= 0 && victim->surprised <= 0 && victim->id != 0)Reverse();
1521                 if (animTarget == rabbittacklinganim && frameTarget == 1 && !victim->isCrouch() && victim->animTarget != backhandspringanim) {
1522                     if (normaldotproduct(victim->facing, facing) > 0)victim->animTarget = rabbittackledbackanim;
1523                     else victim->animTarget = rabbittackledfrontanim;
1524                     victim->frameTarget = 2;
1525                     victim->target = 0;
1526                     victim->yaw = yaw;
1527                     victim->targetyaw = yaw;
1528                     if (victim->aitype == gethelptype)victim->DoDamage(victim->damagetolerance - victim->damage);
1529                     //victim->DoDamage(30);
1530                     if (creature == wolftype) {
1531                         DoBloodBig(0, 255);
1532                         emit_sound_at(clawslicesound, victim->coords);
1533                         victim->spurt = 1;
1534                         victim->DoBloodBig(1 / victim->armorhead, 210);
1535                     }
1536                     award_bonus(id, TackleBonus,
1537                                 victim->aitype == gethelptype ? 50 : 0);
1538                 }
1539             }
1540
1541             if (!drawtogglekeydown && drawkeydown && (weaponactive == -1 || num_weapons == 1) && (animation[animTarget].label[frameTarget] || (animTarget != animCurrent && animCurrent == rollanim)) && num_weapons > 0 && creature != wolftype) {
1542                 if (weapons[weaponids[0]].getType() == knife) {
1543                     if (weaponactive == -1)weaponactive = 0;
1544                     else if (weaponactive == 0)weaponactive = -1;
1545
1546                     if (weaponactive == -1) {
1547                         emit_sound_at(knifesheathesound, coords);
1548                     }
1549                     if (weaponactive != -1) {
1550                         emit_sound_at(knifedrawsound, coords, 128);
1551                     }
1552                 }
1553                 drawtogglekeydown = 1;
1554             }
1555             //Footstep sounds
1556             if (tutoriallevel != 1 || id == 0)
1557                 if ((animation[animTarget].label[frameTarget] && (animation[animTarget].label[frameTarget] < 5 || animation[animTarget].label[frameTarget] == 8))/*||(animTarget==rollanim&&frameTarget==animation[rollanim].numframes-1)*/) {
1558                     int whichsound;
1559                     if (onterrain) {
1560                         if (terrain.getOpacity(coords.x, coords.z) < .2) {
1561                             if (animation[animTarget].label[frameTarget] == 1)whichsound = footstepsound;
1562                             else whichsound = footstepsound2;
1563                             if (animation[animTarget].label[frameTarget] == 1)FootLand(0, 1);
1564                             if (animation[animTarget].label[frameTarget] == 2)FootLand(1, 1);
1565                             if (animation[animTarget].label[frameTarget] == 3 && isRun()) {
1566                                 FootLand(1, 1);
1567                                 FootLand(0, 1);
1568                             }
1569
1570                         }
1571                         if (terrain.getOpacity(coords.x, coords.z) >= .2) {
1572                             if (animation[animTarget].label[frameTarget] == 1)whichsound = footstepsound3;
1573                             else whichsound = footstepsound4;
1574                         }
1575                     }
1576                     if (!onterrain) {
1577                         if (animation[animTarget].label[frameTarget] == 1)whichsound = footstepsound3;
1578                         else whichsound = footstepsound4;
1579                     }
1580                     if (animation[animTarget].label[frameTarget] == 4 && (weaponactive == -1 || (animTarget != knifeslashstartanim && animTarget != knifethrowanim && animTarget != crouchstabanim && animTarget != swordgroundstabanim && animTarget != knifefollowanim))) {
1581                         if (animation[animTarget].attack != neutral) {
1582                             i = abs(Random() % 3);
1583                             if (i == 0)whichsound = lowwhooshsound;
1584                             if (i == 1)whichsound = midwhooshsound;
1585                             if (i == 2)whichsound = highwhooshsound;
1586                         }
1587                         if (animation[animTarget].attack == neutral)whichsound = movewhooshsound;
1588                     } else if (animation[animTarget].label[frameTarget] == 4)whichsound = knifeswishsound;
1589                     if (animation[animTarget].label[frameTarget] == 8 && tutoriallevel != 1)whichsound = landsound2;
1590
1591                     emit_sound_at(whichsound, coords, 256.);
1592
1593                     if (id == 0)
1594                         if (whichsound == footstepsound || whichsound == footstepsound2 || whichsound == footstepsound3 || whichsound == footstepsound4) {
1595                             envsound[numenvsounds] = coords;
1596                             if (animTarget == wolfrunninganim || animTarget == rabbitrunninganim)envsoundvol[numenvsounds] = 15;
1597                             else envsoundvol[numenvsounds] = 6;
1598                             envsoundlife[numenvsounds] = .4;
1599                             numenvsounds++;
1600                         }
1601
1602                     if (animation[animTarget].label[frameTarget] == 3) {
1603                         whichsound--;
1604                         emit_sound_at(whichsound, coords, 128.);
1605                     }
1606                 }
1607
1608             //Combat sounds
1609             if (tutoriallevel != 1 || id == 0)
1610                 if (speechdelay <= 0)
1611                     if (animTarget != crouchstabanim && animTarget != swordgroundstabanim && animTarget != staffgroundsmashanim)
1612                         if ((animation[animTarget].label[frameTarget] && (animation[animTarget].label[frameTarget] < 5 || animation[animTarget].label[frameTarget] == 8))/*||(animTarget==rollanim&&frameTarget==animation[rollanim].numframes-1)*/) {
1613                             int whichsound = -1;
1614                             if (animation[animTarget].label[frameTarget] == 4 && aitype != playercontrolled) {
1615                                 if (animation[animTarget].attack != neutral) {
1616                                     i = abs(Random() % 4);
1617                                     if (creature == rabbittype) {
1618                                         if (i == 0)whichsound = rabbitattacksound;
1619                                         if (i == 1)whichsound = rabbitattack2sound;
1620                                         if (i == 2)whichsound = rabbitattack3sound;
1621                                         if (i == 3)whichsound = rabbitattack4sound;
1622                                     }
1623                                     if (creature == wolftype) {
1624                                         if (i == 0)whichsound = barksound;
1625                                         if (i == 1)whichsound = bark2sound;
1626                                         if (i == 2)whichsound = bark3sound;
1627                                         if (i == 3)whichsound = barkgrowlsound;
1628                                     }
1629                                     speechdelay = .3;
1630                                 }
1631                                 //if(animation[animTarget].attack==neutral)whichsound=movewhooshsound;
1632                             }
1633                             //else if(animation[animTarget].label[frameTarget]==4)whichsound=knifeswishsound;
1634                             //if(animation[animTarget].label[frameTarget]==8)whichsound=landsound2;
1635
1636                             if (whichsound != -1) {
1637                                 emit_sound_at(whichsound, coords);
1638                             }
1639                         }
1640
1641
1642
1643             if ((!wasLanding() && !wasLandhard()) && animCurrent != getIdle() && (isLanding() || isLandhard())) {
1644                 FootLand(0, 1);
1645                 FootLand(1, 1);
1646             }
1647
1648             transspeed = 0;
1649             currentoffset = targetoffset;
1650             frameTarget = frameCurrent;
1651             animCurrent = animTarget;
1652             frameTarget++;
1653
1654             if (animTarget == removeknifeanim && animation[animTarget].label[frameCurrent] == 5) {
1655                 for (i = 0; i < weapons.size(); i++) {
1656                     if (weapons[i].owner == -1)
1657                         if (distsqflat(&coords, &weapons[i].position) < 4 && weaponactive == -1) {
1658                             if (distsq(&coords, &weapons[i].position) >= 1) {
1659                                 if (weapons[i].getType() != staff) {
1660                                     emit_sound_at(knifedrawsound, coords, 128.);
1661                                 }
1662
1663                                 weaponactive = 0;
1664                                 weapons[i].owner = id;
1665                                 if (num_weapons > 0) {
1666                                     weaponids[num_weapons] = weaponids[0];
1667                                 }
1668                                 num_weapons++;
1669                                 weaponids[0] = i;
1670                             }
1671                         }
1672                 }
1673             }
1674
1675             if (animTarget == crouchremoveknifeanim && animation[animTarget].label[frameCurrent] == 5) {
1676                 for (i = 0; i < weapons.size(); i++) {
1677                     bool willwork = true;
1678                     if (weapons[i].owner != -1)
1679                         if (player[weapons[i].owner].weaponstuck != -1)
1680                             if (player[weapons[i].owner].weaponids[player[weapons[i].owner].weaponstuck] == i)
1681                                 if (player[weapons[i].owner].num_weapons > 1)willwork = 0;
1682                     if ((weapons[i].owner == -1) || (hasvictim && weapons[i].owner == victim->id && victim->skeleton.free))
1683                         if (willwork && distsqflat(&coords, &weapons[i].position) < 3 && weaponactive == -1) {
1684                             if (distsq(&coords, &weapons[i].position) < 1 || hasvictim) {
1685                                 bool fleshstuck = false;
1686                                 if (weapons[i].owner != -1)
1687                                     if (victim->weaponstuck != -1) {
1688                                         if (victim->weaponids[victim->weaponstuck] == i) {
1689                                             fleshstuck = true;
1690                                         }
1691                                     }
1692                                 if (fleshstuck) {
1693                                     emit_sound_at(fleshstabremovesound, coords, 128.);
1694                                 } else {
1695                                     if (weapons[i].getType() != staff) {
1696                                         emit_sound_at(knifedrawsound, coords, 128.);
1697                                     }
1698                                 }
1699                                 weaponactive = 0;
1700                                 if (weapons[i].owner != -1) {
1701
1702                                     victim = &player[weapons[i].owner];
1703                                     if (victim->num_weapons == 1)victim->num_weapons = 0;
1704                                     else victim->num_weapons = 1;
1705
1706                                     //victim->weaponactive=-1;
1707                                     victim->skeleton.longdead = 0;
1708                                     victim->skeleton.free = 1;
1709                                     victim->skeleton.broken = 0;
1710
1711                                     for (int j = 0; j < victim->skeleton.num_joints; j++) {
1712                                         victim->skeleton.joints[j].velchange = 0;
1713                                         victim->skeleton.joints[j].locked = 0;
1714                                     }
1715
1716                                     XYZ relative;
1717                                     relative = 0;
1718                                     relative.y = 10;
1719                                     Normalise(&relative);
1720                                     XYZ footvel, footpoint;
1721                                     footvel = 0;
1722                                     footpoint = weapons[i].position;
1723                                     if (victim->weaponstuck != -1) {
1724                                         if (victim->weaponids[victim->weaponstuck] == i) {
1725                                             if (bloodtoggle)Sprite::MakeSprite(cloudimpactsprite, footpoint, footvel, 1, 0, 0, .8, .3);
1726                                             weapons[i].bloody = 2;
1727                                             weapons[i].blooddrip = 5;
1728                                             victim->weaponstuck = -1;
1729                                         }
1730                                     }
1731                                     if (victim->num_weapons > 0) {
1732                                         if (victim->weaponstuck != 0 && victim->weaponstuck != -1)victim->weaponstuck = 0;
1733                                         if (victim->weaponids[0] == i)
1734                                             victim->weaponids[0] = victim->weaponids[victim->num_weapons];
1735                                     }
1736
1737                                     victim->skeleton.joints[victim->skeleton.jointlabels[abdomen]].velocity += relative * 6;
1738                                     victim->skeleton.joints[victim->skeleton.jointlabels[neck]].velocity += relative * 6;
1739                                     victim->skeleton.joints[victim->skeleton.jointlabels[rightshoulder]].velocity += relative * 6;
1740                                     victim->skeleton.joints[victim->skeleton.jointlabels[leftshoulder]].velocity += relative * 6;
1741                                 }
1742                                 weapons[i].owner = id;
1743                                 if (num_weapons > 0) {
1744                                     weaponids[num_weapons] = weaponids[0];
1745                                 }
1746                                 num_weapons++;
1747                                 weaponids[0] = i;
1748                             }
1749                         }
1750                 }
1751             }
1752
1753             if (animCurrent == drawleftanim && animation[animTarget].label[frameCurrent] == 5) {
1754                 if (weaponactive == -1)weaponactive = 0;
1755                 else if (weaponactive == 0) {
1756                     weaponactive = -1;
1757                     if (num_weapons == 2) {
1758                         int buffer;
1759                         buffer = weaponids[0];
1760                         weaponids[0] = weaponids[1];
1761                         weaponids[1] = buffer;
1762                     }
1763                 }
1764                 if (weaponactive == -1) {
1765                     emit_sound_at(knifesheathesound, coords, 128.);
1766                 }
1767                 if (weaponactive != -1) {
1768                     emit_sound_at(knifedrawsound, coords, 128.);
1769                 }
1770             }
1771
1772
1773             if ((animCurrent == walljumprightkickanim && animTarget == walljumprightkickanim) || (animCurrent == walljumpleftkickanim && animTarget == walljumpleftkickanim)) {
1774                 XYZ rotatetarget = DoRotation(skeleton.forward, 0, yaw, 0);
1775                 Normalise(&rotatetarget);
1776                 targetyaw = -asin(0 - rotatetarget.x);
1777                 targetyaw *= 360 / 6.28;
1778                 if (rotatetarget.z < 0)targetyaw = 180 - targetyaw;
1779
1780                 if (animTarget == walljumprightkickanim)targetyaw += 40;
1781                 if (animTarget == walljumpleftkickanim)targetyaw -= 40;
1782             }
1783
1784             bool dojumpattack;
1785             dojumpattack = 0;
1786             if ((animTarget == rabbitrunninganim || animTarget == wolfrunninganim) && frameTarget == 3 && (jumpkeydown || attackkeydown || id != 0))dojumpattack = 1;
1787             if (hasvictim)
1788                 if (distsq(&victim->coords, &/*player[i].*/coords) < 5 && victim->aitype == gethelptype && (attackkeydown) && !victim->skeleton.free && victim->isRun() && victim->runninghowlong >= 1)dojumpattack = 1;
1789             if (!hostile)dojumpattack = 0;
1790             if (dojumpattack) {
1791                 if ((animTarget == rabbitrunninganim || animTarget == wolfrunninganim) && id == 0) {
1792                     animTarget = rabbittackleanim;
1793                     frameTarget = 0;
1794                     emit_sound_at(jumpsound, coords);
1795                 }
1796
1797                 float closestdist;
1798                 closestdist = 0;
1799                 int closestid;
1800                 closestid = -1;
1801                 XYZ targetloc;
1802                 targetloc = velocity;
1803                 Normalise(&targetloc);
1804                 targetloc += coords;
1805                 for (i = 0; i < numplayers; i++) {
1806                     if (i != id)
1807                         if (distsq(&targetloc, &player[i].coords) < closestdist || closestdist == 0) {
1808                             closestdist = distsq(&targetloc, &player[i].coords);
1809                             closestid = i;
1810                         }
1811                 }
1812                 if (closestid != -1)
1813                     if (closestdist < 5 && !player[closestid].dead && animation[player[closestid].animTarget].height != lowheight && player[closestid].animTarget != backhandspringanim) {
1814                         hasvictim = 1;
1815                         victim = &player[closestid];
1816                         coords = victim->coords;
1817                         animCurrent = rabbittacklinganim;
1818                         animTarget = rabbittacklinganim;
1819                         frameCurrent = 0;
1820                         frameTarget = 1;
1821                         XYZ rotatetarget;
1822                         if (coords.z != victim->coords.z || coords.x != victim->coords.x) {
1823                             rotatetarget = coords - victim->coords;
1824                             Normalise(&rotatetarget);
1825                             targetyaw = -asin(0 - rotatetarget.x);
1826                             targetyaw *= 360 / 6.28;
1827                             if (rotatetarget.z < 0)targetyaw = 180 - targetyaw;
1828                         }
1829                         if (animTarget != rabbitrunninganim) {
1830                             emit_sound_at(jumpsound, coords, 128.);
1831                         }
1832                     }
1833             }
1834
1835             //Move impacts
1836             float damagemult = 1 * power;
1837             if (creature == wolftype)damagemult = 2.5 * power;
1838             if (hasvictim) {
1839                 damagemult /= victim->damagetolerance / 200;
1840             }
1841             //if(onfire)damagemult=3;
1842             if ((animation[animTarget].attack == normalattack || animTarget == walljumprightkickanim || animTarget == walljumpleftkickanim) && (!feint) && (victim->skeleton.free != 2 || animTarget == killanim || animTarget == dropkickanim || animTarget == crouchstabanim || animTarget == swordgroundstabanim || animTarget == staffgroundsmashanim)) {
1843                 if (animTarget == spinkickanim && animation[animTarget].label[frameCurrent] == 5) {
1844                     if (distsq(&coords, &victim->coords) < (scale * 5) * (scale * 5) * 3 && 3 && animation[victim->animTarget].height != lowheight) {
1845                         escapednum = 0;
1846                         if (id == 0)camerashake += .4;
1847                         if (Random() % 2 || creature == wolftype) {
1848                             victim->spurt = 1;
1849                             DoBlood(.2, 250);
1850                             if (creature == wolftype)DoBloodBig(0, 250);
1851                         }
1852                         if (tutoriallevel != 1) {
1853                             emit_sound_at(heavyimpactsound, victim->coords, 128.);
1854                         }
1855                         if (creature == wolftype) {
1856                             emit_sound_at(clawslicesound, victim->coords, 128.);
1857                             victim->spurt = 1;
1858                             victim->DoBloodBig(2 / victim->armorhead, 175);
1859                         }
1860                         victim->RagDoll(0);
1861                         XYZ relative;
1862                         relative = victim->coords - coords;
1863                         relative.y = 0;
1864                         Normalise(&relative);
1865                         relative = DoRotation(relative, 0, -90, 0);
1866                         for (i = 0; i < victim->skeleton.num_joints; i++) {
1867                             victim->skeleton.joints[i].velocity += relative * damagemult * 40;
1868                         }
1869                         victim->skeleton.joints[victim->skeleton.jointlabels[head]].velocity += relative * damagemult * 200;
1870                         //FootLand(1,2);
1871                         victim->Puff(head);
1872                         victim->DoDamage(damagemult * 100 / victim->protectionhead);
1873
1874                         SolidHitBonus(id);
1875                     }
1876                 }
1877
1878                 if (animTarget == wolfslapanim && animation[animTarget].label[frameCurrent] == 5) {
1879                     if (distsq(&coords, &victim->coords) < (scale * 5) * (scale * 5) * 3 && 3 && animation[victim->animTarget].height != lowheight) {
1880                         escapednum = 0;
1881                         if (id == 0)camerashake += .4;
1882                         if (Random() % 2 || creature == wolftype) {
1883                             victim->spurt = 1;
1884                             if (creature == wolftype)DoBloodBig(0, 235);
1885                         }
1886                         emit_sound_at(whooshhitsound, victim->coords);
1887                         if (creature == wolftype) {
1888                             emit_sound_at(clawslicesound, victim->coords, 128.);
1889                             victim->spurt = 1;
1890                             victim->DoBloodBig(2, 175);
1891                         }
1892                         victim->RagDoll(0);
1893                         XYZ relative;
1894                         relative = victim->coords - coords;
1895                         relative.y = 0;
1896                         Normalise(&relative);
1897                         relative.y -= 1;
1898                         Normalise(&relative);
1899                         relative = DoRotation(relative, 0, 90, 0);
1900                         for (i = 0; i < victim->skeleton.num_joints; i++) {
1901                             victim->skeleton.joints[i].velocity += relative * damagemult * 20;
1902                         }
1903                         victim->skeleton.joints[victim->skeleton.jointlabels[head]].velocity += relative * damagemult * 100;
1904                         //FootLand(1,2);
1905                         victim->Puff(head);
1906                         victim->DoDamage(damagemult * 50 / victim->protectionhead);
1907                     }
1908                 }
1909
1910                 if (animTarget == walljumprightkickanim && animation[animTarget].label[frameCurrent] == 5) {
1911                     if (distsq(&coords, &victim->coords) < (scale * 5) * (scale * 5) * 3 && animation[victim->animTarget].height != lowheight) {
1912                         escapednum = 0;
1913                         if (id == 0)camerashake += .4;
1914                         victim->spurt = 1;
1915                         DoBlood(.2, 250);
1916                         if (tutoriallevel != 1) {
1917                             emit_sound_at(heavyimpactsound, victim->coords, 160.);
1918                         }
1919                         if (creature == wolftype) {
1920                             emit_sound_at(clawslicesound, victim->coords, 128.);
1921                             victim->spurt = 1;
1922                             victim->DoBloodBig(2 / victim->armorhead, 175);
1923                         }
1924                         victim->RagDoll(0);
1925                         XYZ relative;
1926                         relative = facing;
1927                         relative.y = 0;
1928                         Normalise(&relative);
1929                         relative = DoRotation(relative, 0, -90, 0);
1930                         for (i = 0; i < victim->skeleton.num_joints; i++) {
1931                             victim->skeleton.joints[i].velocity += relative * damagemult * 40;
1932                         }
1933                         victim->skeleton.joints[victim->skeleton.jointlabels[head]].velocity += relative * damagemult * 200;
1934                         //FootLand(1,2);
1935                         victim->Puff(head);
1936                         victim->DoDamage(damagemult * 150 / victim->protectionhead);
1937
1938                         if (victim->damage > victim->damagetolerance)
1939                             award_bonus(id, style);
1940                         else
1941                             SolidHitBonus(id);
1942                     }
1943                 }
1944
1945                 if (animTarget == walljumpleftkickanim && animation[animTarget].label[frameCurrent] == 5) {
1946                     if (distsq(&coords, &victim->coords) < (scale * 5) * (scale * 5) * 3 && animation[victim->animTarget].height != lowheight) {
1947                         escapednum = 0;
1948                         if (id == 0)camerashake += .4;
1949                         victim->spurt = 1;
1950                         DoBlood(.2, 250);
1951                         if (tutoriallevel != 1) {
1952                             emit_sound_at(heavyimpactsound, victim->coords, 160.);
1953                         }
1954                         if (creature == wolftype) {
1955                             emit_sound_at(clawslicesound, victim->coords, 128.);
1956                             victim->spurt = 1;
1957                             victim->DoBloodBig(2 / victim->armorhead, 175);
1958                         }
1959                         victim->RagDoll(0);
1960                         XYZ relative;
1961                         relative = facing;
1962                         relative.y = 0;
1963                         Normalise(&relative);
1964                         relative = DoRotation(relative, 0, 90, 0);
1965                         for (i = 0; i < victim->skeleton.num_joints; i++) {
1966                             victim->skeleton.joints[i].velocity += relative * damagemult * 40;
1967                         }
1968                         victim->skeleton.joints[victim->skeleton.jointlabels[head]].velocity += relative * damagemult * 200;
1969                         //FootLand(1,2);
1970                         victim->Puff(head);
1971                         victim->DoDamage(damagemult * 150 / victim->protectionhead);
1972
1973                         if (victim->damage > victim->damagetolerance)
1974                             award_bonus(id, style);
1975                         else
1976                             SolidHitBonus(id);
1977                     }
1978                 }
1979
1980                 if (animTarget == blockhighleftstrikeanim && animation[animTarget].label[frameCurrent] == 5) {
1981                     if (distsq(&coords, &victim->coords) < (scale * 5) * (scale * 5) * 3 && animation[victim->animTarget].height != lowheight) {
1982                         escapednum = 0;
1983                         if (id == 0)camerashake += .4;
1984                         if (Random() % 2) {
1985                             victim->spurt = 1;
1986                             DoBlood(.2, 235);
1987                         }
1988                         emit_sound_at(whooshhitsound, victim->coords);
1989                         victim->RagDoll(0);
1990                         XYZ relative;
1991                         relative = victim->coords - coords;
1992                         relative.y = 0;
1993                         Normalise(&relative);
1994                         for (i = 0; i < victim->skeleton.num_joints; i++) {
1995                             victim->skeleton.joints[i].velocity += relative * damagemult * 30;
1996                         }
1997                         victim->skeleton.joints[victim->skeleton.jointlabels[head]].velocity += relative * damagemult * 100;
1998                         //FootLand(1,2);
1999                         victim->Puff(head);
2000                         victim->DoDamage(damagemult * 50 / victim->protectionhead);
2001                     }
2002                 }
2003
2004                 if (animTarget == killanim && animation[animTarget].label[frameCurrent] == 8) {
2005                     if (distsq(&coords, &victim->coords) < (scale * 5) * (scale * 5) * 3 && victim->dead) {
2006                         escapednum = 0;
2007                         if (id == 0)camerashake += .2;
2008                         emit_sound_at(whooshhitsound, victim->coords, 128.);
2009
2010                         victim->skeleton.longdead = 0;
2011                         victim->skeleton.free = 1;
2012                         victim->skeleton.broken = 0;
2013                         victim->skeleton.spinny = 1;
2014
2015                         for (i = 0; i < victim->skeleton.num_joints; i++) {
2016                             victim->skeleton.joints[i].velchange = 0;
2017                             victim->skeleton.joints[i].delay = 0;
2018                             victim->skeleton.joints[i].locked = 0;
2019                             //victim->skeleton.joints[i].velocity=0;
2020                         }
2021
2022                         XYZ relative;
2023                         relative = 0;
2024                         relative.y = 1;
2025                         Normalise(&relative);
2026                         for (i = 0; i < victim->skeleton.num_joints; i++) {
2027                             victim->skeleton.joints[i].velocity.y = relative.y * 10;
2028                             victim->skeleton.joints[i].position.y += relative.y * .3;
2029                             victim->skeleton.joints[i].oldposition.y += relative.y * .3;
2030                             victim->skeleton.joints[i].realoldposition.y += relative.y * .3;
2031                         }
2032                         victim->Puff(abdomen);
2033                         victim->skeleton.joints[victim->skeleton.jointlabels[abdomen]].velocity.y = relative.y * 400;
2034                     }
2035                 }
2036
2037                 if (animTarget == killanim && animation[animTarget].label[frameCurrent] == 5) {
2038                     if (distsq(&coords, &victim->coords) < (scale * 5) * (scale * 5) * 9 && victim->dead) {
2039                         escapednum = 0;
2040                         if (id == 0)camerashake += .4;
2041                         if (tutoriallevel != 1) {
2042                             emit_sound_at(heavyimpactsound, coords, 128.);
2043                         }
2044                         XYZ relative;
2045                         relative = victim->coords - coords;
2046                         relative.y = 0;
2047                         Normalise(&relative);
2048                         for (i = 0; i < victim->skeleton.num_joints; i++) {
2049                             victim->skeleton.joints[i].velocity += relative * damagemult * 90;
2050                         }
2051                         victim->Puff(abdomen);
2052                         if (victim->dead != 2 && victim->permanentdamage > victim->damagetolerance - 250 && autoslomo) {
2053                             slomo = 1;
2054                             slomodelay = .2;
2055                         }
2056                         victim->DoDamage(damagemult * 500 / victim->protectionhigh);
2057                         victim->skeleton.joints[victim->skeleton.jointlabels[abdomen]].velocity += relative * damagemult * 300;
2058                     }
2059                 }
2060
2061                 if (animTarget == dropkickanim && animation[animTarget].label[frameCurrent] == 7) {
2062                     if (distsq(&coords, &victim->coords) < (scale * 5) * (scale * 5) * 9 && victim->skeleton.free) {
2063                         escapednum = 0;
2064                         if (id == 0)camerashake += .4;
2065                         if (tutoriallevel != 1) {
2066                             emit_sound_at(thudsound, coords);
2067                         }
2068
2069                         victim->skeleton.longdead = 0;
2070                         victim->skeleton.free = 1;
2071                         victim->skeleton.broken = 0;
2072                         victim->skeleton.spinny = 1;
2073
2074                         for (i = 0; i < victim->skeleton.num_joints; i++) {
2075                             victim->skeleton.joints[i].velchange = 0;
2076                             //victim->skeleton.joints[i].delay=0;
2077                             victim->skeleton.joints[i].locked = 0;
2078                         }
2079                         XYZ relative;
2080                         relative = victim->coords - coords;
2081                         Normalise(&relative);
2082                         relative.y += .3;
2083                         Normalise(&relative);
2084                         for (i = 0; i < victim->skeleton.num_joints; i++) {
2085                             victim->skeleton.joints[i].velocity += relative * damagemult * 20;
2086                         }
2087                         if (!victim->dead)
2088                             SolidHitBonus(id);
2089
2090                         victim->Puff(abdomen);
2091                         victim->DoDamage(damagemult * 20 / victim->protectionhigh);
2092                         victim->skeleton.joints[victim->skeleton.jointlabels[abdomen]].velocity += relative * damagemult * 200;
2093                         staggerdelay = .5;
2094                         if (!victim->dead)staggerdelay = 1.2;
2095
2096
2097                     }
2098                 }
2099
2100                 if ((animTarget == crouchstabanim || animTarget == swordgroundstabanim) && animation[animTarget].label[frameCurrent] == 5) {
2101                     //if(id==0)camerashake+=.4;
2102
2103                     if (hasvictim)
2104                         if (!victim->skeleton.free)hasvictim = 0;
2105
2106                     if (!hasvictim) {
2107                         terrain.MakeDecal(blooddecalfast, (weapons[weaponids[weaponactive]].tippoint * .8 + weapons[weaponids[weaponactive]].position * .2), .08, .6, Random() % 360);
2108                         emit_sound_at(knifesheathesound, coords, 128.);
2109                     }
2110
2111                     if (victim && hasvictim) {
2112                         if (distsq(&coords, &victim->coords) < (scale * 5) * (scale * 5) * 3) {
2113
2114                             XYZ where, startpoint, endpoint, movepoint, colpoint;
2115                             float rotationpoint;
2116                             int whichtri;
2117                             if (weapons[weaponids[weaponactive]].getType() == knife) {
2118                                 where = (weapons[weaponids[weaponactive]].tippoint * .6 + weapons[weaponids[weaponactive]].position * .4);
2119                                 where -= victim->coords;
2120                                 if (!victim->skeleton.free)where = DoRotation(where, 0, -victim->yaw, 0);
2121                                 //where=scale;
2122                                 startpoint = where;
2123                                 startpoint.y += 100;
2124                                 endpoint = where;
2125                                 endpoint.y -= 100;
2126                             }
2127                             if (weapons[weaponids[weaponactive]].getType() == sword) {
2128                                 where = weapons[weaponids[weaponactive]].position;
2129                                 where -= victim->coords;
2130                                 if (!victim->skeleton.free)where = DoRotation(where, 0, -victim->yaw, 0);
2131                                 startpoint = where;
2132                                 where = weapons[weaponids[weaponactive]].tippoint;
2133                                 where -= victim->coords;
2134                                 if (!victim->skeleton.free)where = DoRotation(where, 0, -victim->yaw, 0);
2135                                 endpoint = where;
2136                             }
2137                             if (weapons[weaponids[weaponactive]].getType() == staff) {
2138                                 where = weapons[weaponids[weaponactive]].position;
2139                                 where -= victim->coords;
2140                                 if (!victim->skeleton.free)where = DoRotation(where, 0, -victim->yaw, 0);
2141                                 startpoint = where;
2142                                 where = weapons[weaponids[weaponactive]].tippoint;
2143                                 where -= victim->coords;
2144                                 if (!victim->skeleton.free)where = DoRotation(where, 0, -victim->yaw, 0);
2145                                 endpoint = where;
2146                             }
2147                             movepoint = 0;
2148                             rotationpoint = 0;
2149                             whichtri = victim->skeleton.drawmodel.LineCheck(&startpoint, &endpoint, &colpoint, &movepoint, &rotationpoint);
2150
2151                             if (whichtri != -1) {
2152                                 if (victim->dead != 2) {
2153                                     victim->DoDamage(abs((victim->damagetolerance - victim->permanentdamage) * 2));
2154                                     if (!victim->dead)
2155                                         award_bonus(id, FinishedBonus);
2156                                 }
2157                                 if (bloodtoggle)weapons[weaponids[weaponactive]].bloody = 2;
2158
2159                                 victim->skeleton.longdead = 0;
2160                                 victim->skeleton.free = 1;
2161                                 victim->skeleton.broken = 0;
2162
2163                                 for (i = 0; i < victim->skeleton.num_joints; i++) {
2164                                     victim->skeleton.joints[i].velchange = 0;
2165                                     victim->skeleton.joints[i].locked = 0;
2166                                     //victim->skeleton.joints[i].velocity=0;
2167                                 }
2168                                 emit_sound_at(fleshstabsound, coords, 128);
2169
2170                             }
2171                             if (whichtri != -1 || weapons[weaponids[weaponactive]].bloody) {
2172                                 weapons[weaponids[weaponactive]].blooddrip += 5;
2173                                 weapons[weaponids[weaponactive]].blooddripdelay = 0;
2174                             }
2175                             if (whichtri == -1) {
2176                                 hasvictim = 0;
2177                                 emit_sound_at(knifesheathesound, coords, 128.);
2178                             }
2179                         }
2180                     }
2181                 }
2182
2183                 if ((animTarget == crouchstabanim || animTarget == swordgroundstabanim) && animation[animTarget].label[frameCurrent] == 6) {
2184                     if (!hasvictim) {
2185                         emit_sound_at(knifedrawsound, coords, 128);
2186                     }
2187
2188                     if (victim && hasvictim) {
2189                         XYZ footvel, footpoint;
2190
2191                         emit_sound_at(fleshstabremovesound, coords, 128.);
2192
2193                         footvel = 0;
2194                         footpoint = (weapons[weaponids[weaponactive]].tippoint * .8 + weapons[weaponids[weaponactive]].position * .2);
2195
2196                         if (weapons[weaponids[weaponactive]].getType() == sword) {
2197                             XYZ where, startpoint, endpoint, movepoint;
2198                             float rotationpoint;
2199                             int whichtri;
2200
2201                             where = weapons[weaponids[weaponactive]].position;
2202                             where -= victim->coords;
2203                             if (!victim->skeleton.free)where = DoRotation(where, 0, -victim->yaw, 0);
2204                             startpoint = where;
2205                             where = weapons[weaponids[weaponactive]].tippoint;
2206                             where -= victim->coords;
2207                             if (!victim->skeleton.free)where = DoRotation(where, 0, -victim->yaw, 0);
2208                             endpoint = where;
2209
2210                             movepoint = 0;
2211                             rotationpoint = 0;
2212                             whichtri = victim->skeleton.drawmodel.LineCheck(&startpoint, &endpoint, &footpoint, &movepoint, &rotationpoint);
2213                             footpoint += victim->coords;
2214
2215                             if (whichtri == -1) {
2216                                 footpoint = (weapons[weaponids[weaponactive]].tippoint * .8 + weapons[weaponids[weaponactive]].position * .2);
2217                             }
2218                         }
2219                         if (weapons[weaponids[weaponactive]].getType() == staff) {
2220                             XYZ where, startpoint, endpoint, movepoint;
2221                             float rotationpoint;
2222                             int whichtri;
2223
2224                             where = weapons[weaponids[weaponactive]].position;
2225                             where -= victim->coords;
2226                             if (!victim->skeleton.free)where = DoRotation(where, 0, -victim->yaw, 0);
2227                             startpoint = where;
2228                             where = weapons[weaponids[weaponactive]].tippoint;
2229                             where -= victim->coords;
2230                             if (!victim->skeleton.free)where = DoRotation(where, 0, -victim->yaw, 0);
2231                             endpoint = where;
2232
2233                             movepoint = 0;
2234                             rotationpoint = 0;
2235                             whichtri = victim->skeleton.drawmodel.LineCheck(&startpoint, &endpoint, &footpoint, &movepoint, &rotationpoint);
2236                             footpoint += victim->coords;
2237
2238                             if (whichtri == -1) {
2239                                 footpoint = (weapons[weaponids[weaponactive]].tippoint * .8 + weapons[weaponids[weaponactive]].position * .2);
2240                             }
2241                         }
2242                         hasvictim = victim->DoBloodBigWhere(2, 220, footpoint);
2243                         if (hasvictim) {
2244                             if (distsq(&coords, &victim->coords) < (scale * 5) * (scale * 5) * 3) {
2245                                 victim->skeleton.longdead = 0;
2246                                 victim->skeleton.free = 1;
2247                                 victim->skeleton.broken = 0;
2248
2249                                 for (i = 0; i < victim->skeleton.num_joints; i++) {
2250                                     victim->skeleton.joints[i].velchange = 0;
2251                                     victim->skeleton.joints[i].locked = 0;
2252                                     //victim->skeleton.joints[i].velocity=0;
2253                                 }
2254
2255                                 XYZ relative;
2256                                 relative = 0;
2257                                 relative.y = 10;
2258                                 Normalise(&relative);
2259                                 //victim->Puff(abdomen);
2260                                 if (bloodtoggle)Sprite::MakeSprite(cloudimpactsprite, footpoint, footvel, 1, 0, 0, .8, .3);
2261
2262                                 if (victim->bloodloss < victim->damagetolerance) {
2263                                     victim->bloodloss += 1000;
2264                                     victim->bled = 0;
2265                                 }
2266
2267                                 victim->skeleton.joints[victim->skeleton.jointlabels[abdomen]].velocity += relative * damagemult * 20;
2268                             }
2269                         }
2270                     }
2271                     if (!hasvictim && onterrain) {
2272                         weapons[weaponids[weaponactive]].bloody = 0;
2273                         weapons[weaponids[weaponactive]].blooddrip = 0;
2274                     }
2275                 }
2276
2277                 if (animTarget == upunchanim && animation[animTarget].label[frameCurrent] == 5) {
2278                     if (distsq(&coords, &victim->coords) < (scale * 5) * (scale * 5) * 3) {
2279                         escapednum = 0;
2280                         if (id == 0)camerashake += .4;
2281                         if (Random() % 2) {
2282                             victim->spurt = 1;
2283                             DoBlood(.2, 235);
2284                         }
2285                         if (tutoriallevel != 1) {
2286                             emit_sound_at(heavyimpactsound, victim->coords, 128);
2287                         }
2288
2289                         victim->RagDoll(0);
2290                         XYZ relative;
2291                         relative = victim->coords - coords;
2292                         relative.y = 0;
2293                         Normalise(&relative);
2294                         for (i = 0; i < victim->skeleton.num_joints; i++) {
2295                             victim->skeleton.joints[i].velocity = relative * 30;
2296                         }
2297                         victim->skeleton.joints[victim->skeleton.jointlabels[head]].velocity += relative * damagemult * 150;
2298
2299                         victim->frameTarget = 0;
2300                         victim->animTarget = staggerbackhardanim;
2301                         victim->targetyaw = targetyaw + 180;
2302                         victim->target = 0;
2303                         victim->stunned = 1;
2304
2305                         victim->Puff(head);
2306                         victim->Puff(abdomen);
2307                         victim->DoDamage(damagemult * 60 / victim->protectionhigh);
2308
2309                         SolidHitBonus(id);
2310                     }
2311                 }
2312
2313
2314                 if (animTarget == winduppunchanim && animation[animTarget].label[frameCurrent] == 5) {
2315                     if (distsq(&coords, &victim->coords) < (scale * 5) * (scale * 5) * 2) {
2316                         escapednum = 0;
2317                         if (id == 0)camerashake += .4;
2318                         if (victim->damage <= victim->damagetolerance - 60 && normaldotproduct(victim->facing, victim->coords - coords) < (scale * 5) * (scale * 5) * 0 && animation[victim->animTarget].height != lowheight) {
2319                             if (tutoriallevel != 1) {
2320                                 emit_sound_at(thudsound, victim->coords);
2321                             }
2322                         } else if (victim->damage <= victim->damagetolerance - 60 && normaldotproduct(victim->facing, victim->coords - coords) < (scale * 5) * (scale * 5) * 0 && animation[victim->animTarget].height == lowheight) {
2323                             if (tutoriallevel != 1) {
2324                                 emit_sound_at(whooshhitsound, victim->coords);
2325                             }
2326                         } else {
2327                             if (tutoriallevel != 1) {
2328                                 emit_sound_at(heavyimpactsound, victim->coords);
2329                             }
2330                         }
2331
2332                         if (victim->damage > victim->damagetolerance - 60 || normaldotproduct(victim->facing, victim->coords - coords) > 0 || animation[victim->animTarget].height == lowheight)
2333                             victim->RagDoll(0);
2334                         XYZ relative;
2335                         relative = victim->coords - coords;
2336                         relative.y = 0;
2337                         Normalise(&relative);
2338                         relative.y = .3;
2339                         Normalise(&relative);
2340                         for (i = 0; i < victim->skeleton.num_joints; i++) {
2341                             victim->skeleton.joints[i].velocity = relative * 5;
2342                         }
2343                         victim->skeleton.joints[victim->skeleton.jointlabels[abdomen]].velocity += relative * damagemult * 400;
2344
2345                         victim->frameTarget = 0;
2346                         victim->animTarget = staggerbackhardanim;
2347                         victim->targetyaw = targetyaw + 180;
2348                         victim->target = 0;
2349                         victim->stunned = 1;
2350
2351                         victim->Puff(abdomen);
2352                         victim->DoDamage(damagemult * 60 / victim->protectionhigh);
2353
2354                         SolidHitBonus(id);
2355                     }
2356                 }
2357
2358                 if (animTarget == blockhighleftanim && animation[animTarget].label[frameCurrent] == 5) {
2359                     if (distsq(&coords, &victim->coords) < (scale * 5) * (scale * 5) * 4) {
2360                         if (victim->id == 0)camerashake += .4;
2361                         emit_sound_at(landsound2, victim->coords);
2362
2363                         Puff(righthand);
2364                     }
2365                 }
2366
2367                 if (animTarget == swordslashparryanim && animation[animTarget].label[frameCurrent] == 5) {
2368                     if (distsq(&coords, &victim->coords) < (scale * 5) * (scale * 5) * 4) {
2369                         if (victim->id == 0)camerashake += .4;
2370
2371                         if (weaponactive != -1) {
2372                             if (weapons[victim->weaponids[0]].getType() == staff || weapons[weaponids[0]].getType() == staff) {
2373                                 if (weapons[victim->weaponids[0]].getType() == staff)weapons[victim->weaponids[0]].damage += .2 + float(abs(Random() % 100) - 50) / 250;
2374                                 if (weapons[weaponids[0]].getType() == staff)weapons[weaponids[0]].damage += .2 + float(abs(Random() % 100) - 50) / 250;
2375
2376                                 emit_sound_at(swordstaffsound, victim->coords);
2377                             } else {
2378                                 emit_sound_at(metalhitsound, victim->coords);
2379                             }
2380                         }
2381
2382                         //Puff(righthand);
2383                     }
2384                 }
2385
2386                 if (animTarget == knifethrowanim && animation[animTarget].label[frameCurrent] == 5) {
2387                     if (weaponactive != -1) {
2388                         escapednum = 0;
2389                         XYZ aim;
2390                         weapons[weaponids[0]].owner = -1;
2391                         aim = victim->coords + DoRotation(victim->skeleton.joints[victim->skeleton.jointlabels[abdomen]].position, 0, victim->yaw, 0) * victim->scale + victim->velocity * findDistance(&victim->coords, &coords) / 50 - (coords + DoRotation(skeleton.joints[skeleton.jointlabels[righthand]].position, 0, yaw, 0) * scale);
2392                         Normalise(&aim);
2393                         /*if(victim->animTarget==jumpupanim||victim->animTarget==jumpdownanim){
2394                         aim=DoRotation(aim,(float)abs(Random()%15)-7,(float)abs(Random()%15)-7,0);
2395                         }*/
2396                         weapons[weaponids[0]].velocity = aim * 50;
2397                         weapons[weaponids[0]].tipvelocity = aim * 50;
2398                         weapons[weaponids[0]].missed = 0;
2399                         weapons[weaponids[0]].hitsomething = 0;
2400                         weapons[weaponids[0]].freetime = 0;
2401                         weapons[weaponids[0]].firstfree = 1;
2402                         weapons[weaponids[0]].physics = 0;
2403                         num_weapons--;
2404                         if (num_weapons) {
2405                             weaponids[0] = weaponids[num_weapons];
2406                         }
2407                         weaponactive = -1;
2408                     }
2409                 }
2410
2411                 if (animTarget == knifeslashstartanim && animation[animTarget].label[frameCurrent] == 5) {
2412                     if (hasvictim)
2413                         if (distsq(&coords, &victim->coords) < (scale * 5) * (scale * 5) * 4.5 &&/*animation[victim->animTarget].height!=lowheight&&*/victim->animTarget != dodgebackanim && victim->animTarget != rollanim) {
2414                             escapednum = 0;
2415                             if (tutoriallevel != 1)victim->DoBloodBig(1.5 / victim->armorhigh, 225);
2416
2417                             award_bonus(id, Slicebonus);
2418                             if (tutoriallevel != 1) {
2419                                 emit_sound_at(knifeslicesound, victim->coords);
2420                             }
2421                             //victim->skeleton.joints[victim->skeleton.jointlabels[abdomen]].velocity+=relative*damagemult*200;
2422                             if (animation[victim->animTarget].attack && (victim->aitype != playercontrolled || victim->animTarget == knifeslashstartanim) && (victim->creature == rabbittype || victim->deathbleeding <= 0)) {
2423                                 if (victim->id != 0 || difficulty == 2) {
2424                                     victim->frameTarget = 0;
2425                                     victim->animTarget = staggerbackhardanim;
2426                                     victim->targetyaw = targetyaw + 180;
2427                                     victim->target = 0;
2428                                 }
2429                             }
2430                             victim->lowreversaldelay = 0;
2431                             victim->highreversaldelay = 0;
2432                             if (aitype != playercontrolled)weaponmissdelay = .6;
2433
2434                             if (tutoriallevel != 1)if (bloodtoggle && !weapons[weaponids[weaponactive]].bloody)weapons[weaponids[weaponactive]].bloody = 1;
2435                             if (tutoriallevel != 1)weapons[weaponids[weaponactive]].blooddrip += 3;
2436
2437                             XYZ footvel, footpoint;
2438                             footvel = 0;
2439                             if (skeleton.free) {
2440                                 footpoint = (victim->skeleton.joints[victim->skeleton.jointlabels[abdomen]].position + victim->skeleton.joints[victim->skeleton.jointlabels[neck]].position) / 2 * victim->scale + victim->coords;
2441                             }
2442                             if (!skeleton.free) {
2443                                 footpoint = DoRotation((victim->skeleton.joints[victim->skeleton.jointlabels[abdomen]].position + victim->skeleton.joints[victim->skeleton.jointlabels[neck]].position) / 2, 0, victim->yaw, 0) * victim->scale + victim->coords;
2444                             }
2445                             if (tutoriallevel != 1) {
2446                                 if (bloodtoggle)Sprite::MakeSprite(cloudimpactsprite, footpoint, footvel, 1, 0, 0, .6, .3);
2447                                 footvel = DoRotation(facing, 0, 90, 0) * .8;
2448                                 //footvel.y-=.3;
2449                                 Sprite::MakeSprite(bloodsprite, footpoint, DoRotation(footvel * 7, (float)(Random() % 20), (float)(Random() % 20), 0), 1, 1, 1, .05, .9);
2450                                 Sprite::MakeSprite(bloodsprite, footpoint, DoRotation(footvel * 3, (float)(Random() % 20), (float)(Random() % 20), 0), 1, 1, 1, .05, .9);
2451                                 Sprite::MakeSprite(bloodflamesprite, footpoint, footvel * 5, 1, 1, 1, .2, 1);
2452                                 Sprite::MakeSprite(bloodflamesprite, footpoint, footvel * 2, 1, 1, 1, .2, 1);
2453                             }
2454                             if (tutoriallevel == 1) {
2455                                 Sprite::MakeSprite(cloudimpactsprite, footpoint, footvel, 1, 1, 1, .6, .3);
2456                             }
2457                             victim->DoDamage(damagemult * 0);
2458                         }
2459                 }
2460                 if (animTarget == swordslashanim && animation[animTarget].label[frameCurrent] == 5 && victim->animTarget != rollanim) {
2461                     if (distsq(&coords, &victim->coords) < (scale * 5) * (scale * 5) * 6.5 && victim->animTarget != dodgebackanim) {
2462                         if (victim->weaponactive == -1 || normaldotproduct(victim->facing, victim->coords - coords) > 0 || (Random() % 2 == 0)) {
2463                             award_bonus(id, Slashbonus);
2464                             escapednum = 0;
2465                             if (tutoriallevel != 1) {
2466                                 if (normaldotproduct(victim->facing, victim->coords - coords) < 0)victim->DoBloodBig(2 / victim->armorhigh, 190);
2467                                 else victim->DoBloodBig(2 / victim->armorhigh, 185);
2468                                 victim->deathbleeding = 1;
2469                                 emit_sound_at(swordslicesound, victim->coords);
2470                             }
2471                             //victim->skeleton.joints[victim->skeleton.jointlabels[abdomen]].velocity+=relative*damagemult*200;
2472                             if (tutoriallevel != 1) {
2473                                 victim->frameTarget = 0;
2474                                 victim->animTarget = staggerbackhardanim;
2475                                 victim->targetyaw = targetyaw + 180;
2476                                 victim->target = 0;
2477                             }
2478
2479                             if (tutoriallevel != 1) {
2480                                 if (bloodtoggle && !weapons[weaponids[weaponactive]].bloody)weapons[weaponids[weaponactive]].bloody = 1;
2481                                 weapons[weaponids[weaponactive]].blooddrip += 3;
2482
2483                                 float bloodlossamount;
2484                                 bloodlossamount = 200 + abs((float)(Random() % 40)) - 20;
2485                                 victim->bloodloss += bloodlossamount / victim->armorhigh;
2486                                 //victim->bloodloss+=100*(6.5-distsq(&coords,&victim->coords));
2487                                 victim->DoDamage(damagemult * 0);
2488
2489                                 XYZ footvel, footpoint;
2490                                 footvel = 0;
2491                                 if (skeleton.free) {
2492                                     footpoint = (victim->skeleton.joints[victim->skeleton.jointlabels[abdomen]].position + victim->skeleton.joints[victim->skeleton.jointlabels[neck]].position) / 2 * victim->scale + victim->coords;
2493                                 }
2494                                 if (!skeleton.free) {
2495                                     footpoint = DoRotation((victim->skeleton.joints[victim->skeleton.jointlabels[abdomen]].position + victim->skeleton.joints[victim->skeleton.jointlabels[neck]].position) / 2, 0, victim->yaw, 0) * victim->scale + victim->coords;
2496                                 }
2497                                 if (bloodtoggle)Sprite::MakeSprite(cloudimpactsprite, footpoint, footvel, 1, 0, 0, .9, .3);
2498                                 footvel = DoRotation(facing, 0, 90, 0) * .8;
2499                                 footvel.y -= .3;
2500                                 Sprite::MakeSprite(bloodsprite, footpoint, DoRotation(footvel * 7, (float)(Random() % 20), (float)(Random() % 20), 0), 1, 1, 1, .05, .9);
2501                                 Sprite::MakeSprite(bloodsprite, footpoint, DoRotation(footvel * 3, (float)(Random() % 20), (float)(Random() % 20), 0), 1, 1, 1, .05, .9);
2502                                 Sprite::MakeSprite(bloodflamesprite, footpoint, footvel * 5, 1, 1, 1, .3, 1);
2503                                 Sprite::MakeSprite(bloodflamesprite, footpoint, footvel * 2, 1, 1, 1, .3, 1);
2504                             }
2505                         } else {
2506                             if (victim->weaponactive != -1) {
2507                                 if (weapons[victim->weaponids[0]].getType() == staff || weapons[weaponids[0]].getType() == staff) {
2508                                     if (weapons[victim->weaponids[0]].getType() == staff)weapons[victim->weaponids[0]].damage += .2 + float(abs(Random() % 100) - 50) / 250;
2509                                     if (weapons[weaponids[0]].getType() == staff)weapons[weaponids[0]].damage += .2 + float(abs(Random() % 100) - 50) / 250;
2510
2511                                     emit_sound_at(swordstaffsound, victim->coords);
2512                                 } else {
2513                                     emit_sound_at(metalhitsound, victim->coords);
2514                                 }
2515                             }
2516
2517
2518                             XYZ aim;
2519                             victim->Puff(righthand);
2520                             victim->target = 0;
2521                             victim->frameTarget = 0;
2522                             victim->animTarget = staggerbackhighanim;
2523                             victim->targetyaw = targetyaw + 180;
2524                             victim->target = 0;
2525                             weapons[victim->weaponids[0]].owner = -1;
2526                             aim = DoRotation(facing, 0, 90, 0) * 21;
2527                             aim.y += 7;
2528                             weapons[victim->weaponids[0]].velocity = aim * -.2;
2529                             weapons[victim->weaponids[0]].tipvelocity = aim;
2530                             weapons[victim->weaponids[0]].missed = 1;
2531                             weapons[weaponids[0]].hitsomething = 0;
2532                             weapons[victim->weaponids[0]].freetime = 0;
2533                             weapons[victim->weaponids[0]].firstfree = 1;
2534                             weapons[victim->weaponids[0]].physics = 1;
2535                             victim->num_weapons--;
2536                             if (victim->num_weapons) {
2537                                 victim->weaponids[0] = victim->weaponids[num_weapons];
2538                                 if (victim->weaponstuck == victim->num_weapons)victim->weaponstuck = 0;
2539                             }
2540                             victim->weaponactive = -1;
2541                             for (i = 0; i < numplayers; i++) {
2542                                 player[i].wentforweapon = 0;
2543                             }
2544
2545                         }
2546                     }
2547                 }
2548
2549                 if (animTarget == staffhitanim && animation[animTarget].label[frameCurrent] == 5 && victim->animTarget != rollanim) {
2550                     if (distsq(&coords, &victim->coords) < (scale * 5) * (scale * 5) * 6.5 && victim->animTarget != dodgebackanim && victim->animTarget != sweepanim) {
2551                         if (tutoriallevel != 1) {
2552                             weapons[weaponids[0]].damage += .4 + float(abs(Random() % 100) - 50) / 250;
2553                             escapednum = 0;
2554                             if (id == 0)camerashake += .4;
2555                             if (Random() % 2 || creature == wolftype) {
2556                                 victim->spurt = 1;
2557                             }
2558                             emit_sound_at(staffheadsound, victim->coords);
2559                         }
2560                         victim->RagDoll(0);
2561                         XYZ relative;
2562                         relative = victim->coords - coords;
2563                         relative.y = 0;
2564                         Normalise(&relative);
2565                         relative = DoRotation(relative, 0, 90, 0);
2566                         relative.y -= 1;
2567                         Normalise(&relative);
2568                         for (i = 0; i < victim->skeleton.num_joints; i++) {
2569                             victim->skeleton.joints[i].velocity += relative * damagemult * 60;
2570                         }
2571                         victim->skeleton.joints[victim->skeleton.jointlabels[head]].velocity += relative * damagemult * 230;
2572                         victim->skeleton.joints[victim->skeleton.jointlabels[neck]].velocity += relative * damagemult * 230;
2573                         //FootLand(1,2);
2574                         victim->Puff(head);
2575                         if (tutoriallevel != 1) {
2576                             victim->DoDamage(damagemult * 120 / victim->protectionhigh);
2577
2578                             award_bonus(id, solidhit, 30);
2579                         }
2580                     }
2581                 }
2582
2583                 if (animTarget == staffspinhitanim && animation[animTarget].label[frameCurrent] == 5 && victim->animTarget != rollanim) {
2584                     if (distsq(&coords, &victim->coords) < (scale * 5) * (scale * 5) * 6.5 && victim->animTarget != dodgebackanim && victim->animTarget != sweepanim) {
2585                         if (tutoriallevel != 1) {
2586                             weapons[weaponids[0]].damage += .6 + float(abs(Random() % 100) - 50) / 250;
2587                             escapednum = 0;
2588                             if (id == 0)camerashake += .4;
2589                             if (Random() % 2 || creature == wolftype) {
2590                                 victim->spurt = 1;
2591                             }
2592                             emit_sound_at(staffheadsound, victim->coords);
2593                         }
2594                         victim->RagDoll(0);
2595                         XYZ relative;
2596                         relative = victim->coords - coords;
2597                         relative.y = 0;
2598                         Normalise(&relative);
2599                         relative = DoRotation(relative, 0, -90, 0);
2600                         for (i = 0; i < victim->skeleton.num_joints; i++) {
2601                             victim->skeleton.joints[i].velocity += relative * damagemult * 40;
2602                         }
2603                         victim->skeleton.joints[victim->skeleton.jointlabels[head]].velocity += relative * damagemult * 220;
2604                         victim->skeleton.joints[victim->skeleton.jointlabels[neck]].velocity += relative * damagemult * 220;
2605                         //FootLand(1,2);
2606                         victim->Puff(head);
2607                         if (tutoriallevel != 1) {
2608                             victim->DoDamage(damagemult * 350 / victim->protectionhead);
2609
2610                             award_bonus(id, solidhit, 60);
2611                         }
2612                     }
2613                 }
2614
2615                 if (animTarget == staffgroundsmashanim && animation[animTarget].label[frameCurrent] == 5) {
2616                     if (distsq(&coords, &victim->coords) < (scale * 5) * (scale * 5) * 6.5) {
2617                         escapednum = 0;
2618                         if (tutoriallevel != 1) {
2619                             if (!victim->dead)weapons[weaponids[0]].damage += .4 + float(abs(Random() % 100) - 50) / 500;
2620                             if (id == 0)camerashake += .4;
2621                             if (Random() % 2 || creature == wolftype) {
2622                                 victim->spurt = 1;
2623                             }
2624                             emit_sound_at(staffbodysound, victim->coords);
2625                         }
2626                         victim->skeleton.longdead = 0;
2627                         victim->skeleton.free = 1;
2628                         victim->skeleton.broken = 0;
2629
2630                         for (i = 0; i < victim->skeleton.num_joints; i++) {
2631                             victim->skeleton.joints[i].velchange = 0;
2632                             victim->skeleton.joints[i].locked = 0;
2633                             //victim->skeleton.joints[i].velocity=0;
2634                         }
2635
2636                         victim->RagDoll(0);
2637                         XYZ relative;
2638                         relative = 0;
2639                         /*relative=victim->coords-coords;
2640                         relative.y=0;
2641                         Normalise(&relative);
2642                         relative=DoRotation(relative,0,90,0);*/
2643                         relative.y = -1;
2644                         Normalise(&relative);
2645                         if (!victim->dead) {
2646                             for (i = 0; i < victim->skeleton.num_joints; i++) {
2647                                 victim->skeleton.joints[i].velocity = relative * damagemult * 40;
2648                             }
2649                             //FootLand(1,2);
2650                             victim->skeleton.joints[victim->skeleton.jointlabels[abdomen]].velocity += relative * damagemult * 40;
2651                         }
2652                         if (victim->dead) {
2653                             for (i = 0; i < victim->skeleton.num_joints; i++) {
2654                                 victim->skeleton.joints[i].velocity = relative * damagemult * abs(Random() % 20);
2655                             }
2656                             //FootLand(1,2);
2657                             //victim->skeleton.joints[victim->skeleton.jointlabels[abdomen]].velocity+=relative*damagemult*20;
2658                         }
2659                         victim->Puff(abdomen);
2660                         if (tutoriallevel != 1) {
2661                             victim->DoDamage(damagemult * 100 / victim->protectionhigh);
2662
2663                             if (!victim->dead) {
2664                                 award_bonus(id, solidhit, 40);
2665                             }
2666                         }
2667                     }
2668                 }
2669
2670                 if (animTarget == lowkickanim && animation[animTarget].label[frameCurrent] == 5) {
2671                     if (distsq(&coords, &victim->coords) < (scale * 5) * (scale * 5) * 3 && animation[victim->animTarget].height != highheight) {
2672                         escapednum = 0;
2673                         if (id == 0)camerashake += .4;
2674                         XYZ relative;
2675                         relative = victim->coords - coords;
2676                         relative.y = 0;
2677                         Normalise(&relative);
2678
2679                         SolidHitBonus(id);
2680
2681                         if (animation[victim->animTarget].height == lowheight) {
2682                             if (Random() % 2) {
2683                                 victim->spurt = 1;
2684                                 DoBlood(.2, 250);
2685                             }
2686                             victim->RagDoll(0);
2687                             for (i = 0; i < victim->skeleton.num_joints; i++) {
2688                                 victim->skeleton.joints[i].velocity += relative * damagemult * 40;
2689                             }
2690                             victim->skeleton.joints[victim->skeleton.jointlabels[head]].velocity += relative * damagemult * 200;
2691                             if (tutoriallevel != 1) {
2692                                 emit_sound_at(heavyimpactsound, victim->coords, 128.);
2693                             }
2694                             victim->Puff(head);
2695                             victim->DoDamage(damagemult * 100 / victim->protectionhead);
2696                             if (victim->howactive == typesleeping)victim->DoDamage(damagemult * 150 / victim->protectionhead);
2697                             if (creature == wolftype) {
2698                                 emit_sound_at(clawslicesound, victim->coords, 128.);
2699                                 victim->spurt = 1;
2700                                 victim->DoBloodBig(2 / victim->armorhead, 175);
2701                             }
2702                         } else {
2703                             if (victim->damage >= victim->damagetolerance)victim->RagDoll(0);
2704                             for (i = 0; i < victim->skeleton.num_joints; i++) {
2705                                 victim->skeleton.joints[i].velocity += relative * damagemult * 10;
2706                             }
2707                             victim->skeleton.joints[victim->skeleton.jointlabels[abdomen]].velocity += relative * damagemult * 200;
2708                             victim->frameTarget = 0;
2709                             victim->animTarget = staggerbackhighanim;
2710                             victim->targetyaw = targetyaw + 180;
2711                             victim->target = 0;
2712                             if (tutoriallevel != 1) {
2713                                 emit_sound_at(landsound2, victim->coords, 128.);
2714                             }
2715                             victim->Puff(abdomen);
2716                             victim->DoDamage(damagemult * 30 / victim->protectionhigh);
2717                             if (creature == wolftype) {
2718                                 emit_sound_at(clawslicesound, victim->coords, 128.);
2719                                 victim->spurt = 1;
2720                                 victim->DoBloodBig(2 / victim->armorhigh, 170);
2721                             }
2722                         }
2723
2724                     }
2725                 }
2726
2727                 if (animTarget == sweepanim && animation[animTarget].label[frameCurrent] == 5) {
2728                     if (victim->animTarget != jumpupanim && distsq(&coords, &victim->coords) < (scale * 5) * (scale * 5) * 3 && victim != this) {
2729                         escapednum = 0;
2730                         if (id == 0)camerashake += .2;
2731                         if (tutoriallevel != 1) {
2732                             emit_sound_at(landsound2, victim->coords, 128.);
2733                         }
2734                         XYZ relative;
2735                         relative = victim->coords - coords;
2736                         relative.y = 0;
2737                         Normalise(&relative);
2738
2739                         if (animation[victim->animTarget].height == middleheight || animation[victim->animCurrent].height == middleheight || victim->damage >= victim->damagetolerance - 40) {
2740                             victim->RagDoll(0);
2741
2742                             for (i = 0; i < victim->skeleton.num_joints; i++) {
2743                                 victim->skeleton.joints[i].velocity += relative * damagemult * 15;
2744                             }
2745                             relative = DoRotation(relative, 0, -90, 0);
2746                             relative.y += .1;
2747                             for (i = 0; i < victim->skeleton.num_joints; i++) {
2748                                 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)
2749                                     victim->skeleton.joints[i].velocity = relative * 80;
2750                             }
2751                             victim->Puff(rightankle);
2752                             victim->Puff(leftankle);
2753                             victim->DoDamage(damagemult * 40 / victim->protectionlow);
2754                         } else {
2755                             if (victim->damage >= victim->damagetolerance)victim->RagDoll(0);
2756                             for (i = 0; i < victim->skeleton.num_joints; i++) {
2757                                 victim->skeleton.joints[i].velocity += relative * damagemult * 10;
2758                             }
2759                             relative = DoRotation(relative, 0, -90, 0);
2760                             for (i = 0; i < victim->skeleton.num_joints; i++) {
2761                                 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)
2762                                     victim->skeleton.joints[i].velocity += relative * damagemult * 80;
2763                             }
2764                             victim->skeleton.joints[victim->skeleton.jointlabels[abdomen]].velocity += relative * damagemult * 200;
2765                             victim->frameTarget = 0;
2766                             victim->animTarget = staggerbackhighanim;
2767                             victim->targetyaw = targetyaw + 180;
2768                             victim->target = 0;
2769                             if (tutoriallevel != 1) {
2770                                 emit_sound_at(landsound2, victim->coords, 128.);
2771                             }
2772                             victim->Puff(abdomen);
2773                             victim->DoDamage(damagemult * 30 / victim->protectionlow);
2774                         }
2775
2776                         SolidHitBonus(id);
2777
2778                     }
2779                 }
2780             }
2781             if (animation[animTarget].attack == reversal && (!victim->feint || (victim->lastattack == victim->lastattack2 && victim->lastattack2 == victim->lastattack3 && Random() % 2) || animTarget == knifefollowanim)) {
2782                 if (animTarget == spinkickreversalanim && animation[animTarget].label[frameCurrent] == 7) {
2783                     escapednum = 0;
2784                     if (id == 0)camerashake += .4;
2785                     if (Random() % 2) {
2786                         victim->spurt = 1;
2787                         DoBlood(.2, 230);
2788                     }
2789                     if (tutoriallevel != 1) {
2790                         emit_sound_at(heavyimpactsound, victim->coords, 128.);
2791                     }
2792                     if (creature == wolftype) {
2793                         emit_sound_at(clawslicesound, victim->coords, 128);
2794                         victim->spurt = 1;
2795                         victim->DoBloodBig(2 / victim->armorhigh, 170);
2796                     }
2797                     victim->RagDoll(0);
2798                     XYZ relative;
2799                     relative = victim->coords - oldcoords;
2800                     relative.y = 0;
2801                     Normalise(&relative);
2802                     //relative=DoRotation(relative,0,-90,0);
2803                     for (i = 0; i < victim->skeleton.num_joints; i++) {
2804                         victim->skeleton.joints[i].velocity += relative * damagemult * 40;
2805                     }
2806                     victim->skeleton.joints[victim->skeleton.jointlabels[abdomen]].velocity += relative * damagemult * 200;
2807                     //FootLand(1,2);
2808                     victim->Puff(abdomen);
2809                     victim->DoDamage(damagemult * 150 / victim->protectionhigh);
2810
2811                     award_bonus(id, Reversal);
2812                 }
2813
2814                 if ((animTarget == swordslashreversalanim || animTarget == knifeslashreversalanim || animTarget == staffhitreversalanim || animTarget == staffspinhitreversalanim) && animation[animTarget].label[frameCurrent] == 5) {
2815                     if (victim->weaponactive != -1 && victim->num_weapons > 0) {
2816                         if (weapons[victim->weaponids[victim->weaponactive]].owner == victim->id) {
2817                             weapons[victim->weaponids[victim->weaponactive]].owner = id;
2818                             weaponactive = 0;
2819                             if (num_weapons > 0) {
2820                                 weaponids[num_weapons] = weaponids[victim->weaponactive];
2821                             }
2822                             num_weapons++;
2823                             weaponids[0] = victim->weaponids[victim->weaponactive];
2824                             victim->num_weapons--;
2825                             if (victim->num_weapons > 0) {
2826                                 victim->weaponids[victim->weaponactive] = victim->weaponids[victim->num_weapons];
2827                                 //if(victim->weaponstuck==victim->num_weapons)victim->weaponstuck=0;
2828                             }
2829                             victim->weaponactive = -1;
2830                         }
2831                     }
2832                 }
2833
2834                 if (animTarget == staffhitreversalanim && animation[animTarget].label[frameCurrent] == 5) {
2835                     escapednum = 0;
2836                     if (id == 0)camerashake += .4;
2837                     if (Random() % 2) {
2838                         victim->spurt = 1;
2839                         DoBlood(.2, 230);
2840                     }
2841                     emit_sound_at(whooshhitsound, victim->coords, 128.);
2842                     victim->RagDoll(0);
2843                     XYZ relative;
2844                     relative = victim->coords - oldcoords;
2845                     relative.y = 0;
2846                     Normalise(&relative);
2847                     //relative=DoRotation(relative,0,-90,0);
2848                     for (i = 0; i < victim->skeleton.num_joints; i++) {
2849                         victim->skeleton.joints[i].velocity += relative * damagemult * 30;
2850                     }
2851                     victim->skeleton.joints[victim->skeleton.jointlabels[abdomen]].velocity += relative * damagemult * 200;
2852                     //FootLand(1,2);
2853                     victim->Puff(head);
2854                     victim->DoDamage(damagemult * 70 / victim->protectionhigh);
2855                 }
2856
2857                 if (animTarget == staffspinhitreversalanim && animation[animTarget].label[frameCurrent] == 7) {
2858                     escapednum = 0;
2859                     if (id == 0)camerashake += .4;
2860                     if (Random() % 2) {
2861                         victim->spurt = 1;
2862                         DoBlood(.2, 230);
2863                     }
2864
2865                     award_bonus(id, staffreversebonus);
2866
2867                     if (tutoriallevel != 1) {
2868                         emit_sound_at(heavyimpactsound, victim->coords, 128.);
2869                     }
2870                     victim->RagDoll(0);
2871                     award_bonus(id, staffreversebonus); // Huh, again?
2872
2873                     XYZ relative;
2874                     relative = victim->coords - oldcoords;
2875                     relative.y = 0;
2876                     Normalise(&relative);
2877                     //relative=DoRotation(relative,0,-90,0);
2878                     for (i = 0; i < victim->skeleton.num_joints; i++) {
2879                         victim->skeleton.joints[i].velocity += relative * damagemult * 30;
2880                     }
2881                     victim->skeleton.joints[victim->skeleton.jointlabels[abdomen]].velocity += relative * damagemult * 200;
2882                     //FootLand(1,2);
2883                     victim->Puff(head);
2884                     victim->DoDamage(damagemult * 70 / victim->protectionhigh);
2885                 }
2886
2887                 if (animTarget == upunchreversalanim && animation[animTarget].label[frameCurrent] == 7) {
2888                     escapednum = 0;
2889                     victim->RagDoll(1);
2890                     XYZ relative;
2891                     relative = facing;
2892                     relative.y = 0;
2893                     Normalise(&relative);
2894                     //relative*=-1;
2895                     relative.y -= .1;
2896                     for (i = 0; i < victim->skeleton.num_joints; i++) {
2897                         victim->skeleton.joints[i].velocity += relative * damagemult * 70;
2898                     }
2899                     victim->skeleton.joints[victim->skeleton.jointlabels[lefthand]].velocity *= .1;
2900                     victim->skeleton.joints[victim->skeleton.jointlabels[leftwrist]].velocity *= .2;
2901                     victim->skeleton.joints[victim->skeleton.jointlabels[leftelbow]].velocity *= .5;
2902                     victim->skeleton.joints[victim->skeleton.jointlabels[leftshoulder]].velocity *= .7;
2903                     victim->skeleton.joints[victim->skeleton.jointlabels[righthand]].velocity *= .1;
2904                     victim->skeleton.joints[victim->skeleton.jointlabels[rightwrist]].velocity *= .2;
2905                     victim->skeleton.joints[victim->skeleton.jointlabels[rightelbow]].velocity *= .5;
2906                     victim->skeleton.joints[victim->skeleton.jointlabels[rightshoulder]].velocity *= .7;
2907
2908                     victim->Puff(abdomen);
2909                     victim->DoDamage(damagemult * 90 / victim->protectionhigh);
2910
2911                     award_bonus(id, Reversal);
2912
2913                     bool doslice;
2914                     doslice = 0;
2915                     if (weaponactive != -1 || creature == wolftype)doslice = 1;
2916                     if (creature == rabbittype && weaponactive != -1)if (weapons[weaponids[0]].getType() == staff)doslice = 0;
2917                     if (doslice) {
2918                         if (weaponactive != -1) {
2919                             victim->DoBloodBig(2 / victim->armorhigh, 225);
2920                             emit_sound_at(knifeslicesound, victim->coords);
2921                             if (bloodtoggle && !weapons[weaponids[weaponactive]].bloody)weapons[weaponids[weaponactive]].bloody = 1;
2922                             weapons[weaponids[weaponactive]].blooddrip += 3;
2923                         }
2924                         if (weaponactive == -1 && creature == wolftype) {
2925                             ;
2926                             emit_sound_at(clawslicesound, victim->coords, 128.);
2927                             victim->spurt = 1;
2928                             victim->DoBloodBig(2 / victim->armorhigh, 175);
2929                         }
2930                     }
2931                 }
2932
2933
2934
2935                 if (animTarget == swordslashreversalanim && animation[animTarget].label[frameCurrent] == 7) {
2936                     escapednum = 0;
2937                     victim->RagDoll(1);
2938                     XYZ relative;
2939                     relative = facing;
2940                     relative.y = 0;
2941                     Normalise(&relative);
2942                     //relative*=-1;
2943                     relative.y -= .1;
2944                     for (i = 0; i < victim->skeleton.num_joints; i++) {
2945                         victim->skeleton.joints[i].velocity += relative * damagemult * 70;
2946                     }
2947                     victim->skeleton.joints[victim->skeleton.jointlabels[lefthand]].velocity *= .1 - 1;
2948                     victim->skeleton.joints[victim->skeleton.jointlabels[leftwrist]].velocity *= .2 - 1;
2949                     victim->skeleton.joints[victim->skeleton.jointlabels[leftelbow]].velocity *= .5 - 1;
2950                     victim->skeleton.joints[victim->skeleton.jointlabels[leftshoulder]].velocity *= .7 - 1;
2951                     victim->skeleton.joints[victim->skeleton.jointlabels[righthand]].velocity *= .1 - 1;
2952                     victim->skeleton.joints[victim->skeleton.jointlabels[rightwrist]].velocity *= .2 - 1;
2953                     victim->skeleton.joints[victim->skeleton.jointlabels[rightelbow]].velocity *= .5 - 1;
2954                     victim->skeleton.joints[victim->skeleton.jointlabels[rightshoulder]].velocity *= .7 - 1;
2955
2956                     award_bonus(id, swordreversebonus);
2957                 }
2958
2959                 if (hasvictim && animTarget == knifeslashreversalanim && animation[animTarget].label[frameCurrent] == 7) {
2960                     escapednum = 0;
2961                     if (id == 0)camerashake += .4;
2962                     if (Random() % 2) {
2963                         victim->spurt = 1;
2964                         DoBlood(.2, 230);
2965                     }
2966                     if (tutoriallevel != 1) {
2967                         emit_sound_at(heavyimpactsound, victim->coords, 128.);
2968                     }
2969                     victim->RagDoll(0);
2970                     XYZ relative;
2971                     relative = victim->coords - oldcoords;
2972                     relative.y = 0;
2973                     Normalise(&relative);
2974                     relative = DoRotation(relative, 0, -90, 0);
2975                     for (i = 0; i < victim->skeleton.num_joints; i++) {
2976                         victim->skeleton.joints[i].velocity += relative * damagemult * 40;
2977                     }
2978                     victim->skeleton.joints[victim->skeleton.jointlabels[abdomen]].velocity += relative * damagemult * 200;
2979                     //FootLand(1,2);
2980                     victim->Puff(abdomen);
2981                     victim->DoDamage(damagemult * 30 / victim->protectionhigh);
2982
2983                     award_bonus(id, Reversal);
2984                 }
2985
2986                 if (hasvictim && animTarget == sneakattackanim && animation[animTarget].label[frameCurrent] == 7) {
2987                     escapednum = 0;
2988                     victim->RagDoll(0);
2989                     victim->skeleton.spinny = 0;
2990                     XYZ relative;
2991                     relative = facing * -1;
2992                     relative.y = -3;
2993                     Normalise(&relative);
2994                     if (victim->id == 0)relative /= 30;
2995                     for (i = 0; i < victim->skeleton.num_joints; i++) {
2996                         victim->skeleton.joints[i].velocity += relative * damagemult * 40;
2997                     }
2998                     //victim->DoDamage(1000);
2999                     victim->damage = victim->damagetolerance;
3000                     victim->permanentdamage = victim->damagetolerance - 1;
3001                     bool doslice;
3002                     doslice = 0;
3003                     if (weaponactive != -1 || creature == wolftype)doslice = 1;
3004                     if (creature == rabbittype && weaponactive != -1)if (weapons[weaponids[0]].getType() == staff)doslice = 0;
3005                     if (doslice) {
3006                         if (weaponactive != -1) {
3007                             victim->DoBloodBig(200, 225);
3008                             emit_sound_at(knifeslicesound, victim->coords);
3009                             if (bloodtoggle)weapons[weaponids[weaponactive]].bloody = 2;
3010                             weapons[weaponids[weaponactive]].blooddrip += 5;
3011                         }
3012
3013                         if (creature == wolftype && weaponactive == -1) {
3014                             emit_sound_at(clawslicesound, victim->coords, 128.);
3015                             victim->spurt = 1;
3016                             victim->DoBloodBig(2, 175);
3017                         }
3018                     }
3019                     award_bonus(id, spinecrusher);
3020                 }
3021
3022                 if (hasvictim && (animTarget == knifefollowanim || animTarget == knifesneakattackanim) && animation[animTarget].label[frameCurrent] == 5) {
3023                     if (weaponactive != -1 && victim->bloodloss < victim->damagetolerance) {
3024                         escapednum = 0;
3025                         if (animTarget == knifefollowanim)victim->DoBloodBig(200, 210);
3026                         if (animTarget == knifesneakattackanim) {
3027                             /*victim->DoBloodBig(200,195);
3028                             XYZ bloodvel;
3029                             bloodvel=0;
3030                             bloodvel.z=20;
3031                             bloodvel.y=5;
3032                             bloodvel=DoRotation(bloodvel,((float)(Random()%100))/4,yaw+((float)(Random()%100))/4,0)*scale;
3033                             Sprite::MakeSprite(bloodsprite, DoRotation(skeleton.joints[skeleton.jointlabels[neck]].position,0,yaw,0)*scale+coords,bloodvel, 1,1,1, .05, 1);
3034                             */
3035                             XYZ footvel, footpoint;
3036                             footvel = 0;
3037                             footpoint = weapons[weaponids[0]].tippoint;
3038                             if (bloodtoggle)Sprite::MakeSprite(cloudimpactsprite, footpoint, footvel, 1, 0, 0, .9, .3);
3039                             footvel = (weapons[weaponids[0]].tippoint - weapons[weaponids[0]].position);
3040                             Sprite::MakeSprite(bloodsprite, footpoint, DoRotation(footvel * 7, (float)(Random() % 20), (float)(Random() % 20), 0), 1, 1, 1, .05, .9);
3041                             Sprite::MakeSprite(bloodsprite, footpoint, DoRotation(footvel * 3, (float)(Random() % 20), (float)(Random() % 20), 0), 1, 1, 1, .05, .9);
3042                             Sprite::MakeSprite(bloodflamesprite, footpoint, footvel * 5, 1, 1, 1, .3, 1);
3043                             Sprite::MakeSprite(bloodflamesprite, footpoint, footvel * 2, 1, 1, 1, .3, 1);
3044                             victim->DoBloodBig(200, 195);
3045                             award_bonus(id, tracheotomy);
3046                         }
3047                         if (animTarget == knifefollowanim) {
3048                             award_bonus(id, Stabbonus);
3049                             XYZ footvel, footpoint;
3050                             footvel = 0;
3051                             footpoint = weapons[weaponids[0]].tippoint;
3052                             if (bloodtoggle)Sprite::MakeSprite(cloudimpactsprite, footpoint, footvel, 1, 0, 0, .9, .3);
3053                             footvel = (weapons[weaponids[0]].tippoint - weapons[weaponids[0]].position) * -1;
3054                             Sprite::MakeSprite(bloodsprite, footpoint, DoRotation(footvel * 7, (float)(Random() % 20), (float)(Random() % 20), 0), 1, 1, 1, .05, .9);
3055                             Sprite::MakeSprite(bloodsprite, footpoint, DoRotation(footvel * 3, (float)(Random() % 20), (float)(Random() % 20), 0), 1, 1, 1, .05, .9);
3056                             Sprite::MakeSprite(bloodflamesprite, footpoint, footvel * 5, 1, 1, 1, .2, 1);
3057                             Sprite::MakeSprite(bloodflamesprite, footpoint, footvel * 2, 1, 1, 1, .2, 1);
3058
3059                         }
3060                         victim->bloodloss += 10000;
3061                         victim->velocity = 0;
3062                         emit_sound_at(fleshstabsound, victim->coords);
3063                         if (bloodtoggle)weapons[weaponids[weaponactive]].bloody = 2;
3064                         weapons[weaponids[weaponactive]].blooddrip += 5;
3065                     }
3066                 }
3067
3068                 if (hasvictim && (animTarget == knifefollowanim || animTarget == knifesneakattackanim) && animation[animTarget].label[frameCurrent] == 6) {
3069                     escapednum = 0;
3070                     victim->velocity = 0;
3071                     for (i = 0; i < victim->skeleton.num_joints; i++) {
3072                         victim->skeleton.joints[i].velocity = 0;
3073                     }
3074                     if (animTarget == knifefollowanim) {
3075                         victim->RagDoll(0);
3076                         for (i = 0; i < victim->skeleton.num_joints; i++) {
3077                             victim->skeleton.joints[i].velocity = 0;
3078                         }
3079                     }
3080                     if (weaponactive != -1 && animation[victim->animTarget].attack != reversal) {
3081                         emit_sound_at(fleshstabremovesound, victim->coords);
3082                         if (bloodtoggle)weapons[weaponids[weaponactive]].bloody = 2;
3083                         weapons[weaponids[weaponactive]].blooddrip += 5;
3084
3085                         XYZ footvel, footpoint;
3086                         footvel = 0;
3087                         footpoint = weapons[weaponids[0]].tippoint;
3088                         if (bloodtoggle)Sprite::MakeSprite(cloudimpactsprite, footpoint, footvel, 1, 0, 0, .9, .3);
3089                         footvel = (weapons[weaponids[0]].tippoint - weapons[weaponids[0]].position) * -1;
3090                         Sprite::MakeSprite(bloodsprite, footpoint, DoRotation(footvel * 7, (float)(Random() % 20), (float)(Random() % 20), 0), 1, 1, 1, .05, .9);
3091                         Sprite::MakeSprite(bloodsprite, footpoint, DoRotation(footvel * 3, (float)(Random() % 20), (float)(Random() % 20), 0), 1, 1, 1, .05, .9);
3092                         Sprite::MakeSprite(bloodflamesprite, footpoint, footvel * 5, 1, 1, 1, .3, 1);
3093                         Sprite::MakeSprite(bloodflamesprite, footpoint, footvel * 2, 1, 1, 1, .3, 1);
3094                     }
3095                 }
3096
3097                 if (hasvictim && (animTarget == swordsneakattackanim) && animation[animTarget].label[frameCurrent] == 5) {
3098                     if (weaponactive != -1 && victim->bloodloss < victim->damagetolerance) {
3099                         award_bonus(id, backstab);
3100
3101                         escapednum = 0;
3102
3103                         XYZ footvel, footpoint;
3104                         footvel = 0;
3105                         footpoint = (weapons[weaponids[0]].tippoint + weapons[weaponids[0]].position) / 2;
3106                         if (bloodtoggle)Sprite::MakeSprite(cloudimpactsprite, footpoint, footvel, 1, 0, 0, .9, .3);
3107                         footvel = (weapons[weaponids[0]].tippoint - weapons[weaponids[0]].position);
3108                         Sprite::MakeSprite(bloodsprite, footpoint, DoRotation(footvel * 7, (float)(Random() % 20), (float)(Random() % 20), 0), 1, 1, 1, .05, .9);
3109                         Sprite::MakeSprite(bloodsprite, footpoint, DoRotation(footvel * 3, (float)(Random() % 20), (float)(Random() % 20), 0), 1, 1, 1, .05, .9);
3110                         Sprite::MakeSprite(bloodflamesprite, footpoint, DoRotation(footvel * 5, (float)(Random() % 20), (float)(Random() % 20), 0), 1, 1, 1, .3, 1);
3111                         Sprite::MakeSprite(bloodflamesprite, footpoint, DoRotation(footvel * 3, (float)(Random() % 20), (float)(Random() % 20), 0), 1, 1, 1, .3, 1);
3112                         victim->DoBloodBig(200, 180);
3113                         victim->DoBloodBig(200, 215);
3114                         victim->bloodloss += 10000;
3115                         victim->velocity = 0;
3116                         emit_sound_at(fleshstabsound, victim->coords);
3117                         if (bloodtoggle)weapons[weaponids[weaponactive]].bloody = 2;
3118                         weapons[weaponids[weaponactive]].blooddrip += 5;
3119                     }
3120                 }
3121
3122                 if (hasvictim && animTarget == swordsneakattackanim && animation[animTarget].label[frameCurrent] == 6) {
3123                     escapednum = 0;
3124                     victim->velocity = 0;
3125                     for (i = 0; i < victim->skeleton.num_joints; i++) {
3126                         victim->skeleton.joints[i].velocity = 0;
3127                     }
3128                     if (weaponactive != -1) {
3129                         emit_sound_at(fleshstabremovesound, victim->coords);
3130                         if (bloodtoggle)weapons[weaponids[weaponactive]].bloody = 2;
3131                         weapons[weaponids[weaponactive]].blooddrip += 5;
3132
3133                         XYZ footvel, footpoint;
3134                         footvel = 0;
3135                         footpoint = weapons[weaponids[0]].tippoint;
3136                         if (bloodtoggle)Sprite::MakeSprite(cloudimpactsprite, footpoint, footvel, 1, 0, 0, .9, .3);
3137                         footvel = (weapons[weaponids[0]].tippoint - weapons[weaponids[0]].position) * -1;
3138                         Sprite::MakeSprite(bloodsprite, footpoint, DoRotation(footvel * 7, (float)(Random() % 20), (float)(Random() % 20), 0), 1, 1, 1, .05, .9);
3139                         Sprite::MakeSprite(bloodsprite, footpoint, DoRotation(footvel * 3, (float)(Random() % 20), (float)(Random() % 20), 0), 1, 1, 1, .05, .9);
3140                         Sprite::MakeSprite(bloodflamesprite, footpoint, footvel * 5, 1, 1, 1, .3, 1);
3141                         Sprite::MakeSprite(bloodflamesprite, footpoint, footvel * 2, 1, 1, 1, .3, 1);
3142                     }
3143                 }
3144
3145                 if (animTarget == sweepreversalanim && animation[animTarget].label[frameCurrent] == 7) {
3146                     escapednum = 0;
3147                     if (id == 0)camerashake += .4;
3148                     if (Random() % 2) {
3149                         victim->spurt = 1;
3150                         DoBlood(.2, 240);
3151                     }
3152                     if (weaponactive == -1) {
3153                         if (tutoriallevel != 1) {
3154                             emit_sound_at(heavyimpactsound, victim->coords, 128.);
3155                         }
3156                     }
3157                     bool doslice;
3158                     doslice = 0;
3159                     if (weaponactive != -1 || creature == wolftype)doslice = 1;
3160                     if (creature == rabbittype && weaponactive != -1)if (weapons[weaponids[0]].getType() == staff)doslice = 0;
3161                     if (doslice) {
3162                         if (weaponactive != -1) {
3163                             victim->DoBloodBig(2 / victim->armorhead, 225);
3164                             emit_sound_at(knifeslicesound, victim->coords);
3165                             if (bloodtoggle && !weapons[weaponids[weaponactive]].bloody)weapons[weaponids[weaponactive]].bloody = 1;
3166                             weapons[weaponids[weaponactive]].blooddrip += 3;
3167                         }
3168                         if (weaponactive == -1 && creature == wolftype) {
3169                             emit_sound_at(clawslicesound, victim->coords, 128.);
3170                             victim->spurt = 1;
3171                             victim->DoBloodBig(2 / victim->armorhead, 175);
3172                         }
3173                     }
3174
3175                     award_bonus(id, Reversal);
3176
3177                     victim->Puff(neck);
3178
3179                     XYZ relative;
3180                     //relative=victim->coords-oldcoords;
3181                     relative = facing * -1;
3182                     relative.y = 0;
3183                     Normalise(&relative);
3184                     relative = DoRotation(relative, 0, 90, 0);
3185                     relative.y = .5;
3186                     Normalise(&relative);
3187                     for (i = 0; i < victim->skeleton.num_joints; i++) {
3188                         victim->skeleton.joints[i].velocity += relative * damagemult * 20;
3189                     }
3190                     victim->skeleton.joints[victim->skeleton.jointlabels[head]].velocity += relative * damagemult * 200;
3191                     if (victim->damage < victim->damagetolerance - 100)victim->velocity = relative * 200;
3192                     victim->DoDamage(damagemult * 100 / victim->protectionhead);
3193                     victim->velocity = 0;
3194                 }
3195
3196                 if (animTarget == sweepreversalanim && ((animation[animTarget].label[frameCurrent] == 9 && victim->damage < victim->damagetolerance) || (animation[animTarget].label[frameCurrent] == 7 && victim->damage > victim->damagetolerance))) {
3197                     escapednum = 0;
3198                     victim->RagDoll(0);
3199                     XYZ relative;
3200                     //relative=victim->coords-oldcoords;
3201                     relative = facing * -1;
3202                     relative.y = 0;
3203                     Normalise(&relative);
3204                     relative = DoRotation(relative, 0, 90, 0);
3205                     relative.y = .5;
3206                     Normalise(&relative);
3207                     for (i = 0; i < victim->skeleton.num_joints; i++) {
3208                         victim->skeleton.joints[i].velocity += relative * damagemult * 20;
3209                     }
3210                     victim->skeleton.joints[victim->skeleton.jointlabels[head]].velocity += relative * damagemult * 200;
3211                 }
3212
3213                 if (hasvictim && (animTarget == spinkickreversalanim || animTarget == sweepreversalanim || animTarget == rabbitkickreversalanim || animTarget == upunchreversalanim || animTarget == jumpreversalanim || animTarget == swordslashreversalanim || animTarget == knifeslashreversalanim || animTarget == rabbittacklereversal || animTarget == wolftacklereversal || animTarget == staffhitreversalanim || animTarget == staffspinhitreversalanim))
3214                     if (victim->damage > victim->damagetolerance && bonus != reverseko) {
3215                         award_bonus(id, reverseko);
3216                     }
3217             }
3218
3219
3220             //Animation end
3221             if (frameTarget > animation[animCurrent].numframes - 1) {
3222                 frameTarget = 0;
3223                 if (wasStop()) {
3224                     animTarget = getIdle();
3225                     FootLand(0, 1);
3226                     FootLand(1, 1);
3227                 }
3228                 if (animCurrent == rabbittackleanim || animCurrent == rabbittacklinganim) {
3229                     animTarget = rollanim;
3230                     frameTarget = 3;
3231                     emit_sound_at(movewhooshsound, coords, 128.);
3232                 }
3233                 if (animCurrent == staggerbackhighanim) {
3234                     animTarget = getIdle();
3235                 }
3236                 if (animCurrent == staggerbackhardanim) {
3237                     animTarget = getIdle();
3238                 }
3239                 if (animCurrent == removeknifeanim) {
3240                     animTarget = getIdle();
3241                 }
3242                 if (animCurrent == crouchremoveknifeanim) {
3243                     animTarget = getCrouch();
3244                 }
3245                 if (animCurrent == backhandspringanim) {
3246                     animTarget = getIdle();
3247                 }
3248                 if (animCurrent == dodgebackanim) {
3249                     animTarget = getIdle();
3250                 }
3251                 if (animCurrent == drawleftanim) {
3252                     animTarget = getIdle();
3253                 }
3254                 if (animCurrent == drawrightanim || animCurrent == crouchdrawrightanim) {
3255                     animTarget = getIdle();
3256                     if (animCurrent == crouchdrawrightanim) {
3257                         animTarget = getCrouch();
3258                     }
3259                     if (weaponactive == -1)weaponactive = 0;
3260                     else if (weaponactive == 0) {
3261                         weaponactive = -1;
3262                         if (num_weapons == 2) {
3263                             int buffer;
3264                             buffer = weaponids[0];
3265                             weaponids[0] = weaponids[1];
3266                             weaponids[1] = buffer;
3267                         }
3268                     }
3269
3270                     if (weaponactive == -1) {
3271                         emit_sound_at(knifesheathesound, coords, 128.);
3272                     }
3273                     if (weaponactive != -1) {
3274                         emit_sound_at(knifedrawsound, coords, 128.);
3275                     }
3276                 }
3277                 if (animCurrent == rollanim) {
3278                     animTarget = getCrouch();
3279                     FootLand(0, 1);
3280                     FootLand(1, 1);
3281                 }
3282                 if (isFlip()) {
3283                     if (animTarget == walljumprightkickanim) {
3284                         targetrot = -190;
3285                     }
3286                     if (animTarget == walljumpleftkickanim) {
3287                         targetrot = 190;
3288                     }
3289                     animTarget = jumpdownanim;
3290                 }
3291                 if (animCurrent == climbanim) {
3292                     animTarget = getCrouch();
3293                     frameTarget = 1;
3294                     coords += facing * .1;
3295                     if (!isnormal(coords.x))
3296                         coords = oldcoords;
3297                     oldcoords = coords;
3298                     collided = 0;
3299                     targetoffset = 0;
3300                     currentoffset = 0;
3301                     grabdelay = 1;
3302                     velocity = 0;
3303                     collided = 0;
3304                     avoidcollided = 0;
3305                 }
3306                 if (animTarget == rabbitkickreversalanim) {
3307                     animTarget = getCrouch();
3308                     lastfeint = 0;
3309                 }
3310                 if (animTarget == jumpreversalanim) {
3311                     animTarget = getCrouch();
3312                     lastfeint = 0;
3313                 }
3314                 if (animTarget == walljumprightanim || animTarget == walljumpbackanim || animTarget == walljumpfrontanim) {
3315                     if (attackkeydown && animTarget != walljumpfrontanim) {
3316                         int closest = -1;
3317                         float closestdist = -1;
3318                         float distance;
3319                         if (numplayers > 1)
3320                             for (i = 0; i < numplayers; i++) {
3321                                 if (id != i && player[i].coords.y < coords.y && !player[i].skeleton.free) {
3322                                     distance = distsq(&player[i].coords, &coords);
3323                                     if (closestdist == -1 || distance < closestdist) {
3324                                         closestdist = distance;
3325                                         closest = i;
3326                                     }
3327                                 }
3328                             }
3329                         if (closestdist > 0 && closest >= 0 && closestdist < 16) {
3330                             victim = &player[closest];
3331                             animTarget = walljumprightkickanim;
3332                             frameTarget = 0;
3333                             XYZ rotatetarget = victim->coords - coords;
3334                             Normalise(&rotatetarget);
3335                             yaw = -asin(0 - rotatetarget.x);
3336                             yaw *= 360 / 6.28;
3337                             if (rotatetarget.z < 0)yaw = 180 - yaw;
3338                             targettilt2 = -asin(rotatetarget.y) * 360 / 6.28;
3339                             velocity = (victim->coords - coords) * 4;
3340                             velocity.y += 2;
3341                             transspeed = 40;
3342                         }
3343                     }
3344                     if (animTarget == walljumpbackanim) {
3345                         animTarget = backflipanim;
3346                         frameTarget = 3;
3347                         velocity = facing * -8;
3348                         velocity.y = 4;
3349                         if (id == 0)
3350                             resume_stream(whooshsound);
3351                     }
3352                     if (animTarget == walljumprightanim) {
3353                         animTarget = rightflipanim;
3354                         frameTarget = 4;
3355                         targetyaw -= 90;
3356                         yaw -= 90;
3357                         velocity = DoRotation(facing, 0, 30, 0) * -8;
3358                         velocity.y = 4;
3359                     }
3360                     if (animTarget == walljumpfrontanim) {
3361                         animTarget = frontflipanim;
3362                         frameTarget = 2;
3363                         //targetyaw-=180;
3364                         ////yaw-=180;
3365                         velocity = facing * 8;
3366                         velocity.y = 4;
3367                     }
3368                     if (id == 0)
3369                         resume_stream(whooshsound);
3370                 }
3371                 if (animTarget == walljumpleftanim) {
3372                     if (attackkeydown) {
3373                         int closest = -1;
3374                         float closestdist = -1;
3375                         float distance;
3376                         if (numplayers > 1)
3377                             for (i = 0; i < numplayers; i++) {
3378                                 if (id != i && player[i].coords.y < coords.y && !player[i].skeleton.free) {
3379                                     distance = distsq(&player[i].coords, &coords);
3380                                     if (closestdist == -1 || distance < closestdist) {
3381                                         closestdist = distance;
3382                                         closest = i;
3383                                     }
3384                                 }
3385                             }
3386                         if (closestdist > 0 && closest >= 0 && closestdist < 16) {
3387                             victim = &player[closest];
3388                             animTarget = walljumpleftkickanim;
3389                             frameTarget = 0;
3390                             XYZ rotatetarget = victim->coords - coords;
3391                             Normalise(&rotatetarget);
3392                             yaw = -asin(0 - rotatetarget.x);
3393                             yaw *= 360 / 6.28;
3394                             if (rotatetarget.z < 0)yaw = 180 - yaw;
3395                             targettilt2 = -asin(rotatetarget.y) * 360 / 6.28;
3396                             velocity = (victim->coords - coords) * 4;
3397                             velocity.y += 2;
3398                             transspeed = 40;
3399                         }
3400                     }
3401                     if (animTarget != walljumpleftkickanim) {
3402                         animTarget = leftflipanim;
3403                         frameTarget = 4;
3404                         targetyaw += 90;
3405                         yaw += 90;
3406                         velocity = DoRotation(facing, 0, -30, 0) * -8;
3407                         velocity.y = 4;
3408                     }
3409                     if (id == 0)
3410                         resume_stream(whooshsound);
3411                 }
3412                 if (animTarget == sneakattackanim) {
3413                     animCurrent = getCrouch();
3414                     animTarget = getCrouch();
3415                     frameTarget = 1;
3416                     frameCurrent = 0;
3417                     targetyaw += 180;
3418                     yaw += 180;
3419                     targettilt2 *= -1;
3420                     tilt2 *= -1;
3421                     transspeed = 1000000;
3422                     targetheadyaw += 180;
3423                     coords -= facing * .7;
3424                     if (onterrain)coords.y = terrain.getHeight(coords.x, coords.z);
3425
3426                     lastfeint = 0;
3427                 }
3428                 if (animTarget == knifesneakattackanim || animTarget == swordsneakattackanim) {
3429                     animTarget = getIdle();
3430                     frameTarget = 0;
3431                     if (onterrain)coords.y = terrain.getHeight(coords.x, coords.z);
3432
3433                     lastfeint = 0;
3434                 }
3435                 if (animCurrent == knifefollowanim) {
3436                     animTarget = getIdle();
3437                     lastfeint = 0;
3438                 }
3439                 if (animation[animTarget].attack == reversal && animCurrent != sneakattackanim && animCurrent != knifesneakattackanim && animCurrent != swordsneakattackanim && animCurrent != knifefollowanim) {
3440                     float ycoords = oldcoords.y;
3441                     animTarget = getStop();
3442                     targetyaw += 180;
3443                     yaw += 180;
3444                     targettilt2 *= -1;
3445                     tilt2 *= -1;
3446                     transspeed = 1000000;
3447                     targetheadyaw += 180;
3448                     if (!isnormal(coords.x))
3449                         coords = oldcoords;
3450                     if (animCurrent == spinkickreversalanim || animCurrent == swordslashreversalanim)
3451                         oldcoords = coords + facing * .5;
3452                     else if (animCurrent == sweepreversalanim)
3453                         oldcoords = coords + facing * 1.1;
3454                     else if (animCurrent == upunchreversalanim) {
3455                         oldcoords = coords + facing * 1.5;
3456                         targetyaw += 180;
3457                         yaw += 180;
3458                         targetheadyaw += 180;
3459                         targettilt2 *= -1;
3460                         tilt2 *= -1;
3461                     } else if (animCurrent == knifeslashreversalanim) {
3462                         oldcoords = coords + facing * .5;
3463                         targetyaw += 90;
3464                         yaw += 90;
3465                         targetheadyaw += 90;
3466                         targettilt2 = 0;
3467                         tilt2 = 0;
3468                     } else if (animCurrent == staffspinhitreversalanim) {
3469                         targetyaw += 180;
3470                         yaw += 180;
3471                         targetheadyaw += 180;
3472                         targettilt2 = 0;
3473                         tilt2 = 0;
3474                     }
3475                     if (onterrain)oldcoords.y = terrain.getHeight(oldcoords.x, oldcoords.z);
3476                     else oldcoords.y = ycoords;
3477                     currentoffset = coords - oldcoords;
3478                     targetoffset = 0;
3479                     coords = oldcoords;
3480
3481                     lastfeint = 0;
3482                 }
3483                 if (animCurrent == knifesneakattackedanim || animCurrent == swordsneakattackedanim) {
3484                     velocity = 0;
3485                     velocity.y = -5;
3486                     RagDoll(0);
3487                 }
3488                 if (animation[animTarget].attack == reversed) {
3489                     escapednum++;
3490                     if (animTarget == sweepreversedanim)targetyaw += 90;
3491                     animTarget = backhandspringanim;
3492                     frameTarget = 2;
3493                     emit_sound_at(landsound, coords, 128);
3494
3495                     if (animCurrent == upunchreversedanim || animCurrent == swordslashreversedanim) {
3496                         animTarget = rollanim;
3497                         frameTarget = 5;
3498                         oldcoords = coords;
3499                         coords += (DoRotation(skeleton.joints[skeleton.jointlabels[leftfoot]].position, 0, yaw, 0) + DoRotation(skeleton.joints[skeleton.jointlabels[rightfoot]].position, 0, yaw, 0)) / 2 * scale;
3500                         coords.y = oldcoords.y;
3501                     }
3502                     if (animCurrent == knifeslashreversedanim) {
3503                         animTarget = rollanim;
3504                         frameTarget = 0;
3505                         targetyaw += 90;
3506                         yaw += 90;
3507                         oldcoords = coords;
3508                         coords += (DoRotation(skeleton.joints[skeleton.jointlabels[leftfoot]].position, 0, yaw, 0) + DoRotation(skeleton.joints[skeleton.jointlabels[rightfoot]].position, 0, yaw, 0)) / 2 * scale;
3509                         coords.y = oldcoords.y;
3510                     }
3511                 }
3512                 if (wasFlip()) {
3513                     animTarget = jumpdownanim;
3514                 }
3515                 if (wasLanding())animTarget = getIdle();
3516                 if (wasLandhard())animTarget = getIdle();
3517                 if (animCurrent == spinkickanim || animCurrent == getupfrombackanim || animCurrent == getupfromfrontanim || animCurrent == lowkickanim) {
3518                     animTarget = getIdle();
3519                     oldcoords = coords;
3520                     coords += (DoRotation(skeleton.joints[skeleton.jointlabels[leftfoot]].position, 0, yaw, 0) + DoRotation(skeleton.joints[skeleton.jointlabels[rightfoot]].position, 0, yaw, 0)) / 2 * scale;
3521                     coords.y = oldcoords.y;
3522                     //coords+=DoRotation(animation[animCurrent].offset,0,yaw,0)*scale;
3523                     targetoffset.y = coords.y;
3524                     if (onterrain)targetoffset.y = terrain.getHeight(coords.x, coords.z);
3525                     currentoffset = DoRotation(animation[animCurrent].offset * -1, 0, yaw, 0) * scale;
3526                     currentoffset.y -= (coords.y - targetoffset.y);
3527                     coords.y = targetoffset.y;
3528                     targetoffset = 0;
3529                     normalsupdatedelay = 0;
3530                 }
3531                 if (animCurrent == upunchanim) {
3532                     animTarget = getStop();
3533                     normalsupdatedelay = 0;
3534                     lastfeint = 0;
3535                 }
3536                 if (animCurrent == rabbitkickanim && animTarget != backflipanim) {
3537                     targetyaw = yaw;
3538                     bool hasstaff;
3539                     hasstaff = 0;
3540                     if (num_weapons > 0)if (weapons[0].getType() == staff)hasstaff = 1;
3541                     if (!hasstaff)DoDamage(35);
3542                     RagDoll(0);
3543                     lastfeint = 0;
3544                     rabbitkickragdoll = 1;
3545                 }
3546                 if (animCurrent == rabbitkickreversedanim) {
3547                     if (!feint) {
3548                         velocity = 0;
3549                         velocity.y = -10;
3550                         //DoDamage(100);
3551                         RagDoll(0);
3552                         skeleton.spinny = 0;
3553                         SolidHitBonus(!id); // FIXME: tricky id
3554                     }
3555                     if (feint) {
3556                         escapednum++;
3557                         animTarget = rollanim;
3558                         coords += facing;
3559                         if (id == 0)pause_sound(whooshsound);
3560                     }
3561                     lastfeint = 0;
3562                 }
3563                 if (animCurrent == rabbittackledbackanim || animCurrent == rabbittackledfrontanim) {
3564                     velocity = 0;
3565                     velocity.y = -10;
3566                     RagDoll(0);
3567                     skeleton.spinny = 0;
3568                 }
3569                 if (animCurrent == jumpreversedanim) {
3570                     if (!feint) {
3571                         velocity = 0;
3572                         velocity.y = -10;
3573                         //DoDamage(100);
3574                         RagDoll(0);
3575                         skeleton.spinny = 0;
3576                         SolidHitBonus(!id); // FIXME: tricky id
3577                     }
3578                     if (feint) {
3579                         escapednum++;
3580                         animTarget = rollanim;
3581                         coords += facing * 2;
3582                         if (id == 0)pause_sound(whooshsound);
3583                     }
3584                     lastfeint = 0;
3585                 }
3586
3587                 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) {
3588                     animTarget = getupfromfrontanim;
3589                     lastfeint = 0;
3590                 } else if (animation[animCurrent].attack == normalattack) {
3591                     animTarget = getIdle();
3592                     lastfeint = 0;
3593                 }
3594                 if (animCurrent == blockhighleftanim && aitype != playercontrolled) {
3595                     animTarget = blockhighleftstrikeanim;
3596                 }
3597                 if (animCurrent == knifeslashstartanim || animCurrent == knifethrowanim || animCurrent == swordslashanim || animCurrent == staffhitanim || animCurrent == staffgroundsmashanim || animCurrent == staffspinhitanim) {
3598                     animTarget = getIdle();
3599                     lastfeint = 0;
3600                 }
3601                 if (animCurrent == spinkickanim && victim->skeleton.free) {
3602                     if (creature == rabbittype)animTarget = fightidleanim;
3603                 }
3604             }
3605             target = 0;
3606
3607             if (isIdle() && !wasIdle())normalsupdatedelay = 0;
3608
3609             if (animCurrent == jumpupanim && velocity.y < 0 && !isFlip()) {
3610                 animTarget = jumpdownanim;
3611             }
3612         }
3613         if (!skeleton.free) {
3614             oldtarget = target;
3615             if (!transspeed && animation[animTarget].attack != 2 && animation[animTarget].attack != 3) {
3616                 if (!isRun() || !wasRun()) {
3617                     if (animation[animTarget].speed[frameTarget] > animation[animCurrent].speed[frameCurrent])
3618                         target += multiplier * animation[animTarget].speed[frameTarget] * speed * 2;
3619                     if (animation[animTarget].speed[frameTarget] <= animation[animCurrent].speed[frameCurrent])
3620                         target += multiplier * animation[animCurrent].speed[frameCurrent] * speed * 2;
3621                 }
3622                 if (isRun() && wasRun()) {
3623                     float tempspeed;
3624                     tempspeed = velspeed;
3625                     if (tempspeed < 10 * speedmult)tempspeed = 10 * speedmult;
3626                     target += multiplier * animation[animTarget].speed[frameCurrent] * speed * 1.7 * tempspeed / (speed * 45 * scale);
3627                 }
3628             } else if (transspeed)target += multiplier * transspeed * speed * 2;
3629             else {
3630                 if (!isRun() || !wasRun()) {
3631                     if (animation[animTarget].speed[frameTarget] > animation[animCurrent].speed[frameCurrent])
3632                         target += multiplier * animation[animTarget].speed[frameTarget] * 2;
3633                     if (animation[animTarget].speed[frameTarget] <= animation[animCurrent].speed[frameCurrent])
3634                         target += multiplier * animation[animCurrent].speed[frameCurrent] * 2;
3635                 }
3636             }
3637
3638             if (animCurrent != animTarget)target = (target + oldtarget) / 2;
3639
3640             if (target > 1) {
3641                 frameCurrent = frameTarget;
3642                 target = 1;
3643             }
3644             oldrot = rot;
3645             rot = targetrot * target;
3646             yaw += rot - oldrot;
3647             if (target == 1) {
3648                 rot = 0;
3649                 oldrot = 0;
3650                 targetrot = 0;
3651             }
3652             if (animCurrent != oldanimCurrent || animTarget != oldanimTarget || ((frameCurrent != oldframeCurrent || frameTarget != oldframeTarget) && !calcrot)) {
3653                 //Old rotates
3654                 for (i = 0; i < skeleton.num_joints; i++) {
3655                     skeleton.joints[i].position = animation[animCurrent].position[i][frameCurrent];
3656                 }
3657
3658                 skeleton.FindForwards();
3659
3660                 for (i = 0; i < skeleton.num_muscles; i++) {
3661                     if (skeleton.muscles[i].visible) {
3662                         skeleton.FindRotationMuscle(i, animTarget);
3663                     }
3664                 }
3665                 for (i = 0; i < skeleton.num_muscles; i++) {
3666                     if (skeleton.muscles[i].visible) {
3667                         if (isnormal((float)((int)(skeleton.muscles[i].rotate1 * 100) % 36000) / 100))skeleton.muscles[i].oldrotate1 = (float)((int)(skeleton.muscles[i].rotate1 * 100) % 36000) / 100;
3668                         if (isnormal((float)((int)(skeleton.muscles[i].rotate2 * 100) % 36000) / 100))skeleton.muscles[i].oldrotate2 = (float)((int)(skeleton.muscles[i].rotate2 * 100) % 36000) / 100;
3669                         if (isnormal((float)((int)(skeleton.muscles[i].rotate3 * 100) % 36000) / 100))skeleton.muscles[i].oldrotate3 = (float)((int)(skeleton.muscles[i].rotate3 * 100) % 36000) / 100;
3670                     }
3671                 }
3672
3673                 //New rotates
3674                 for (i = 0; i < skeleton.num_joints; i++) {
3675                     skeleton.joints[i].position = animation[animTarget].position[i][frameTarget];
3676                 }
3677
3678                 skeleton.FindForwards();
3679
3680                 for (i = 0; i < skeleton.num_muscles; i++) {
3681                     if (skeleton.muscles[i].visible) {
3682                         skeleton.FindRotationMuscle(i, animTarget);
3683                     }
3684                 }
3685                 for (i = 0; i < skeleton.num_muscles; i++) {
3686                     if (skeleton.muscles[i].visible) {
3687                         if (isnormal((float)((int)(skeleton.muscles[i].rotate1 * 100) % 36000) / 100))skeleton.muscles[i].newrotate1 = (float)((int)(skeleton.muscles[i].rotate1 * 100) % 36000) / 100;
3688                         if (isnormal((float)((int)(skeleton.muscles[i].rotate2 * 100) % 36000) / 100))skeleton.muscles[i].newrotate2 = (float)((int)(skeleton.muscles[i].rotate2 * 100) % 36000) / 100;
3689                         if (isnormal((float)((int)(skeleton.muscles[i].rotate3 * 100) % 36000) / 100))skeleton.muscles[i].newrotate3 = (float)((int)(skeleton.muscles[i].rotate3 * 100) % 36000) / 100;
3690                         if (skeleton.muscles[i].newrotate3 > skeleton.muscles[i].oldrotate3 + 180)skeleton.muscles[i].newrotate3 -= 360;
3691                         if (skeleton.muscles[i].newrotate3 < skeleton.muscles[i].oldrotate3 - 180)skeleton.muscles[i].newrotate3 += 360;
3692                         if (skeleton.muscles[i].newrotate2 > skeleton.muscles[i].oldrotate2 + 180)skeleton.muscles[i].newrotate2 -= 360;
3693                         if (skeleton.muscles[i].newrotate2 < skeleton.muscles[i].oldrotate2 - 180)skeleton.muscles[i].newrotate2 += 360;
3694                         if (skeleton.muscles[i].newrotate1 > skeleton.muscles[i].oldrotate1 + 180)skeleton.muscles[i].newrotate1 -= 360;
3695                         if (skeleton.muscles[i].newrotate1 < skeleton.muscles[i].oldrotate1 - 180)skeleton.muscles[i].newrotate1 += 360;
3696                     }
3697                 }
3698             }
3699             if (frameCurrent >= animation[animCurrent].numframes)frameCurrent = animation[animCurrent].numframes - 1;
3700
3701             oldanimCurrent = animCurrent;
3702             oldanimTarget = animTarget;
3703             oldframeTarget = frameTarget;
3704             oldframeCurrent = frameCurrent;
3705
3706             for (i = 0; i < skeleton.num_joints; i++) {
3707                 skeleton.joints[i].velocity = (animation[animCurrent].position[i][frameCurrent] * (1 - target) + animation[animTarget].position[i][frameTarget] * (target) - skeleton.joints[i].position) / multiplier;
3708                 skeleton.joints[i].position = animation[animCurrent].position[i][frameCurrent] * (1 - target) + animation[animTarget].position[i][frameTarget] * (target);
3709             }
3710             offset = currentoffset * (1 - target) + targetoffset * target;
3711             for (i = 0; i < skeleton.num_muscles; i++) {
3712                 if (skeleton.muscles[i].visible) {
3713                     skeleton.muscles[i].rotate1 = skeleton.muscles[i].oldrotate1 * (1 - target) + skeleton.muscles[i].newrotate1 * (target);
3714                     skeleton.muscles[i].rotate2 = skeleton.muscles[i].oldrotate2 * (1 - target) + skeleton.muscles[i].newrotate2 * (target);
3715                     skeleton.muscles[i].rotate3 = skeleton.muscles[i].oldrotate3 * (1 - target) + skeleton.muscles[i].newrotate3 * (target);
3716                 }
3717             }
3718         }
3719
3720         if (isLanding() && landhard) {
3721             if (id == 0)camerashake += .4;
3722             animTarget = getLandhard();
3723             frameTarget = 0;
3724             target = 0;
3725             landhard = 0;
3726             transspeed = 15;
3727         }
3728     }
3729     //skeleton.DoConstraints();
3730 }
3731
3732 void    Person::DoStuff()
3733 {
3734     static XYZ terrainnormal;
3735     static XYZ flatfacing;
3736     static XYZ flatvelocity;
3737     static float flatvelspeed;
3738     static int i, j, l;
3739     static XYZ average;
3740     static int howmany;
3741     static int bloodsize;
3742     static int startx, starty, endx, endy;
3743     static GLubyte color;
3744     static XYZ bloodvel;
3745
3746     onfiredelay -= multiplier;
3747     if (onfiredelay < 0 && onfire) {
3748         if (Random() % 2 == 0) {
3749             crouchkeydown = 1;
3750         }
3751         onfiredelay = 0.3;
3752     }
3753
3754     crouchkeydowntime += multiplier;
3755     if (!crouchkeydown)crouchkeydowntime = 0;
3756     jumpkeydowntime += multiplier;
3757     if (!jumpkeydown && skeleton.free)jumpkeydowntime = 0;
3758
3759     if (hostile || damage > 0 || bloodloss > 0)immobile = 0;
3760
3761     if (isIdle() || isRun())targetoffset = 0;
3762
3763     if (num_weapons == 1 && weaponactive != -1)weaponstuck = -1;
3764
3765     if (id == 0)blooddimamount -= multiplier * .3;
3766     speechdelay -= multiplier;
3767     texupdatedelay -= multiplier;
3768     interestdelay -= multiplier;
3769     flamedelay -= multiplier;
3770     parriedrecently -= multiplier;
3771     if (!victim) {
3772         victim = this;
3773         hasvictim = 0;
3774     }
3775
3776     if (id == 0)speed = 1.1 * speedmult;
3777     else speed = 1.0 * speedmult;
3778     if (!skeleton.free)rabbitkickragdoll = 0;
3779
3780     speed *= speedmult;
3781
3782     if (id != 0 && (creature == rabbittype || difficulty != 2))superruntoggle = 0;
3783     if (id != 0 && creature == wolftype && difficulty == 2) {
3784         superruntoggle = 0;
3785         if (aitype != passivetype) {
3786             superruntoggle = 1;
3787             if (aitype == attacktypecutoff && (player[0].isIdle() || player[0].isCrouch() || player[0].skeleton.free || player[0].animTarget == getupfrombackanim || player[0].animTarget == getupfromfrontanim || player[0].animTarget == sneakanim) && distsq(&coords, &player[0].coords) < 16) {
3788                 superruntoggle = 0;
3789             }
3790         }
3791         if (scale < 0.2)superruntoggle = 0;
3792         if (animTarget == wolfrunninganim && !superruntoggle) {
3793             animTarget = getRun();
3794             frameTarget = 0;
3795         }
3796     }
3797     if (weaponactive == -1 && num_weapons > 0) {
3798         if (weapons[weaponids[0]].getType() == staff) {
3799             weaponactive = 0;
3800         }
3801     }
3802
3803     if (onfire) {
3804         burnt += multiplier;
3805         /*if(aitype!=playercontrolled)*///deathbleeding=5;
3806         /*if(aitype!=playercontrolled)*/
3807         deathbleeding = 1;
3808         if (burnt > .6)burnt = .6;
3809         OPENAL_SetVolume(channels[stream_firesound], 256 + 256 * findLength(&velocity) / 3);
3810
3811         if (animTarget == jumpupanim || animTarget == jumpdownanim || isFlip()) {
3812             float gLoc[3];
3813             float vel[3];
3814             gLoc[0] = coords.x;
3815             gLoc[1] = coords.y;
3816             gLoc[2] = coords.z;
3817             vel[0] = velocity.x;
3818             vel[1] = velocity.y;
3819             vel[2] = velocity.z;
3820
3821             if (id == 0) {
3822                 OPENAL_3D_SetAttributes(channels[whooshsound], gLoc, vel);
3823                 OPENAL_SetVolume(channels[whooshsound], 64 * findLength(&velocity) / 5);
3824             }
3825         }
3826     }
3827     while (flamedelay < 0 && onfire) {
3828         flamedelay += .006;
3829         howmany = abs(Random() % (skeleton.num_joints));
3830         if (!skeleton.free)flatvelocity = (coords - oldcoords) / multiplier / 2; //velocity/2;
3831         if (skeleton.free)flatvelocity = skeleton.joints[howmany].velocity * scale / 2;
3832         if (!skeleton.free)flatfacing = DoRotation(DoRotation(DoRotation(skeleton.joints[howmany].position, 0, 0, tilt), tilt2, 0, 0), 0, yaw, 0) * scale + coords;
3833         if (skeleton.free)flatfacing = skeleton.joints[howmany].position * scale + coords;
3834         Sprite::MakeSprite(flamesprite, flatfacing, flatvelocity, 1, 1, 1, .6 + (float)abs(Random() % 100) / 200 - .25, 1);
3835     }
3836
3837     while (flamedelay < 0 && !onfire && tutoriallevel == 1 && id != 0) {
3838         flamedelay += .05;
3839         howmany = abs(Random() % (skeleton.num_joints));
3840         if (!skeleton.free)flatvelocity = (coords - oldcoords) / multiplier / 2; //velocity/2;
3841         if (skeleton.free)flatvelocity = skeleton.joints[howmany].velocity * scale / 2;
3842         if (!skeleton.free)flatfacing = DoRotation(DoRotation(DoRotation(skeleton.joints[howmany].position, 0, 0, tilt), tilt2, 0, 0), 0, yaw, 0) * scale + coords;
3843         if (skeleton.free)flatfacing = skeleton.joints[howmany].position * scale + coords;
3844         Sprite::MakeSprite(breathsprite, flatfacing, flatvelocity, 1, 1, 1, .6 + (float)abs(Random() % 100) / 200 - .25, .3);
3845     }
3846
3847     if (bleeding > 0) {
3848         bleeding -= multiplier * .3;
3849         if (bloodtoggle == 2) {
3850             skeleton.drawmodel.textureptr.bind();
3851             if (bleeding <= 0 && (detail != 2 || osx))DoMipmaps();
3852         }
3853     }
3854
3855     if (neckspurtamount > 0) {
3856         neckspurtamount -= multiplier;
3857         neckspurtdelay -= multiplier * 3;
3858         neckspurtparticledelay -= multiplier * 3;
3859         if (neckspurtparticledelay < 0 && neckspurtdelay > 2) {
3860             spurt = 0;
3861             bloodvel = 0;
3862             if (!skeleton.free) {
3863                 bloodvel.z = 5 * neckspurtamount;
3864                 bloodvel = DoRotation(bloodvel, ((float)(Random() % 100)) / 40, yaw + ((float)(Random() % 100)) / 40, 0) * scale;
3865             }
3866             if (skeleton.free) {
3867                 bloodvel -= DoRotation(skeleton.forward * 10 * scale, ((float)(Random() % 100)) / 40, ((float)(Random() % 100)) / 40, 0);
3868             }
3869             if (skeleton.free)bloodvel += DoRotation(skeleton.joints[skeleton.jointlabels[head]].velocity, ((float)(Random() % 100)) / 40, yaw + ((float)(Random() % 100)) / 40, 0) * scale;
3870             if (!skeleton.free)bloodvel += DoRotation(velocity, ((float)(Random() % 100)) / 40, ((float)(Random() % 100)) / 40, 0) * scale;
3871             if (skeleton.free)Sprite::MakeSprite(bloodsprite, (skeleton.joints[skeleton.jointlabels[neck]].position + (skeleton.joints[skeleton.jointlabels[neck]].position - skeleton.joints[skeleton.jointlabels[head]].position) / 5)*scale + coords, bloodvel, 1, 1, 1, .05, .9);
3872             if (!skeleton.free)Sprite::MakeSprite(bloodsprite, DoRotation(skeleton.joints[skeleton.jointlabels[neck]].position + (skeleton.joints[skeleton.jointlabels[neck]].position - skeleton.joints[skeleton.jointlabels[head]].position) / 5, 0, yaw, 0)*scale + coords, bloodvel, 1, 1, 1, .05, .9);
3873             neckspurtparticledelay = .05;
3874         }
3875         if (neckspurtdelay < 0) {
3876             neckspurtdelay = 3;
3877         }
3878     }
3879
3880     if (deathbleeding > 0 && dead != 2) {
3881         if (deathbleeding < 5)bleeddelay -= deathbleeding * multiplier / 4;
3882         else bleeddelay -= 5 * multiplier / 4;
3883         if (bleeddelay < 0 && bloodtoggle) {
3884             bleeddelay = 1;
3885             XYZ bloodvel;
3886             if (bloodtoggle) {
3887                 bloodvel = 0;
3888                 if (skeleton.free)bloodvel += DoRotation(skeleton.joints[skeleton.jointlabels[abdomen]].velocity, ((float)(Random() % 100)) / 4, yaw + ((float)(Random() % 100)) / 4, 0) * scale;
3889                 if (!skeleton.free)bloodvel += DoRotation(velocity, ((float)(Random() % 100)) / 4, ((float)(Random() % 100)) / 4, 0) * scale;
3890                 if (skeleton.free)Sprite::MakeSprite(bloodsprite, skeleton.joints[skeleton.jointlabels[abdomen]].position * scale + coords, bloodvel, 1, 1, 1, .05, 1);
3891                 if (!skeleton.free)Sprite::MakeSprite(bloodsprite, DoRotation((skeleton.joints[skeleton.jointlabels[abdomen]].position + skeleton.joints[skeleton.jointlabels[abdomen]].position) / 2, 0, yaw, 0)*scale + coords, bloodvel, 1, 1, 1, .05, 1);
3892             }
3893         }
3894         bloodloss += deathbleeding * multiplier * 80;
3895         deathbleeding -= multiplier * 1.6;
3896         //if(id==0)deathbleeding-=multiplier*.2;
3897         if (deathbleeding < 0)deathbleeding = 0;
3898         if (bloodloss > damagetolerance && animation[animTarget].attack == neutral) {
3899             if (weaponactive != -1) {
3900                 weapons[weaponids[0]].owner = -1;
3901                 weapons[weaponids[0]].velocity = velocity * scale * -.3;
3902                 weapons[weaponids[0]].velocity.x += .01;
3903                 weapons[weaponids[0]].tipvelocity = velocity * scale;
3904                 weapons[weaponids[0]].missed = 1;
3905                 weapons[weaponids[0]].hitsomething = 0;
3906                 weapons[weaponids[0]].freetime = 0;
3907                 weapons[weaponids[0]].firstfree = 1;
3908                 weapons[weaponids[0]].physics = 1;
3909                 num_weapons--;
3910                 if (num_weapons) {
3911                     weaponids[0] = weaponids[num_weapons];
3912                     if (weaponstuck == num_weapons)weaponstuck = 0;
3913                 }
3914                 weaponactive = -1;
3915                 for (i = 0; i < numplayers; i++) {
3916                     player[i].wentforweapon = 0;
3917                 }
3918
3919                 if (id == 0) {
3920                     flashamount = .5;
3921                     flashr = 1;
3922                     flashg = 0;
3923                     flashb = 0;
3924                     flashdelay = 0;
3925                 }
3926             }
3927
3928             if (!dead && creature == wolftype) {
3929                 award_bonus(0, Wolfbonus);
3930             }
3931             dead = 2;
3932             if (animTarget == knifefollowedanim && !skeleton.free) {
3933                 for (i = 0; i < skeleton.num_joints; i++) {
3934                     skeleton.joints[i].velocity = 0;
3935                     skeleton.joints[i].velocity.y = -2;
3936                 }
3937             }
3938             if (id != 0 && unconscioustime > .1) {
3939                 numafterkill++;
3940             }
3941
3942             RagDoll(0);
3943         }
3944     }
3945
3946     if (texupdatedelay < 0 && bleeding > 0 && bloodtoggle == 2 && distsq(&viewer, &coords) < 9) {
3947         texupdatedelay = .12;
3948
3949         bloodsize = 5 - realtexdetail;
3950
3951         startx = 0;
3952         starty = 0;
3953         startx = bleedy; //abs(Random()%(skeleton.skinsize-bloodsize-1));
3954         starty = bleedx; //abs(Random()%(skeleton.skinsize-bloodsize-1));
3955         endx = startx + bloodsize;
3956         endy = starty + bloodsize;
3957
3958         if (startx < 0) {
3959             startx = 0;
3960             bleeding = 0;
3961         }
3962         if (starty < 0) {
3963             starty = 0;
3964             bleeding = 0;
3965         }
3966         if (endx > skeleton.skinsize - 1) {
3967             endx = skeleton.skinsize - 1;
3968             bleeding = 0;
3969         }
3970         if (endy > skeleton.skinsize - 1) {
3971             endy = skeleton.skinsize - 1;
3972             bleeding = 0;
3973         }
3974         if (endx < startx)endx = startx;
3975         if (endy < starty)endy = starty;
3976
3977         for (i = startx; i < endx; i++) {
3978             for (j = starty; j < endy; j++) {
3979                 if (Random() % 2 == 0) {
3980                     color = Random() % 85 + 170;
3981                     if (skeleton.skinText[i * skeleton.skinsize * 3 + j * 3 + 0] > color / 2)skeleton.skinText[i * skeleton.skinsize * 3 + j * 3 + 0] = color / 2;
3982                     skeleton.skinText[i * skeleton.skinsize * 3 + j * 3 + 1] = 0;
3983                     skeleton.skinText[i * skeleton.skinsize * 3 + j * 3 + 2] = 0;
3984                 }
3985             }
3986         }
3987         if (!osx && detail > 1) {
3988             skeleton.drawmodel.textureptr.bind();
3989             DoMipmaps();
3990         }
3991
3992         if (!skeleton.free) {
3993             bleedy -= 4 / realtexdetail;
3994             if (detail == 2)bleedx += (abs(Random() % 3) - 1) * 2 / realtexdetail;
3995             else bleedx += (abs(Random() % 3) - 1) * 4 / realtexdetail;
3996         }
3997         if (skeleton.free) {
3998             bleedx += 4 * direction / realtexdetail;
3999             if (detail == 2)bleedy += (abs(Random() % 3) - 1) * 2 / realtexdetail;
4000             else bleedy += (abs(Random() % 3) - 1) * 4 / realtexdetail;
4001         }
4002     }
4003
4004     if (abs(righthandmorphness - targetrighthandmorphness) < multiplier * 4) {
4005         righthandmorphness = targetrighthandmorphness;
4006         righthandmorphstart = righthandmorphend;
4007     } else if (righthandmorphness > targetrighthandmorphness) {
4008         righthandmorphness -= multiplier * 4;
4009     } else if (righthandmorphness < targetrighthandmorphness) {
4010         righthandmorphness += multiplier * 4;
4011     }
4012
4013     if (abs(lefthandmorphness - targetlefthandmorphness) < multiplier * 4) {
4014         lefthandmorphness = targetlefthandmorphness;
4015         lefthandmorphstart = lefthandmorphend;
4016     } else if (lefthandmorphness > targetlefthandmorphness) {
4017         lefthandmorphness -= multiplier * 4;
4018     } else if (lefthandmorphness < targetlefthandmorphness) {
4019         lefthandmorphness += multiplier * 4;
4020     }
4021
4022     if (creature == rabbittype || targettailmorphness == 5 || targettailmorphness == 0) {
4023         if (abs(tailmorphness - targettailmorphness) < multiplier * 10) {
4024             tailmorphness = targettailmorphness;
4025             tailmorphstart = tailmorphend;
4026         } else if (tailmorphness > targettailmorphness) {
4027             tailmorphness -= multiplier * 10;
4028         } else if (tailmorphness < targettailmorphness) {
4029             tailmorphness += multiplier * 10;
4030         }
4031     }
4032
4033     if (creature == wolftype) {
4034         if (abs(tailmorphness - targettailmorphness) < multiplier * 4) {
4035             tailmorphness = targettailmorphness;
4036             tailmorphstart = tailmorphend;
4037         } else if (tailmorphness > targettailmorphness) {
4038             tailmorphness -= multiplier * 2;
4039         } else if (tailmorphness < targettailmorphness) {
4040             tailmorphness += multiplier * 2;
4041         }
4042     }
4043
4044     if (headmorphend == 3 || headmorphstart == 3) {
4045         if (abs(headmorphness - targetheadmorphness) < multiplier * 7) {
4046             headmorphness = targetheadmorphness;
4047             headmorphstart = headmorphend;
4048         } else if (headmorphness > targetheadmorphness) {
4049             headmorphness -= multiplier * 7;
4050         } else if (headmorphness < targetheadmorphness) {
4051             headmorphness += multiplier * 7;
4052         }
4053     } else if (headmorphend == 5 || headmorphstart == 5) {
4054         if (abs(headmorphness - targetheadmorphness) < multiplier * 10) {
4055             headmorphness = targetheadmorphness;
4056             headmorphstart = headmorphend;
4057         } else if (headmorphness > targetheadmorphness) {
4058             headmorphness -= multiplier * 10;
4059         } else if (headmorphness < targetheadmorphness) {
4060             headmorphness += multiplier * 10;
4061         }
4062     } else {
4063         if (abs(headmorphness - targetheadmorphness) < multiplier * 4) {
4064             headmorphness = targetheadmorphness;
4065             headmorphstart = headmorphend;
4066         } else if (headmorphness > targetheadmorphness) {
4067             headmorphness -= multiplier * 4;
4068         } else if (headmorphness < targetheadmorphness) {
4069             headmorphness += multiplier * 4;
4070         }
4071     }
4072
4073     if (abs(chestmorphness - targetchestmorphness) < multiplier) {
4074         chestmorphness = targetchestmorphness;
4075         chestmorphstart = chestmorphend;
4076     } else if (chestmorphness > targetchestmorphness) {
4077         chestmorphness -= multiplier;
4078     } else if (chestmorphness < targetchestmorphness) {
4079         chestmorphness += multiplier;
4080     }
4081
4082     if (dead != 2 && howactive <= typesleeping) {
4083         if (chestmorphstart == 0 && chestmorphend == 0) {
4084             chestmorphness = 0;
4085             targetchestmorphness = 1;
4086             chestmorphend = 3;
4087         }
4088         if (chestmorphstart != 0 && chestmorphend != 0) {
4089             chestmorphness = 0;
4090             targetchestmorphness = 1;
4091             chestmorphend = 0;
4092             if (environment == snowyenvironment) {
4093                 XYZ footpoint;
4094                 XYZ footvel;
4095                 if (!skeleton.free)footvel = DoRotation(skeleton.specialforward[0], 0, yaw, 0) * -1;
4096                 if (skeleton.free)footvel = skeleton.specialforward[0] * -1;
4097                 if (!skeleton.free)footpoint = DoRotation((skeleton.joints[skeleton.jointlabels[head]].position + skeleton.joints[skeleton.jointlabels[neck]].position) / 2, 0, yaw, 0) * scale + coords;
4098                 if (skeleton.free)footpoint = ((skeleton.joints[skeleton.jointlabels[head]].position + skeleton.joints[skeleton.jointlabels[neck]].position) / 2) * scale + coords;
4099                 if (animTarget == sleepanim)footvel = DoRotation(footvel, 0, 90, 0);
4100                 Sprite::MakeSprite(breathsprite, footpoint + footvel * .2, footvel * .4, 1, 1, 1, .4, .3);
4101             }
4102         }
4103
4104         if (!dead && howactive < typesleeping) {
4105             blinkdelay -= multiplier * 2;
4106             if (headmorphstart == 0 && headmorphend == 0 && blinkdelay <= 0) {
4107                 headmorphness = 0;
4108                 targetheadmorphness = 1;
4109                 headmorphend = 3;
4110                 blinkdelay = (float)(abs(Random() % 40)) / 5;
4111             }
4112             if (headmorphstart == 3 && headmorphend == 3) {
4113                 headmorphness = 0;
4114                 targetheadmorphness = 1;
4115                 headmorphend = 0;
4116             }
4117         }
4118         if (!dead) {
4119             twitchdelay -= multiplier * 1.5;
4120             if (animTarget != hurtidleanim) {
4121                 if (headmorphstart == 0 && headmorphend == 0 && twitchdelay <= 0) {
4122                     headmorphness = 0;
4123                     targetheadmorphness = 1;
4124                     headmorphend = 5;
4125                     twitchdelay = (float)(abs(Random() % 40)) / 5;
4126                 }
4127                 if (headmorphstart == 5 && headmorphend == 5) {
4128                     headmorphness = 0;
4129                     targetheadmorphness = 1;
4130                     headmorphend = 0;
4131                 }
4132             }
4133             if ((isIdle() || isCrouch()) && animTarget != hurtidleanim) {
4134                 twitchdelay3 -= multiplier * 1;
4135                 if (Random() % 2 == 0) {
4136                     if (righthandmorphstart == 0 && righthandmorphend == 0 && twitchdelay3 <= 0) {
4137                         righthandmorphness = 0;
4138                         targetrighthandmorphness = 1;
4139                         righthandmorphend = 1;
4140                         if (Random() % 2 == 0)twitchdelay3 = (float)(abs(Random() % 40)) / 5;
4141                     }
4142                     if (righthandmorphstart == 1 && righthandmorphend == 1) {
4143                         righthandmorphness = 0;
4144                         targetrighthandmorphness = 1;
4145                         righthandmorphend = 0;
4146                     }
4147                 }
4148                 if (Random() % 2 == 0) {
4149                     if (lefthandmorphstart == 0 && lefthandmorphend == 0 && twitchdelay3 <= 0) {
4150                         lefthandmorphness = 0;
4151                         targetlefthandmorphness = 1;
4152                         lefthandmorphend = 1;
4153                         twitchdelay3 = (float)(abs(Random() % 40)) / 5;
4154                     }
4155                     if (lefthandmorphstart == 1 && lefthandmorphend == 1) {
4156                         lefthandmorphness = 0;
4157                         targetlefthandmorphness = 1;
4158                         lefthandmorphend = 0;
4159                     }
4160                 }
4161             }
4162         }
4163         if (!dead) {
4164             if (creature == rabbittype) {
4165                 if (howactive < typesleeping)twitchdelay2 -= multiplier * 1.5;
4166                 else twitchdelay2 -= multiplier * 0.5;
4167                 if (howactive <= typesleeping) {
4168                     if (tailmorphstart == 0 && tailmorphend == 0 && twitchdelay2 <= 0) {
4169                         tailmorphness = 0;
4170                         targettailmorphness = 1;
4171                         tailmorphend = 1;
4172                         twitchdelay2 = (float)(abs(Random() % 40)) / 5;
4173                     }
4174                     if (tailmorphstart == 1 && tailmorphend == 1) {
4175                         tailmorphness = 0;
4176                         targettailmorphness = 1;
4177                         tailmorphend = 2;
4178                     }
4179                     if (tailmorphstart == 2 && tailmorphend == 2) {
4180                         tailmorphness = 0;
4181                         targettailmorphness = 1;
4182                         tailmorphend = 0;
4183                     }
4184                 }
4185             }
4186         }
4187     }
4188     if (creature == wolftype) {
4189         twitchdelay2 -= multiplier * 1.5;
4190         if (tailmorphend != 0)
4191             if ((isRun() || animTarget == jumpupanim || animTarget == jumpdownanim || animTarget == backflipanim) && !skeleton.free) {
4192                 tailmorphness = 0;
4193                 targettailmorphness = 1;
4194                 tailmorphend = 0;
4195                 twitchdelay2 = .1;
4196             }
4197         if (tailmorphend != 5)
4198             if (animTarget == flipanim || animTarget == frontflipanim || animTarget == rollanim || skeleton.free) {
4199                 tailmorphness = 0;
4200                 targettailmorphness = 1;
4201                 tailmorphend = 5;
4202                 twitchdelay2 = .1;
4203             }
4204         if (twitchdelay2 <= 0) {
4205             if (((tailmorphstart == 0 && tailmorphend == 0) || (tailmorphstart == 5 && tailmorphend == 5))) {
4206                 tailmorphness = 0;
4207                 targettailmorphness = 1;
4208                 tailmorphend = 1;
4209             }
4210             if (tailmorphstart == 1 && tailmorphend == 1) {
4211                 tailmorphness = 0;
4212                 targettailmorphness = 1;
4213                 tailmorphend = 2;
4214             }
4215             if (tailmorphstart == 2 && tailmorphend == 2) {
4216                 tailmorphness = 0;
4217                 targettailmorphness = 1;
4218                 tailmorphend = 3;
4219             }
4220             if (tailmorphstart == 3 && tailmorphend == 3) {
4221                 tailmorphness = 0;
4222                 targettailmorphness = 1;
4223                 tailmorphend = 4;
4224             }
4225             if (tailmorphstart == 4 && tailmorphend == 4) {
4226                 tailmorphness = 0;
4227                 targettailmorphness = 1;
4228                 tailmorphend = 1;
4229             }
4230         }
4231     }
4232
4233     if (dead != 1)unconscioustime = 0;
4234
4235     if (dead == 1 || howactive == typesleeping) {
4236         unconscioustime += multiplier;
4237         //If unconscious, close eyes and mouth
4238         if (righthandmorphend != 0)righthandmorphness = 0;
4239         righthandmorphend = 0;
4240         targetrighthandmorphness = 1;
4241
4242         if (lefthandmorphend != 0)lefthandmorphness = 0;
4243         lefthandmorphend = 0;
4244         targetlefthandmorphness = 1;
4245
4246         if (headmorphend != 3 && headmorphend != 5)headmorphness = 0;
4247         headmorphend = 3;
4248         targetheadmorphness = 1;
4249     }
4250
4251
4252     if (howactive > typesleeping) {
4253         XYZ headpoint;
4254         headpoint = coords;
4255         if (bloodtoggle && !bled) {
4256             terrain.MakeDecal(blooddecalslow, headpoint, .8, .5, 0);
4257         }
4258         if (bloodtoggle && !bled)
4259             for (l = 0; l < terrain.patchobjectnum[whichpatchx][whichpatchz]; l++) {
4260                 j = terrain.patchobjects[whichpatchx][whichpatchz][l];
4261                 XYZ point = DoRotation(headpoint - objects.position[j], 0, -objects.yaw[j], 0);
4262                 float size = .8;
4263                 float opacity = .6;
4264                 float yaw = 0;
4265                 objects.model[j].MakeDecal(blooddecalslow, &point, &size, &opacity, &yaw);
4266             }
4267         bled = 1;
4268     }
4269
4270     if (dead == 2 || howactive > typesleeping) {
4271         //If dead, open mouth and hands
4272         if (righthandmorphend != 0)righthandmorphness = 0;
4273         righthandmorphend = 0;
4274         targetrighthandmorphness = 1;
4275
4276         if (lefthandmorphend != 0)lefthandmorphness = 0;
4277         lefthandmorphend = 0;
4278         targetlefthandmorphness = 1;
4279
4280         if (headmorphend != 2)headmorphness = 0;
4281         headmorphend = 2;
4282         targetheadmorphness = 1;
4283     }
4284
4285     if (stunned > 0 && !dead && headmorphend != 2) {
4286         if (headmorphend != 4)headmorphness = 0;
4287         headmorphend = 4;
4288         targetheadmorphness = 1;
4289     }
4290
4291     if (damage > damagetolerance && !dead) {
4292
4293         dead = 1;
4294         unconscioustime = 0;
4295
4296         if (creature == wolftype) {
4297             award_bonus(0, Wolfbonus);
4298         }
4299
4300         RagDoll(0);
4301
4302         if (weaponactive != -1) {
4303             weapons[weaponids[0]].owner = -1;
4304             weapons[weaponids[0]].velocity = velocity * scale * -.3;
4305             weapons[weaponids[0]].velocity.x += .01;
4306             weapons[weaponids[0]].tipvelocity = velocity * scale;
4307             weapons[weaponids[0]].missed = 1;
4308             weapons[weaponids[0]].hitsomething = 0;
4309             weapons[weaponids[0]].freetime = 0;
4310             weapons[weaponids[0]].firstfree = 1;
4311             weapons[weaponids[0]].physics = 1;
4312             num_weapons--;
4313             if (num_weapons) {
4314                 weaponids[0] = weaponids[num_weapons];
4315                 if (weaponstuck == num_weapons)weaponstuck = 0;
4316             }
4317             weaponactive = -1;
4318             for (i = 0; i < numplayers; i++) {
4319                 player[i].wentforweapon = 0;
4320             }
4321         }
4322
4323
4324
4325         if ((id == 0 || distsq(&coords, &viewer) < 50) && autoslomo) {
4326             slomo = 1;
4327             slomodelay = .2;
4328         }
4329
4330         damage += 20;
4331     }
4332
4333     //if(dead)damage-=multiplier/4;
4334     if (!dead)damage -= multiplier * 13;
4335     //if(!dead&&deathbleeding<=0&&id==0)bloodloss-=multiplier*4;
4336     if (!dead)permanentdamage -= multiplier * 4;
4337     if (isIdle() || isCrouch()) {
4338         if (!dead)permanentdamage -= multiplier * 4;
4339         //if(!dead&&deathbleeding<=0&&id==0)bloodloss-=multiplier*4;
4340     }
4341     if (damage < 0)damage = 0;
4342     if (permanentdamage < 0)permanentdamage = 0;
4343     if (superpermanentdamage < 0)superpermanentdamage = 0;
4344     if (permanentdamage < superpermanentdamage) {
4345         permanentdamage = superpermanentdamage;
4346     }
4347     if (damage < permanentdamage) {
4348         damage = permanentdamage;
4349     }
4350     if (dead == 1 && damage < damagetolerance) {
4351         dead = 0;
4352         skeleton.free = 1;
4353         damage -= 20;
4354         for (i = 0; i < skeleton.num_joints; i++) {
4355             skeleton.joints[i].velocity = 0;
4356         }
4357     }
4358     if (permanentdamage > damagetolerance && dead != 2) {
4359         DoBlood(1, 255);
4360
4361         if (weaponactive != -1) {
4362             weapons[weaponids[0]].owner = -1;
4363             weapons[weaponids[0]].velocity = velocity * scale * -.3;
4364             weapons[weaponids[0]].velocity.x += .01;
4365             weapons[weaponids[0]].tipvelocity = velocity * scale;
4366             weapons[weaponids[0]].missed = 1;
4367             weapons[weaponids[0]].hitsomething = 0;
4368             weapons[weaponids[0]].freetime = 0;
4369             weapons[weaponids[0]].firstfree = 1;
4370             weapons[weaponids[0]].physics = 1;
4371             num_weapons--;
4372             if (num_weapons) {
4373                 weaponids[0] = weaponids[num_weapons];
4374                 if (weaponstuck == num_weapons)weaponstuck = 0;
4375             }
4376             weaponactive = -1;
4377             for (i = 0; i < numplayers; i++) {
4378                 player[i].wentforweapon = 0;
4379             }
4380         }
4381
4382         bled = 0;
4383
4384         if (!dead && creature == wolftype) {
4385             award_bonus(0, Wolfbonus);
4386         }
4387
4388         if (unconscioustime < .1 && (bonus != spinecrusher || bonustime > 1) && (bonus != FinishedBonus || bonustime > 1) && bloodloss < damagetolerance)
4389             award_bonus(id, touchofdeath);
4390         if (id != 0 && unconscioustime > .1) {
4391             numafterkill++;
4392         }
4393
4394         dead = 2;
4395
4396         skeleton.free = 1;
4397
4398         emit_sound_at(breaksound, coords);
4399     }
4400
4401     if (skeleton.free == 1) {
4402         if (id == 0)pause_sound(whooshsound);
4403
4404         if (!dead) {
4405             //If knocked over, open hands and close mouth
4406             if (righthandmorphend != 0)righthandmorphness = 0;
4407             righthandmorphend = 0;
4408             targetrighthandmorphness = 1;
4409
4410             if (lefthandmorphend != 0)lefthandmorphness = 0;
4411             lefthandmorphend = 0;
4412             targetlefthandmorphness = 1;
4413
4414             if (headmorphend != 3 && headmorphend != 5 && headmorphstart != 3 && headmorphstart != 5) {
4415                 if (headmorphend != 0)headmorphness = 0;
4416                 headmorphend = 0;
4417                 targetheadmorphness = 1;
4418             }
4419         }
4420
4421         skeleton.DoGravity(&scale);
4422         float damageamount;
4423         damageamount = skeleton.DoConstraints(&coords, &scale) * 5;
4424         if (damage > damagetolerance - damageamount && !dead && (bonus != spinecrusher || bonustime > 1) && (bonus != style || bonustime > 1) && (bonus != cannon || bonustime > 1))
4425             award_bonus(id, deepimpact);
4426         DoDamage(damageamount / ((protectionhigh + protectionhead + protectionlow) / 3));
4427
4428         average = 0;
4429         howmany = 0;
4430         for (j = 0; j < skeleton.num_joints; j++) {
4431             average += skeleton.joints[j].position;
4432             howmany++;
4433         }
4434         average /= howmany;
4435         coords += average * scale;
4436         for (j = 0; j < skeleton.num_joints; j++) {
4437             skeleton.joints[j].position -= average;
4438         }
4439         average /= multiplier;
4440
4441         //velocity=skeleton.joints[skeleton.jointlabels[groin]].velocity*scale;
4442         velocity = 0;
4443         for (i = 0; i < skeleton.num_joints; i++) {
4444             velocity += skeleton.joints[i].velocity * scale;
4445         }
4446         velocity /= skeleton.num_joints;
4447
4448         if (!isnormal(velocity.x) && velocity.x) {
4449             velocity = 0;
4450         }
4451
4452         if (findLength(&average) < 10 && dead && skeleton.free) {
4453             skeleton.longdead += (2000 - findLength(&average)) * multiplier + multiplier;
4454             if (skeleton.longdead > 2000) {
4455                 if (skeleton.longdead > 6000) {
4456                     if (id == 0)pause_sound(whooshsound);
4457                     skeleton.free = 3;
4458                     DrawSkeleton();
4459                     skeleton.free = 2;
4460                 }
4461                 if (dead == 2 && bloodloss < damagetolerance) {
4462                     XYZ headpoint;
4463                     headpoint = (skeleton.joints[skeleton.jointlabels[head]].position + skeleton.joints[skeleton.jointlabels[neck]].position) / 2 * scale + coords;
4464                     DoBlood(1, 255);
4465                     if (bloodtoggle && !bled) {
4466                         terrain.MakeDecal(blooddecal, headpoint, .2 * 1.2, .5, 0);
4467                     }
4468                     if (bloodtoggle && !bled)
4469                         for (l = 0; l < terrain.patchobjectnum[whichpatchx][whichpatchz]; l++) {
4470                             j = terrain.patchobjects[whichpatchx][whichpatchz][l];
4471                             XYZ point = DoRotation(headpoint - objects.position[j], 0, -objects.yaw[j], 0);
4472                             float size = .2 * 1.2;
4473                             float opacity = .6;
4474                             float yaw = 0;
4475                             objects.model[j].MakeDecal(blooddecal, &point, &size, &opacity, &yaw);
4476                         }
4477                     bled = 1;
4478                 }
4479                 if (dead == 2 && bloodloss >= damagetolerance) {
4480                     XYZ headpoint;
4481                     headpoint = (skeleton.joints[skeleton.jointlabels[abdomen]].position + skeleton.joints[skeleton.jointlabels[neck]].position) / 2 * scale + coords;
4482                     if (bleeding <= 0)DoBlood(1, 255);
4483                     if (bloodtoggle && !bled) {
4484                         terrain.MakeDecal(blooddecalslow, headpoint, .8, .5, 0);
4485                     }
4486                     if (bloodtoggle && !bled)
4487                         for (l = 0; l < terrain.patchobjectnum[whichpatchx][whichpatchz]; l++) {
4488                             j = terrain.patchobjects[whichpatchx][whichpatchz][l];
4489                             XYZ point = DoRotation(headpoint - objects.position[j], 0, -objects.yaw[j], 0);
4490                             float size = .8;
4491                             float opacity = .6;
4492                             float yaw = 0;
4493                             objects.model[j].MakeDecal(blooddecalslow, &point, &size, &opacity, &yaw);
4494                         }
4495                     bled = 1;
4496                 }
4497             }
4498         }
4499
4500         if (!dead && crouchkeydown && skeleton.freetime > .5 && id == 0 && skeleton.free) {
4501             bool canrecover = 1;
4502             XYZ startpoint, endpoint, colpoint, colviewer, coltarget;
4503             startpoint = coords;
4504             endpoint = coords;
4505             endpoint.y -= .7;
4506             if (terrain.lineTerrain(startpoint, endpoint, &colpoint) != -1)canrecover = 0;
4507             if (velocity.y < -30)canrecover = 0;
4508             for (i = 0; i < objects.numobjects; i++) {
4509                 if (objects.type[i] != treeleavestype && objects.type[i] != bushtype && objects.type[i] != firetype) {
4510                     colviewer = startpoint;
4511                     coltarget = endpoint;
4512                     if (objects.model[i].LineCheck(&colviewer, &coltarget, &colpoint, &objects.position[i], &objects.yaw[i]) != -1)canrecover = 0;
4513                 }
4514             }
4515             if (canrecover) {
4516                 skeleton.free = 0;
4517                 XYZ middle;
4518                 middle = 0;
4519
4520                 terrainnormal = skeleton.joints[skeleton.jointlabels[groin]].position - skeleton.joints[skeleton.jointlabels[abdomen]].position;
4521                 if (skeleton.joints[skeleton.jointlabels[groin]].locked && skeleton.joints[skeleton.jointlabels[abdomen]].locked) {
4522                     terrainnormal = skeleton.joints[skeleton.jointlabels[groin]].position - skeleton.joints[skeleton.jointlabels[abdomen]].position;
4523                     middle = (skeleton.joints[skeleton.jointlabels[groin]].position + skeleton.joints[skeleton.jointlabels[abdomen]].position) / 2;
4524                 }
4525                 if (skeleton.joints[skeleton.jointlabels[abdomen]].locked && skeleton.joints[skeleton.jointlabels[neck]].locked) {
4526                     terrainnormal = skeleton.joints[skeleton.jointlabels[abdomen]].position - skeleton.joints[skeleton.jointlabels[neck]].position;
4527                     middle = (skeleton.joints[skeleton.jointlabels[neck]].position + skeleton.joints[skeleton.jointlabels[abdomen]].position) / 2;
4528                 }
4529                 if (skeleton.joints[skeleton.jointlabels[groin]].locked && skeleton.joints[skeleton.jointlabels[neck]].locked) {
4530                     terrainnormal = skeleton.joints[skeleton.jointlabels[groin]].position - skeleton.joints[skeleton.jointlabels[neck]].position;
4531                     middle = (skeleton.joints[skeleton.jointlabels[groin]].position + skeleton.joints[skeleton.jointlabels[neck]].position) / 2;
4532                 }
4533                 Normalise(&terrainnormal);
4534
4535                 targetyaw = -asin(0 - terrainnormal.x);
4536                 targetyaw *= 360 / 6.28;
4537                 if (terrainnormal.z < 0)targetyaw = 180 - targetyaw;
4538                 yaw = targetyaw;
4539
4540                 frameTarget = 0;
4541                 //      frameTarget=2;
4542                 animTarget = flipanim;
4543                 crouchtogglekeydown = 1;
4544                 target = 0;
4545                 tilt2 = 0;
4546                 targettilt2 = 0;
4547
4548                 animCurrent = tempanim;
4549                 frameCurrent = 0;
4550                 target = 0;
4551                 //tilt2=targettilt2;
4552
4553                 //if(middle.y>0)targetoffset.y=middle.y+1;
4554
4555                 for (i = 0; i < skeleton.num_joints; i++) {
4556                     tempanimation.position[i][0] = skeleton.joints[i].position;
4557                     tempanimation.position[i][0] = DoRotation(tempanimation.position[i][0], 0, -yaw, 0);
4558                 }
4559             }
4560         }
4561
4562         if (findLength(&average) < 10 && !dead && skeleton.free) {
4563             skeleton.longdead += (2000 - findLength(&average)) * multiplier + multiplier;
4564             if (skeleton.longdead > (damage + 500) * 1.5) {
4565                 if (id == 0)pause_sound(whooshsound);
4566                 skeleton.free = 0;
4567                 velocity = 0;
4568                 XYZ middle;
4569                 middle = 0;
4570
4571                 terrainnormal = skeleton.joints[skeleton.jointlabels[groin]].position - skeleton.joints[skeleton.jointlabels[abdomen]].position;
4572                 if (skeleton.joints[skeleton.jointlabels[groin]].locked && skeleton.joints[skeleton.jointlabels[abdomen]].locked) {
4573                     terrainnormal = skeleton.joints[skeleton.jointlabels[groin]].position - skeleton.joints[skeleton.jointlabels[abdomen]].position;
4574                     middle = (skeleton.joints[skeleton.jointlabels[groin]].position + skeleton.joints[skeleton.jointlabels[abdomen]].position) / 2;
4575                 }
4576                 if (skeleton.joints[skeleton.jointlabels[abdomen]].locked && skeleton.joints[skeleton.jointlabels[neck]].locked) {
4577                     terrainnormal = skeleton.joints[skeleton.jointlabels[abdomen]].position - skeleton.joints[skeleton.jointlabels[neck]].position;
4578                     middle = (skeleton.joints[skeleton.jointlabels[neck]].position + skeleton.joints[skeleton.jointlabels[abdomen]].position) / 2;
4579                 }
4580                 if (skeleton.joints[skeleton.jointlabels[groin]].locked && skeleton.joints[skeleton.jointlabels[neck]].locked) {
4581                     terrainnormal = skeleton.joints[skeleton.jointlabels[groin]].position - skeleton.joints[skeleton.jointlabels[neck]].position;
4582                     middle = (skeleton.joints[skeleton.jointlabels[groin]].position + skeleton.joints[skeleton.jointlabels[neck]].position) / 2;
4583                 }
4584                 Normalise(&terrainnormal);
4585
4586                 targetyaw = -asin(0 - terrainnormal.x);
4587                 targetyaw *= 360 / 6.28;
4588                 if (terrainnormal.z < 0)targetyaw = 180 - targetyaw;
4589                 yaw = targetyaw;
4590
4591                 targettilt2 = asin(terrainnormal.y) * 180 / 3.14 * -1;
4592
4593
4594                 if (skeleton.forward.y < 0) {
4595                     animTarget = getupfrombackanim;
4596                     frameTarget = 0;
4597                     targettilt2 = 0;
4598                 }
4599                 if (skeleton.forward.y > -.3) {
4600                     animTarget = getupfromfrontanim;
4601                     yaw += 180;
4602                     targetyaw += 180;
4603                     targettilt2 *= -1;
4604                     frameTarget = 0;
4605                     targettilt2 = 0;
4606                 }
4607
4608                 if ((Random() % 8 == 0 && id != 0 && creature == rabbittype) || (Random() % 2 == 0 && id != 0 && creature == wolftype) || (id == 0 && crouchkeydown && (forwardkeydown || backkeydown || leftkeydown || rightkeydown))) {
4609                     animTarget = rollanim;
4610                     targetyaw = lookyaw;
4611                     if (id == 0) {
4612                         if (rightkeydown) {
4613                             targetyaw -= 90;
4614                             if (forwardkeydown)targetyaw += 45;
4615                             if (backkeydown)targetyaw -= 45;
4616                         }
4617                         if (leftkeydown) {
4618                             targetyaw += 90;
4619                             if (forwardkeydown)targetyaw -= 45;
4620                             if (backkeydown)targetyaw += 45;
4621                         }
4622                         if (backkeydown) {
4623                             if ( !leftkeydown && !rightkeydown)
4624                                 targetyaw += 180;
4625                         }
4626                         targetyaw += 180;
4627                     }
4628                 }
4629
4630                 if (abs(targettilt2) > 50)targettilt2 = 0;
4631                 animCurrent = tempanim;
4632                 frameCurrent = 0;
4633                 target = 0;
4634                 tilt2 = targettilt2;
4635
4636                 if (middle.y > 0 && animTarget != rollanim)targetoffset.y = middle.y + 1;
4637
4638                 for (i = 0; i < skeleton.num_joints; i++) {
4639                     tempanimation.position[i][0] = skeleton.joints[i].position;
4640                     tempanimation.position[i][0] = DoRotation(tempanimation.position[i][0], 0, -yaw, 0);
4641                 }
4642             }
4643         }
4644
4645         bool hasstaff;
4646         hasstaff = 0;
4647         if (num_weapons > 0)if (weapons[0].getType() == staff)hasstaff = 1;
4648         if (!skeleton.freefall && freefall && ((jumpkeydown && jumpkeydowntime < .2) || (hasstaff && rabbitkickragdoll)) && !dead) {
4649             if (velocity.y > -30) {
4650                 XYZ tempvelocity;
4651                 tempvelocity = velocity;
4652                 Normalise(&tempvelocity);
4653                 targetyaw = -asin(0 - tempvelocity.x);
4654                 targetyaw *= 360 / 6.28;
4655                 if (velocity.z < 0)targetyaw = 180 - targetyaw;
4656                 //targetyaw+=180;
4657
4658                 skeleton.free = 0;
4659                 if (dotproduct(&skeleton.forward, &tempvelocity) < 0) {
4660                     animTarget = rollanim;
4661                     frameTarget = 2;
4662                 } else {
4663                     animTarget = backhandspringanim;
4664                     targetyaw += 180;
4665                     frameTarget = 6;
4666                 }
4667                 target = 0;
4668
4669                 emit_sound_at(movewhooshsound, coords, 128.);
4670
4671                 animCurrent = animTarget;
4672                 frameCurrent = frameTarget - 1;
4673                 target = 0;
4674
4675                 velocity = 0;
4676
4677                 yaw = targetyaw;
4678                 tilt = 0;
4679                 targettilt = 0;
4680                 tilt2 = 0;
4681                 targettilt2 = 0;
4682             }
4683         }
4684         if (skeleton.freefall == 0)freefall = 0;
4685
4686     }
4687
4688     if (aitype != passivetype || skeleton.free == 1)
4689         if (findLengthfast(&velocity) > .1)
4690             for (i = 0; i < objects.numobjects; i++) {
4691                 if (objects.type[i] == firetype)
4692                     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) {
4693                         if (onfire) {
4694                             if (!objects.onfire[i]) {
4695                                 emit_sound_at(firestartsound, objects.position[i]);
4696                             }
4697                             objects.onfire[i] = 1;
4698                         }
4699                         if (!onfire) {
4700                             if (objects.onfire[i]) {
4701                                 CatchFire();
4702                             }
4703                         }
4704                     }
4705                 if (objects.type[i] == bushtype)
4706                     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) {
4707                         if (onfire) {
4708                             if (!objects.onfire[i]) {
4709                                 emit_sound_at(firestartsound, objects.position[i]);
4710                             }
4711                             objects.onfire[i] = 1;
4712                         }
4713
4714                         if (!onfire) {
4715                             if (objects.onfire[i]) {
4716                                 CatchFire();
4717                             }
4718                         }
4719                         if (objects.messedwith[i] <= 0) {
4720                             XYZ tempvel;
4721                             XYZ pos;
4722
4723                             emit_sound_at(bushrustle, coords, 40 * findLength(&velocity));
4724
4725                             if (id == 0) {
4726                                 envsound[numenvsounds] = coords;
4727                                 envsoundvol[numenvsounds] = 4 * findLength(&velocity);
4728                                 envsoundlife[numenvsounds] = .4;
4729                                 numenvsounds++;
4730                             }
4731
4732                             int howmany;
4733                             if (environment == grassyenvironment)howmany = findLength(&velocity) * 4;
4734                             if (environment == snowyenvironment)howmany = findLength(&velocity) * 2;
4735                             if (detail == 2)
4736                                 if (environment != desertenvironment)
4737                                     for (j = 0; j < howmany; j++) {
4738                                         tempvel.x = float(abs(Random() % 100) - 50) / 20;
4739                                         tempvel.y = float(abs(Random() % 100) - 50) / 20;
4740                                         tempvel.z = float(abs(Random() % 100) - 50) / 20;
4741                                         pos = coords;
4742                                         pos.y += 1;
4743                                         pos.x += float(abs(Random() % 100) - 50) / 200;
4744                                         pos.y += float(abs(Random() % 100) - 50) / 200;
4745                                         pos.z += float(abs(Random() % 100) - 50) / 200;
4746                                         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);
4747                                         Sprite::setLastSpriteSpecial(1);
4748                                     }
4749                             howmany = findLength(&velocity) * 4;
4750                             if (detail == 2)
4751                                 if (environment == snowyenvironment)
4752                                     for (j = 0; j < howmany; j++) {
4753                                         tempvel.x = float(abs(Random() % 100) - 50) / 20;
4754                                         tempvel.y = float(abs(Random() % 100) - 50) / 20;
4755                                         tempvel.z = float(abs(Random() % 100) - 50) / 20;
4756                                         pos = coords;
4757                                         pos.y += 1;
4758                                         pos.x += float(abs(Random() % 100) - 50) / 200;
4759                                         pos.y += float(abs(Random() % 100) - 50) / 200;
4760                                         pos.z += float(abs(Random() % 100) - 50) / 200;
4761                                         Sprite::MakeSprite(splintersprite, pos, tempvel * .3 + velocity * float(abs(Random() % 100)) / 100 / 2, 1, 1, 1, .1, 1);
4762                                         Sprite::setLastSpriteSpecial(2);
4763                                     }
4764                         }
4765                         objects.rotx[i] += velocity.x * multiplier * 6;
4766                         objects.roty[i] += velocity.z * multiplier * 6;
4767                         objects.messedwith[i] = .5;
4768                     }
4769                 XYZ tempcoord;
4770                 if (objects.type[i] == treeleavestype && environment != desertenvironment) {
4771                     if (objects.pitch[i] == 0)tempcoord = coords;
4772                     else {
4773                         tempcoord = coords - objects.position[i];
4774                         tempcoord = DoRotation(tempcoord, 0, -objects.yaw[i], 0);
4775                         tempcoord = DoRotation(tempcoord, -objects.pitch[i], 0, 0);
4776                         tempcoord += objects.position[i];
4777                     }
4778                     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]) {
4779                         if (objects.messedwith[i] <= 0) {
4780                             XYZ tempvel;
4781                             XYZ pos;
4782
4783                             emit_sound_at(bushrustle, coords, 40 * findLength(&velocity));
4784
4785                             if (id == 0) {
4786                                 envsound[numenvsounds] = coords;
4787                                 envsoundvol[numenvsounds] = 4 * findLength(&velocity);
4788                                 envsoundlife[numenvsounds] = .4;
4789                                 numenvsounds++;
4790                             }
4791
4792                             int howmany;
4793                             if (environment == grassyenvironment)howmany = findLength(&velocity) * 4;
4794                             if (environment == snowyenvironment)howmany = findLength(&velocity) * 2;
4795                             if (detail == 2)
4796                                 if (environment != desertenvironment)
4797                                     for (j = 0; j < howmany; j++) {
4798                                         tempvel.x = float(abs(Random() % 100) - 50) / 20;
4799                                         tempvel.y = float(abs(Random() % 100) - 50) / 20;
4800                                         tempvel.z = float(abs(Random() % 100) - 50) / 20;
4801                                         pos = coords;
4802                                         pos += velocity * .1;
4803                                         pos.y += 1;
4804                                         pos.x += float(abs(Random() % 100) - 50) / 150;
4805                                         pos.y += float(abs(Random() % 100) - 50) / 150;
4806                                         pos.z += float(abs(Random() % 100) - 50) / 150;
4807                                         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);
4808                                         Sprite::setLastSpriteSpecial(1);
4809                                     }
4810                             howmany = findLength(&velocity) * 4;
4811                             if (detail == 2)
4812                                 if (environment == snowyenvironment)
4813                                     for (j = 0; j < howmany; j++) {
4814                                         tempvel.x = float(abs(Random() % 100) - 50) / 20;
4815                                         tempvel.y = float(abs(Random() % 100) - 50) / 20;
4816                                         tempvel.z = float(abs(Random() % 100) - 50) / 20;
4817                                         pos = coords;
4818                                         pos += velocity * .1;
4819                                         pos.y += 1;
4820                                         pos.x += float(abs(Random() % 100) - 50) / 150;
4821                                         pos.y += float(abs(Random() % 100) - 50) / 150;
4822                                         pos.z += float(abs(Random() % 100) - 50) / 150;
4823                                         Sprite::MakeSprite(splintersprite, pos, tempvel * .3 + velocity * float(abs(Random() % 100)) / 100 / 2, 1, 1, 1, .1, 1);
4824                                         Sprite::setLastSpriteSpecial(2);
4825                                     }
4826                         }
4827                         objects.messedwith[i] = .5;
4828                     }
4829                 }
4830             }
4831
4832     if (!skeleton.free) {
4833         bool play;
4834         play = 0;
4835         if ((stunned > 0 || surprised > 0) && numplayers > 2 && aitype != passivetype)play = 1;
4836         if (hasvictim)
4837             if (aitype != passivetype && victim->skeleton.free && !victim->dead)play = 1;
4838         if (tutoriallevel == 1 && id != 0)play = 0;
4839         if (play && aitype != playercontrolled) {
4840             int whichsound = -1;
4841             i = abs(Random() % 4);
4842             if (speechdelay <= 0) {
4843                 if (creature == rabbittype) {
4844                     if (i == 0)whichsound = rabbitchitter;
4845                     if (i == 1)whichsound = rabbitchitter2;
4846                 }
4847                 if (creature == wolftype) {
4848                     if (i == 0)whichsound = growlsound;
4849                     if (i == 1)whichsound = growl2sound;
4850                 }
4851             }
4852             speechdelay = .3;
4853
4854             if (whichsound != -1) {
4855                 emit_sound_at(whichsound, coords);
4856             }
4857         }
4858
4859         if (animTarget == staggerbackhighanim)staggerdelay = 1;
4860         if (animTarget == staggerbackhardanim)staggerdelay = 1;
4861         staggerdelay -= multiplier;
4862         if (animTarget != crouchstabanim && animTarget != swordgroundstabanim && animTarget != staffgroundsmashanim)hasvictim = 1;
4863         if (velocity.y < -30 && animTarget == jumpdownanim)RagDoll(0);
4864         if (animCurrent != getIdle() && wasIdle() && animTarget != getIdle() && isIdle()) {
4865             animTarget = getIdle();
4866             frameTarget = 0;
4867             target = 0;
4868         }
4869         weaponmissdelay -= multiplier;
4870         highreversaldelay -= multiplier;
4871         lowreversaldelay -= multiplier;
4872         lastcollide -= multiplier;
4873         skiddelay -= multiplier;
4874         if (!isnormal(velocity.x) && velocity.x) {
4875             velocity = 0;
4876         }
4877         if (!isnormal(targettilt) && targettilt) {
4878             targettilt = 0;
4879         }
4880         if (!isnormal(targettilt2) && targettilt2) {
4881             targettilt2 = 0;
4882         }
4883         if (!isnormal(targetyaw) && targetyaw) {
4884             targetyaw = 0;
4885         }
4886
4887         if (animTarget == bounceidleanim || animTarget == wolfidle || animTarget == walkanim || animTarget == drawrightanim || animTarget == crouchdrawrightanim || animTarget == drawleftanim || animTarget == fightidleanim || animTarget == fightsidestep || animTarget == hanganim || isCrouch() || animTarget == backhandspringanim) {
4888             //open hands and close mouth
4889             if (righthandmorphend != 0 && righthandmorphness == targetrighthandmorphness) {
4890                 righthandmorphness = 0;
4891                 righthandmorphend = 0;
4892                 targetrighthandmorphness = 1;
4893             }
4894
4895             if (lefthandmorphend != 0 && lefthandmorphness == targetlefthandmorphness) {
4896                 lefthandmorphness = 0;
4897                 lefthandmorphend = 0;
4898                 targetlefthandmorphness = 1;
4899             }
4900
4901             if (headmorphend != 3 && headmorphend != 5 && headmorphstart != 3 && headmorphstart != 5 && headmorphend != 0 && headmorphness == targetheadmorphness) {
4902                 headmorphness = 0;
4903                 headmorphend = 0;
4904                 targetheadmorphness = 1;
4905             }
4906         }
4907
4908         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) {
4909             //open hands and mouth
4910             if (righthandmorphend != 0 && righthandmorphness == targetrighthandmorphness) {
4911                 righthandmorphness = 0;
4912                 righthandmorphend = 0;
4913                 targetrighthandmorphness = 1;
4914             }
4915
4916             if (lefthandmorphend != 0 && lefthandmorphness == targetlefthandmorphness) {
4917                 lefthandmorphness = 0;
4918                 lefthandmorphend = 0;
4919                 targetlefthandmorphness = 1;
4920             }
4921
4922             if (headmorphend != 1 && headmorphness == targetheadmorphness) {
4923                 headmorphness = 0;
4924                 headmorphend = 1;
4925                 targetheadmorphness = 1;
4926             }
4927         }
4928
4929         if (animTarget == jumpupanim || animTarget == crouchstabanim || animTarget == swordgroundstabanim || animTarget == swordfightidlebothanim || animTarget == blockhighleftanim || animTarget == blockhighleftanim) {
4930             //close hands and mouth
4931             if (righthandmorphend != 1 && righthandmorphness == targetrighthandmorphness) {
4932                 righthandmorphness = 0;
4933                 righthandmorphend = 1;
4934                 targetrighthandmorphness = 1;
4935             }
4936
4937             if (lefthandmorphend != 1 && lefthandmorphness == targetlefthandmorphness) {
4938                 lefthandmorphness = 0;
4939                 lefthandmorphend = 1;
4940                 targetlefthandmorphness = 1;
4941             }
4942
4943             if (headmorphend != 0 && headmorphness == targetheadmorphness) {
4944                 headmorphness = 0;
4945                 headmorphend = 0;
4946                 targetheadmorphness = 1;
4947             }
4948         }
4949
4950         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) {
4951             //close hands and yell
4952             if (righthandmorphend != 1 && righthandmorphness == targetrighthandmorphness) {
4953                 righthandmorphness = 0;
4954                 righthandmorphend = 1;
4955                 targetrighthandmorphness = 1;
4956             }
4957
4958             if (lefthandmorphend != 1 && lefthandmorphness == targetlefthandmorphness) {
4959                 lefthandmorphness = 0;
4960                 lefthandmorphend = 1;
4961                 targetlefthandmorphness = 1;
4962             }
4963
4964             if (headmorphend != 2 && headmorphness == targetheadmorphness) {
4965                 headmorphness = 1;
4966                 headmorphend = 2;
4967                 targetheadmorphness = 1;
4968             }
4969         }
4970
4971         bool behind;
4972         behind = 0;
4973         if (hasvictim) {
4974             if (victim != this && !victim->dead && victim->aitype != passivetype && victim->aitype != searchtype && aitype != passivetype && aitype != searchtype && victim->id < numplayers && aitype != passivetype) {
4975                 behind = (normaldotproduct(facing, coords - victim->coords) > 0);
4976             }
4977         }
4978
4979         if (!dead && animTarget != hurtidleanim)
4980             if (behind || animTarget == killanim || animTarget == knifethrowanim || animTarget == knifefollowanim || animTarget == spinkickreversalanim || animTarget == rabbitkickreversedanim || animTarget == jumpreversedanim) {
4981                 if (headmorphend != 4 || headmorphness == targetheadmorphness) {
4982                     headmorphend = 4;
4983                     //headmorphness=1;
4984                     targetheadmorphness = 1;
4985                 }
4986             }
4987
4988         if (weaponactive != -1) {
4989             if (weapons[weaponids[weaponactive]].getType() != staff) {
4990                 righthandmorphstart = 1;
4991                 righthandmorphend = 1;
4992             }
4993             if (weapons[weaponids[weaponactive]].getType() == staff) {
4994                 righthandmorphstart = 2;
4995                 righthandmorphend = 2;
4996             }
4997             targetrighthandmorphness = 1;
4998         }
4999
5000         terrainnormal = terrain.getNormal(coords.x, coords.z);
5001
5002         if (animation[animTarget].attack != reversal) {
5003             if (!isnormal(coords.x))
5004                 coords = oldcoords;
5005             oldcoords = coords;
5006         }
5007
5008         flatfacing = 0;
5009         flatfacing.z = 1;
5010
5011         flatfacing = DoRotation(flatfacing, 0, yaw, 0);
5012         facing = flatfacing;
5013         ReflectVector(&facing, terrainnormal);
5014         Normalise(&facing);
5015
5016         if (isRun() || animTarget == sneakanim || animTarget == rollanim || animTarget == walkanim) {
5017             if (onterrain)targettilt2 = -facing.y * 20;
5018             else targettilt2 = 0;
5019         }
5020         onterrain = 0;
5021         if (!isRun() && !animation[animTarget].attack && animTarget != getupfromfrontanim && animTarget != getupfrombackanim && animTarget != sneakanim)targettilt2 = 0;
5022         if (animTarget == jumpupanim || animTarget == jumpdownanim || isFlip()) {
5023             flatvelocity = velocity;
5024             flatvelocity.y = 0;
5025             flatvelspeed = findLength(&flatvelocity);
5026             targettilt = flatvelspeed * fast_sqrt(abs(velocity.y) * .7) * normaldotproduct(DoRotation(flatfacing, 0, -90, 0), flatvelocity);
5027             targettilt2 = flatvelspeed * fast_sqrt(abs(velocity.y) * .7) * normaldotproduct(flatfacing, flatvelocity);
5028             if (velocity.y < 0)targettilt2 *= -1;
5029             if (velocity.y < 0)targettilt *= -1;
5030             if (targettilt > 25)targettilt = 25;
5031             if (targettilt < -25)targettilt = -25;
5032         }
5033
5034         if (targettilt2 > 45)targettilt2 = 45;
5035         if (targettilt2 < -45)targettilt2 = -45;
5036         if (abs(tilt2 - targettilt2) < multiplier * 400)tilt2 = targettilt2;
5037         else if (tilt2 > targettilt2) {
5038             tilt2 -= multiplier * 400;
5039         } else if (tilt2 < targettilt2) {
5040             tilt2 += multiplier * 400;
5041         }
5042         if (!animation[animTarget].attack && animTarget != getupfrombackanim && animTarget != getupfromfrontanim) {
5043             if (tilt2 > 25)tilt2 = 25;
5044             if (tilt2 < -25)tilt2 = -25;
5045         }
5046
5047         if (!isnormal(targettilt) && targettilt) {
5048             targettilt = 0;
5049         }
5050         if (!isnormal(targettilt2) && targettilt2) {
5051             targettilt2 = 0;
5052         }
5053
5054         //Running velocity
5055         //if(!creature==wolftype||animTarget==rabbitkickanim)
5056         if (animTarget == rabbittackleanim) {
5057             velocity += facing * multiplier * speed * 700 * scale;
5058             velspeed = findLength(&velocity);
5059             if (velspeed > speed * 65 * scale) {
5060                 velocity /= velspeed;
5061                 velspeed = speed * 65 * scale;
5062                 velocity *= velspeed;
5063             }
5064             velocity.y += gravity * multiplier * 20;
5065             ReflectVector(&velocity, terrain.getNormal(coords.x, coords.z));
5066             velspeed = findLength(&velocity);
5067             velocity = flatfacing * velspeed;
5068         }
5069         if (animTarget != rabbitrunninganim && animTarget != wolfrunninganim) {
5070             if (isRun() || animTarget == rabbitkickanim) {
5071                 velocity += facing * multiplier * speed * 700 * scale;
5072                 velspeed = findLength(&velocity);
5073                 if (velspeed > speed * 45 * scale) {
5074                     velocity /= velspeed;
5075                     velspeed = speed * 45 * scale;
5076                     velocity *= velspeed;
5077                 }
5078                 velocity.y += gravity * multiplier * 20;
5079                 ReflectVector(&velocity, terrain.getNormal(coords.x, coords.z));
5080                 velspeed = findLength(&velocity);
5081                 if (velspeed < speed * 30 * scale)velspeed = speed * 30 * scale;
5082                 velocity = flatfacing * velspeed;
5083             }
5084         } else if (isRun()) {
5085             velocity += facing * multiplier * speed * 700 * scale;
5086             velspeed = findLength(&velocity);
5087             if (creature == rabbittype) {
5088                 if (velspeed > speed * 55 * scale) {
5089                     velocity /= velspeed;
5090                     velspeed = speed * 55 * scale;
5091                     velocity *= velspeed;
5092                 }
5093             }
5094             if (creature == wolftype) {
5095                 if (velspeed > speed * 75 * scale) {
5096                     velocity /= velspeed;
5097                     velspeed = speed * 75 * scale;
5098                     velocity *= velspeed;
5099                 }
5100             }
5101             velocity.y += gravity * multiplier * 20;
5102             ReflectVector(&velocity, terrain.getNormal(coords.x, coords.z));
5103             velspeed = findLength(&velocity);
5104             velocity = flatfacing * velspeed;
5105         }
5106
5107         if (animTarget == rollanim && animation[animTarget].label[frameTarget] != 6) {
5108             velocity += facing * multiplier * speed * 700 * scale;
5109             velspeed = findLength(&velocity);
5110             if (velspeed > speed * 45 * scale) {
5111                 velocity /= velspeed;
5112                 velspeed = speed * 45 * scale;
5113                 velocity *= velspeed;
5114             }
5115             velocity.y += gravity * multiplier * 20;
5116             ReflectVector(&velocity, terrain.getNormal(coords.x, coords.z));
5117             velspeed = findLength(&velocity);
5118             velocity = flatfacing * velspeed;
5119         }
5120
5121
5122         /*if(animCurrent==rollanim&&(isCrouch()||isIdle())){
5123         velocity+=facing*multiplier*speed*700*scale;
5124         velspeed=findLength(&velocity);
5125         if(velspeed>speed*25*scale){
5126         velocity/=velspeed;
5127         velspeed=speed*25*scale;
5128         velocity*=velspeed;
5129         }
5130         velocity.y+=gravity*multiplier*20;
5131         ReflectVector(&velocity,terrain.getNormal(coords.x,coords.z));
5132         velspeed=findLength(&velocity);
5133         velocity=flatfacing*velspeed;
5134         }*/
5135
5136         if (animTarget == sneakanim || animTarget == walkanim) {
5137             velocity += facing * multiplier * speed * 700 * scale;
5138             velspeed = findLength(&velocity);
5139             if (velspeed > speed * 12 * scale) {
5140                 velocity /= velspeed;
5141                 velspeed = speed * 12 * scale;
5142                 velocity *= velspeed;
5143             }
5144             velocity.y += gravity * multiplier * 20;
5145             ReflectVector(&velocity, terrain.getNormal(coords.x, coords.z));
5146             velspeed = findLength(&velocity);
5147             velocity = flatfacing * velspeed;
5148         }
5149
5150         if ((animTarget == fightidleanim || animTarget == knifefightidleanim) && (animCurrent == bounceidleanim || animCurrent == hurtidleanim)) {
5151             velocity += facing * multiplier * speed * 700 * scale;
5152             velspeed = findLength(&velocity);
5153             if (velspeed > speed * 2 * scale) {
5154                 velocity /= velspeed;
5155                 velspeed = speed * 2 * scale;
5156                 velocity *= velspeed;
5157             }
5158             velocity.y += gravity * multiplier * 20;
5159             ReflectVector(&velocity, terrain.getNormal(coords.x, coords.z));
5160             velspeed = findLength(&velocity);
5161             velocity = flatfacing * velspeed;
5162         }
5163
5164
5165         if ((animTarget == bounceidleanim || animCurrent == hurtidleanim) && (animCurrent == fightidleanim || animCurrent == knifefightidleanim)) {
5166             velocity -= facing * multiplier * speed * 700 * scale;
5167             velspeed = findLength(&velocity);
5168             if (velspeed > speed * 2 * scale) {
5169                 velocity /= velspeed;
5170                 velspeed = speed * 2 * scale;
5171                 velocity *= velspeed;
5172             }
5173             velocity.y += gravity * multiplier * 20;
5174             ReflectVector(&velocity, terrain.getNormal(coords.x, coords.z));
5175             velspeed = findLength(&velocity);
5176             velocity = flatfacing * velspeed * -1;
5177         }
5178
5179         if (animTarget == fightsidestep) {
5180             velocity += DoRotation(facing * multiplier * speed * 700 * scale, 0, -90, 0);
5181             velspeed = findLength(&velocity);
5182             if (velspeed > speed * 12 * scale) {
5183                 velocity /= velspeed;
5184                 velspeed = speed * 12 * scale;
5185                 velocity *= velspeed;
5186             }
5187             velocity.y += gravity * multiplier * 20;
5188             ReflectVector(&velocity, terrain.getNormal(coords.x, coords.z));
5189             velspeed = findLength(&velocity);
5190             velocity = DoRotation(flatfacing * velspeed, 0, -90, 0);
5191         }
5192
5193         if (animTarget == staggerbackhighanim) {
5194             coords -= facing * multiplier * speed * 16 * scale;
5195             velocity = 0;
5196         }
5197         if (animTarget == staggerbackhardanim && animation[staggerbackhardanim].label[frameTarget] != 6) {
5198             coords -= facing * multiplier * speed * 20 * scale;
5199             velocity = 0;
5200         }
5201
5202         if (animTarget == backhandspringanim) {
5203             //coords-=facing*multiplier*50*scale;
5204             velocity += facing * multiplier * speed * 700 * scale * -1;
5205             velspeed = findLength(&velocity);
5206             if (velspeed > speed * 50 * scale) {
5207                 velocity /= velspeed;
5208                 velspeed = speed * 50 * scale;
5209                 velocity *= velspeed;
5210             }
5211             velocity.y += gravity * multiplier * 20;
5212             ReflectVector(&velocity, terrain.getNormal(coords.x, coords.z));
5213             velspeed = findLength(&velocity);
5214             velocity = flatfacing * velspeed * -1;
5215         }
5216         if (animTarget == dodgebackanim) {
5217             //coords-=facing*multiplier*50*scale;
5218             velocity += facing * multiplier * speed * 700 * scale * -1;
5219             velspeed = findLength(&velocity);
5220             if (velspeed > speed * 60 * scale) {
5221                 velocity /= velspeed;
5222                 velspeed = speed * 60 * scale;
5223                 velocity *= velspeed;
5224             }
5225             velocity.y += gravity * multiplier * 20;
5226             ReflectVector(&velocity, terrain.getNormal(coords.x, coords.z));
5227             velspeed = findLength(&velocity);
5228             velocity = flatfacing * velspeed * -1;
5229         }
5230
5231         if (animTarget == jumpupanim || animTarget == jumpdownanim || isFlip()) {
5232             velspeed = findLength(&velocity);
5233         }
5234
5235
5236         if (animTarget == jumpupanim || animTarget == jumpdownanim || isFlip()) {
5237             velocity.y += gravity * multiplier;
5238         }
5239
5240         if (animTarget != climbanim && animTarget != hanganim && !isWallJump())coords += velocity * multiplier;
5241
5242         if (coords.y < terrain.getHeight(coords.x, coords.z) && (animTarget == jumpdownanim || animTarget == jumpupanim || isFlip())) {
5243             if (isFlip() && animation[animTarget].label[frameTarget] == 7)RagDoll(0);
5244
5245             if (animTarget == jumpupanim) {
5246                 jumppower = -4;
5247                 animTarget = getIdle();
5248             }
5249             target = 0;
5250             frameTarget = 0;
5251             onterrain = 1;
5252
5253             if (id == 0) {
5254                 pause_sound(whooshsound);
5255                 OPENAL_SetVolume(channels[whooshsound], 0);
5256             }
5257
5258             if (animTarget == jumpdownanim || isFlip()) {
5259                 if (isFlip())jumppower = -4;
5260                 animTarget = getLanding();
5261                 emit_sound_at(landsound, coords, 128.);
5262
5263                 if (id == 0) {
5264                     envsound[numenvsounds] = coords;
5265                     envsoundvol[numenvsounds] = 16;
5266                     envsoundlife[numenvsounds] = .4;
5267                     numenvsounds++;
5268                 }
5269             }
5270         }
5271
5272         if (animTarget != jumpupanim && animTarget != jumpdownanim && !isFlip() && animTarget != climbanim && animTarget != hanganim && !isWallJump())coords.y += gravity * multiplier * 2;
5273         if (animTarget != jumpupanim && animTarget != jumpdownanim && !isFlip() && coords.y < terrain.getHeight(coords.x, coords.z)) {
5274             coords.y = terrain.getHeight(coords.x, coords.z);
5275             onterrain = 1;
5276         }
5277
5278
5279         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)) {
5280             velspeed = findLength(&velocity);
5281             velocity.y = 0;
5282             if (velspeed < multiplier * 300 * scale) {
5283                 velocity = 0;
5284             } else velocity -= velocity / velspeed * multiplier * 300 * scale;
5285             if (velspeed > 5 && (isLanding() || isLandhard())) {
5286                 skiddingdelay += multiplier;
5287                 if (skiddelay <= 0) {
5288                     FootLand(0, .5);
5289                     FootLand(1, .5);
5290                     skiddelay = .02;
5291                 }
5292             } else skiddingdelay = 0;
5293         }
5294
5295         if (isLandhard()) {
5296             velspeed = findLength(&velocity);
5297             velocity.y = 0;
5298             if (velspeed < multiplier * 600 * scale) {
5299                 velocity = 0;
5300             } else velocity -= velocity / velspeed * multiplier * 600 * scale;
5301             velocity = 0;
5302             if (velspeed > 5 && (isLanding() || isLandhard())) {
5303                 skiddingdelay += multiplier;
5304                 if (skiddelay <= 0) {
5305                     FootLand(0, .5);
5306                     FootLand(1, .5);
5307                     skiddelay = .02;
5308                 }
5309             } else skiddingdelay = 0;
5310         }
5311
5312         if (skiddingdelay < 0)skiddingdelay += multiplier;
5313         if (skiddingdelay > .02 && !forwardkeydown && !backkeydown && !leftkeydown && !rightkeydown && !jumpkeydown && isLanding() && !landhard) {
5314             skiddingdelay = -1;
5315             if (!onterrain || environment == grassyenvironment) {
5316                 emit_sound_at(skidsound, coords, 128 * velspeed / 10);
5317             } else {
5318                 emit_sound_at(snowskidsound, coords, 128 * velspeed / 10);
5319             }
5320         }
5321
5322         if (animation[animTarget].attack == normalattack && animTarget != rabbitkickanim && !victim->skeleton.free) {
5323             terrainnormal = victim->coords - coords;
5324             Normalise(&terrainnormal);
5325             targetyaw = -asin(0 - terrainnormal.x);
5326             targetyaw *= 360 / 6.28;
5327             if (terrainnormal.z < 0)targetyaw = 180 - targetyaw;
5328             targettilt2 = -asin(terrainnormal.y) * 360 / 6.28; //*-70;
5329         }
5330
5331         if (animation[animTarget].attack == reversal && animTarget != rabbittacklinganim) {
5332             targetyaw = victim->targetyaw;
5333         }
5334         if (animTarget == rabbittacklinganim) {
5335             coords = victim->coords;
5336         }
5337     }
5338     skeleton.oldfree = skeleton.free;
5339
5340     XYZ midterrain;
5341     midterrain = 0;
5342     midterrain.x = terrain.size * terrain.scale / 2;
5343     midterrain.z = terrain.size * terrain.scale / 2;
5344     if (distsqflat(&coords, &midterrain) > (terrain.size * terrain.scale / 2 - viewdistance) * (terrain.size * terrain.scale / 2 - viewdistance)) {
5345         XYZ tempposit;
5346         tempposit = coords - midterrain;
5347         tempposit.y = 0;
5348         Normalise(&tempposit);
5349         tempposit *= (terrain.size * terrain.scale / 2 - viewdistance);
5350         coords.x = tempposit.x + midterrain.x;
5351         coords.z = tempposit.z + midterrain.z;
5352     }
5353 }
5354
5355 int Person::DrawSkeleton()
5356 {
5357     int oldplayerdetail;
5358     if ((frustum.SphereInFrustum(coords.x, coords.y + scale * 3, coords.z, scale * 8) && distsq(&viewer, &coords) < viewdistance * viewdistance) || skeleton.free == 3) {
5359         if (onterrain && (isIdle() || isCrouch() || wasIdle() || wasCrouch()) && !skeleton.free) {
5360             calcrot = 1;
5361         }
5362
5363         if (headless) {
5364             headmorphness = 0;
5365             headmorphstart = 6;
5366             headmorphend = 6;
5367         }
5368
5369         glAlphaFunc(GL_GREATER, 0.0001);
5370         XYZ terrainlight;
5371         float terrainheight;
5372         float distance;
5373         if (!isnormal(yaw))yaw = 0;
5374         if (!isnormal(tilt))tilt = 0;
5375         if (!isnormal(tilt2))tilt2 = 0;
5376         oldplayerdetail = playerdetail;
5377         playerdetail = 0;
5378         if (distsq(&viewer, &coords) < viewdistance * viewdistance / 32 && detail == 2) {
5379             playerdetail = 1;
5380         }
5381         if (distsq(&viewer, &coords) < viewdistance * viewdistance / 128 && detail == 1) {
5382             playerdetail = 1;
5383         }
5384         if (distsq(&viewer, &coords) < viewdistance * viewdistance / 256 && (detail != 1 && detail != 2)) {
5385             playerdetail = 1;
5386         }
5387         if (id == 0)
5388             playerdetail = 1;
5389         if (playerdetail != oldplayerdetail) {
5390             updatedelay = 0;
5391             normalsupdatedelay = 0;
5392         }
5393         static float updatedelaychange;
5394         static float morphness;
5395         static float framemult;
5396         if (calcrot) {
5397             skeleton.FindForwards();
5398             if (howactive == typesittingwall) {
5399                 skeleton.specialforward[1] = 0;
5400                 skeleton.specialforward[1].z = 1;
5401             }
5402         }
5403         static XYZ mid;
5404         static float M[16];
5405         static int i, j, k;
5406         static int weaponattachmuscle;
5407         static int weaponrotatemuscle;
5408         static XYZ weaponpoint;
5409         static int start, endthing;
5410         if ((dead != 2 || skeleton.free != 2) && updatedelay <= 0) {
5411             if (!isSleeping() && !isSitting()) {
5412                 if (onterrain && ((isIdle() || isCrouch() || isLanding() || isLandhard() || animTarget == drawrightanim || animTarget == drawleftanim || animTarget == crouchdrawrightanim) && (wasIdle() || wasCrouch() || wasLanding() || wasLandhard() || animCurrent == drawrightanim || animCurrent == drawleftanim || animCurrent == crouchdrawrightanim)) && !skeleton.free) {
5413                     XYZ point, newpoint, change, change2;
5414                     point = DoRotation(skeleton.joints[skeleton.jointlabels[leftfoot]].position, 0, yaw, 0) * scale + coords;
5415                     heightleft = terrain.getHeight(point.x, point.z) + .04;
5416                     point.y = heightleft;
5417                     change = skeleton.joints[skeleton.jointlabels[leftankle]].position - skeleton.joints[skeleton.jointlabels[leftfoot]].position;
5418                     change2 = skeleton.joints[skeleton.jointlabels[leftknee]].position - skeleton.joints[skeleton.jointlabels[leftfoot]].position;
5419                     skeleton.joints[skeleton.jointlabels[leftfoot]].position = DoRotation((point - coords) / scale, 0, -yaw, 0);
5420                     skeleton.joints[skeleton.jointlabels[leftankle]].position = skeleton.joints[skeleton.jointlabels[leftfoot]].position + change;
5421                     skeleton.joints[skeleton.jointlabels[leftknee]].position = (skeleton.joints[skeleton.jointlabels[leftfoot]].position + change2) / 2 + (skeleton.joints[skeleton.jointlabels[leftknee]].position) / 2;
5422
5423                     point = DoRotation(skeleton.joints[skeleton.jointlabels[rightfoot]].position, 0, yaw, 0) * scale + coords;
5424                     heightright = terrain.getHeight(point.x, point.z) + .04;
5425                     point.y = heightright;
5426                     change = skeleton.joints[skeleton.jointlabels[rightankle]].position - skeleton.joints[skeleton.jointlabels[rightfoot]].position;
5427                     change2 = skeleton.joints[skeleton.jointlabels[rightknee]].position - skeleton.joints[skeleton.jointlabels[rightfoot]].position;
5428                     skeleton.joints[skeleton.jointlabels[rightfoot]].position = DoRotation((point - coords) / scale, 0, -yaw, 0);
5429                     skeleton.joints[skeleton.jointlabels[rightankle]].position = skeleton.joints[skeleton.jointlabels[rightfoot]].position + change;
5430                     skeleton.joints[skeleton.jointlabels[rightknee]].position = (skeleton.joints[skeleton.jointlabels[rightfoot]].position + change2) / 2 + (skeleton.joints[skeleton.jointlabels[rightknee]].position) / 2;
5431                     skeleton.DoConstraints(&coords, &scale);
5432
5433                     if (creature == wolftype) {
5434                         point = DoRotation(skeleton.joints[skeleton.jointlabels[leftfoot]].position, 0, yaw, 0) * scale + coords;
5435                         heightleft = terrain.getHeight(point.x, point.z) + .04;
5436                         point.y = heightleft;
5437                         change = skeleton.joints[skeleton.jointlabels[leftankle]].position - skeleton.joints[skeleton.jointlabels[leftfoot]].position;
5438                         change2 = skeleton.joints[skeleton.jointlabels[leftknee]].position - skeleton.joints[skeleton.jointlabels[leftfoot]].position;
5439                         skeleton.joints[skeleton.jointlabels[leftfoot]].position = DoRotation((point - coords) / scale, 0, -yaw, 0);
5440                         skeleton.joints[skeleton.jointlabels[leftankle]].position = skeleton.joints[skeleton.jointlabels[leftfoot]].position + change;
5441                         skeleton.joints[skeleton.jointlabels[leftknee]].position = (skeleton.joints[skeleton.jointlabels[leftfoot]].position + change2) / 2 + (skeleton.joints[skeleton.jointlabels[leftknee]].position) / 2;
5442
5443                         point = DoRotation(skeleton.joints[skeleton.jointlabels[rightfoot]].position, 0, yaw, 0) * scale + coords;
5444                         heightright = terrain.getHeight(point.x, point.z) + .04;
5445                         point.y = heightright;
5446                         change = skeleton.joints[skeleton.jointlabels[rightankle]].position - skeleton.joints[skeleton.jointlabels[rightfoot]].position;
5447                         change2 = skeleton.joints[skeleton.jointlabels[rightknee]].position - skeleton.joints[skeleton.jointlabels[rightfoot]].position;
5448                         skeleton.joints[skeleton.jointlabels[rightfoot]].position = DoRotation((point - coords) / scale, 0, -yaw, 0);
5449                         skeleton.joints[skeleton.jointlabels[rightankle]].position = skeleton.joints[skeleton.jointlabels[rightfoot]].position + change;
5450                         skeleton.joints[skeleton.jointlabels[rightknee]].position = (skeleton.joints[skeleton.jointlabels[rightfoot]].position + change2) / 2 + (skeleton.joints[skeleton.jointlabels[rightknee]].position) / 2;
5451                         skeleton.DoConstraints(&coords, &scale);
5452                     }
5453                 }
5454                 if (onterrain && ((isIdle() || isCrouch() || isLanding() || isLandhard() || animTarget == drawrightanim || animTarget == drawleftanim || animTarget == crouchdrawrightanim) && !(wasIdle() || wasCrouch() || wasLanding() || wasLandhard() || animCurrent == drawrightanim || animCurrent == drawleftanim || animCurrent == crouchdrawrightanim)) && !skeleton.free) {
5455                     XYZ point, newpoint, change, change2;
5456                     point = DoRotation(skeleton.joints[skeleton.jointlabels[leftfoot]].position, 0, yaw, 0) * scale + coords;
5457                     heightleft = terrain.getHeight(point.x, point.z) + .04;
5458                     point.y = heightleft;
5459                     change = skeleton.joints[skeleton.jointlabels[leftankle]].position - skeleton.joints[skeleton.jointlabels[leftfoot]].position;
5460                     change2 = skeleton.joints[skeleton.jointlabels[leftknee]].position - skeleton.joints[skeleton.jointlabels[leftfoot]].position;
5461                     skeleton.joints[skeleton.jointlabels[leftfoot]].position = DoRotation((point - coords) / scale, 0, -yaw, 0) * target + skeleton.joints[skeleton.jointlabels[leftfoot]].position * (1 - target);
5462                     skeleton.joints[skeleton.jointlabels[leftankle]].position = skeleton.joints[skeleton.jointlabels[leftfoot]].position + change;
5463                     skeleton.joints[skeleton.jointlabels[leftknee]].position = (skeleton.joints[skeleton.jointlabels[leftfoot]].position + change2) / 2 + (skeleton.joints[skeleton.jointlabels[leftknee]].position) / 2;
5464
5465                     point = DoRotation(skeleton.joints[skeleton.jointlabels[rightfoot]].position, 0, yaw, 0) * scale + coords;
5466                     heightright = terrain.getHeight(point.x, point.z) + .04;
5467                     point.y = heightright;
5468                     change = skeleton.joints[skeleton.jointlabels[rightankle]].position - skeleton.joints[skeleton.jointlabels[rightfoot]].position;
5469                     change2 = skeleton.joints[skeleton.jointlabels[rightknee]].position - skeleton.joints[skeleton.jointlabels[rightfoot]].position;
5470                     skeleton.joints[skeleton.jointlabels[rightfoot]].position = DoRotation((point - coords) / scale, 0, -yaw, 0) * target + skeleton.joints[skeleton.jointlabels[rightfoot]].position * (1 - target);
5471                     skeleton.joints[skeleton.jointlabels[rightankle]].position = skeleton.joints[skeleton.jointlabels[rightfoot]].position + change;
5472                     skeleton.joints[skeleton.jointlabels[rightknee]].position = (skeleton.joints[skeleton.jointlabels[rightfoot]].position + change2) / 2 + (skeleton.joints[skeleton.jointlabels[rightknee]].position) / 2;
5473                     skeleton.DoConstraints(&coords, &scale);
5474
5475                     if (creature == wolftype) {
5476                         point = DoRotation(skeleton.joints[skeleton.jointlabels[leftfoot]].position, 0, yaw, 0) * scale + coords;
5477                         heightleft = terrain.getHeight(point.x, point.z) + .04;
5478                         point.y = heightleft;
5479                         change = skeleton.joints[skeleton.jointlabels[leftankle]].position - skeleton.joints[skeleton.jointlabels[leftfoot]].position;
5480                         change2 = skeleton.joints[skeleton.jointlabels[leftknee]].position - skeleton.joints[skeleton.jointlabels[leftfoot]].position;
5481                         skeleton.joints[skeleton.jointlabels[leftfoot]].position = DoRotation((point - coords) / scale, 0, -yaw, 0) * target + skeleton.joints[skeleton.jointlabels[leftfoot]].position * (1 - target);
5482                         skeleton.joints[skeleton.jointlabels[leftankle]].position = skeleton.joints[skeleton.jointlabels[leftfoot]].position + change;
5483                         skeleton.joints[skeleton.jointlabels[leftknee]].position = (skeleton.joints[skeleton.jointlabels[leftfoot]].position + change2) / 2 + (skeleton.joints[skeleton.jointlabels[leftknee]].position) / 2;
5484
5485                         point = DoRotation(skeleton.joints[skeleton.jointlabels[rightfoot]].position, 0, yaw, 0) * scale + coords;
5486                         heightright = terrain.getHeight(point.x, point.z) + .04;
5487                         point.y = heightright;
5488                         change = skeleton.joints[skeleton.jointlabels[rightankle]].position - skeleton.joints[skeleton.jointlabels[rightfoot]].position;
5489                         change2 = skeleton.joints[skeleton.jointlabels[rightknee]].position - skeleton.joints[skeleton.jointlabels[rightfoot]].position;
5490                         skeleton.joints[skeleton.jointlabels[rightfoot]].position = DoRotation((point - coords) / scale, 0, -yaw, 0) * target + skeleton.joints[skeleton.jointlabels[rightfoot]].position * (1 - target);
5491                         skeleton.joints[skeleton.jointlabels[rightankle]].position = skeleton.joints[skeleton.jointlabels[rightfoot]].position + change;
5492                         skeleton.joints[skeleton.jointlabels[rightknee]].position = (skeleton.joints[skeleton.jointlabels[rightfoot]].position + change2) / 2 + (skeleton.joints[skeleton.jointlabels[rightknee]].position) / 2;
5493                         skeleton.DoConstraints(&coords, &scale);
5494                     }
5495                 }
5496
5497                 if (onterrain && (!(isIdle() || isCrouch() || isLanding() || isLandhard() || animTarget == drawrightanim || animTarget == drawleftanim || animTarget == crouchdrawrightanim) && (wasIdle() || wasCrouch() || wasLanding() || wasLandhard() || animCurrent == drawrightanim || animCurrent == drawleftanim || animCurrent == crouchdrawrightanim)) && !skeleton.free) {
5498                     XYZ point, newpoint, change, change2;
5499                     point = DoRotation(skeleton.joints[skeleton.jointlabels[leftfoot]].position, 0, yaw, 0) * scale + coords;
5500                     heightleft = terrain.getHeight(point.x, point.z) + .04;
5501                     point.y = heightleft;
5502                     change = skeleton.joints[skeleton.jointlabels[leftankle]].position - skeleton.joints[skeleton.jointlabels[leftfoot]].position;
5503                     change2 = skeleton.joints[skeleton.jointlabels[leftknee]].position - skeleton.joints[skeleton.jointlabels[leftfoot]].position;
5504                     skeleton.joints[skeleton.jointlabels[leftfoot]].position = DoRotation((point - coords) / scale, 0, -yaw, 0) * (1 - target) + skeleton.joints[skeleton.jointlabels[leftfoot]].position * target;
5505                     skeleton.joints[skeleton.jointlabels[leftankle]].position = skeleton.joints[skeleton.jointlabels[leftfoot]].position + change;
5506                     skeleton.joints[skeleton.jointlabels[leftknee]].position = (skeleton.joints[skeleton.jointlabels[leftfoot]].position + change2) / 2 + (skeleton.joints[skeleton.jointlabels[leftknee]].position) / 2;
5507
5508                     point = DoRotation(skeleton.joints[skeleton.jointlabels[rightfoot]].position, 0, yaw, 0) * scale + coords;
5509                     heightright = terrain.getHeight(point.x, point.z) + .04;
5510                     point.y = heightright;
5511                     change = skeleton.joints[skeleton.jointlabels[rightankle]].position - skeleton.joints[skeleton.jointlabels[rightfoot]].position;
5512                     change2 = skeleton.joints[skeleton.jointlabels[rightknee]].position - skeleton.joints[skeleton.jointlabels[rightfoot]].position;
5513                     skeleton.joints[skeleton.jointlabels[rightfoot]].position = DoRotation((point - coords) / scale, 0, -yaw, 0) * (1 - target) + skeleton.joints[skeleton.jointlabels[rightfoot]].position * target;
5514                     skeleton.joints[skeleton.jointlabels[rightankle]].position = skeleton.joints[skeleton.jointlabels[rightfoot]].position + change;
5515                     skeleton.joints[skeleton.jointlabels[rightknee]].position = (skeleton.joints[skeleton.jointlabels[rightfoot]].position + change2) / 2 + (skeleton.joints[skeleton.jointlabels[rightknee]].position) / 2;
5516                     skeleton.DoConstraints(&coords, &scale);
5517
5518                     if (creature == wolftype) {
5519                         point = DoRotation(skeleton.joints[skeleton.jointlabels[leftfoot]].position, 0, yaw, 0) * scale + coords;
5520                         heightleft = terrain.getHeight(point.x, point.z) + .04;
5521                         point.y = heightleft;
5522                         change = skeleton.joints[skeleton.jointlabels[leftankle]].position - skeleton.joints[skeleton.jointlabels[leftfoot]].position;
5523                         change2 = skeleton.joints[skeleton.jointlabels[leftknee]].position - skeleton.joints[skeleton.jointlabels[leftfoot]].position;
5524                         skeleton.joints[skeleton.jointlabels[leftfoot]].position = DoRotation((point - coords) / scale, 0, -yaw, 0) * (1 - target) + skeleton.joints[skeleton.jointlabels[leftfoot]].position * target;
5525                         skeleton.joints[skeleton.jointlabels[leftankle]].position = skeleton.joints[skeleton.jointlabels[leftfoot]].position + change;
5526                         skeleton.joints[skeleton.jointlabels[leftknee]].position = (skeleton.joints[skeleton.jointlabels[leftfoot]].position + change2) / 2 + (skeleton.joints[skeleton.jointlabels[leftknee]].position) / 2;
5527
5528                         point = DoRotation(skeleton.joints[skeleton.jointlabels[rightfoot]].position, 0, yaw, 0) * scale + coords;
5529                         heightright = terrain.getHeight(point.x, point.z) + .04;
5530                         point.y = heightright;
5531                         change = skeleton.joints[skeleton.jointlabels[rightankle]].position - skeleton.joints[skeleton.jointlabels[rightfoot]].position;
5532                         change2 = skeleton.joints[skeleton.jointlabels[rightknee]].position - skeleton.joints[skeleton.jointlabels[rightfoot]].position;
5533                         skeleton.joints[skeleton.jointlabels[rightfoot]].position = DoRotation((point - coords) / scale, 0, -yaw, 0) * (1 - target) + skeleton.joints[skeleton.jointlabels[rightfoot]].position * target;
5534                         skeleton.joints[skeleton.jointlabels[rightankle]].position = skeleton.joints[skeleton.jointlabels[rightfoot]].position + change;
5535                         skeleton.joints[skeleton.jointlabels[rightknee]].position = (skeleton.joints[skeleton.jointlabels[rightfoot]].position + change2) / 2 + (skeleton.joints[skeleton.jointlabels[rightknee]].position) / 2;
5536                         skeleton.DoConstraints(&coords, &scale);
5537                     }
5538                 }
5539             }
5540             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()))
5541                 DoHead();
5542             else {
5543                 targetheadyaw = -targetyaw;
5544                 targetheadpitch = 0;
5545                 if (animation[animTarget].attack == 3)targetheadyaw += 180;
5546             }
5547             for (i = 0; i < skeleton.drawmodel.vertexNum; i++) {
5548                 skeleton.drawmodel.vertex[i] = 0;
5549                 skeleton.drawmodel.vertex[i].y = 999;
5550             }
5551             for (i = 0; i < skeleton.drawmodellow.vertexNum; i++) {
5552                 skeleton.drawmodellow.vertex[i] = 0;
5553                 skeleton.drawmodellow.vertex[i].y = 999;
5554             }
5555             for (i = 0; i < skeleton.drawmodelclothes.vertexNum; i++) {
5556                 skeleton.drawmodelclothes.vertex[i] = 0;
5557                 skeleton.drawmodelclothes.vertex[i].y = 999;
5558             }
5559             for (i = 0; i < skeleton.num_muscles; i++) {
5560                 if ((skeleton.muscles[i].numvertices > 0 && playerdetail) || (skeleton.muscles[i].numverticeslow > 0 && !playerdetail)) {
5561                     morphness = 0;
5562                     start = 0;
5563                     endthing = 0;
5564                     if (skeleton.muscles[i].parent1->label == righthand || skeleton.muscles[i].parent2->label == righthand) {
5565                         morphness = righthandmorphness;
5566                         start = righthandmorphstart;
5567                         endthing = righthandmorphend;
5568                     }
5569                     if (skeleton.muscles[i].parent1->label == lefthand || skeleton.muscles[i].parent2->label == lefthand) {
5570                         morphness = lefthandmorphness;
5571                         start = lefthandmorphstart;
5572                         endthing = lefthandmorphend;
5573                     }
5574                     if (skeleton.muscles[i].parent1->label == head || skeleton.muscles[i].parent2->label == head) {
5575                         morphness = headmorphness;
5576                         start = headmorphstart;
5577                         endthing = headmorphend;
5578                     }
5579                     if ((skeleton.muscles[i].parent1->label == neck && skeleton.muscles[i].parent2->label == abdomen) || (skeleton.muscles[i].parent2->label == neck && skeleton.muscles[i].parent1->label == abdomen)) {
5580                         morphness = chestmorphness;
5581                         start = chestmorphstart;
5582                         endthing = chestmorphend;
5583                     }
5584                     if ((skeleton.muscles[i].parent1->label == groin && skeleton.muscles[i].parent2->label == abdomen) || (skeleton.muscles[i].parent2->label == groin && skeleton.muscles[i].parent1->label == abdomen)) {
5585                         morphness = tailmorphness;
5586                         start = tailmorphstart;
5587                         endthing = tailmorphend;
5588                     }
5589                     if (calcrot)skeleton.FindRotationMuscle(i, animTarget);
5590                     mid = (skeleton.muscles[i].parent1->position + skeleton.muscles[i].parent2->position) / 2;
5591                     glMatrixMode(GL_MODELVIEW);                                                 // Select The Modelview Matrix
5592                     glPushMatrix();
5593                     glLoadIdentity();
5594                     if (!skeleton.free)glRotatef(tilt2, 1, 0, 0);
5595                     if (!skeleton.free)glRotatef(tilt, 0, 0, 1);
5596
5597
5598                     glTranslatef(mid.x, mid.y, mid.z);
5599
5600                     skeleton.muscles[i].lastrotate1 = skeleton.muscles[i].rotate1;
5601                     glRotatef(-skeleton.muscles[i].lastrotate1 + 90, 0, 1, 0);
5602
5603                     skeleton.muscles[i].lastrotate2 = skeleton.muscles[i].rotate2;
5604                     glRotatef(-skeleton.muscles[i].lastrotate2 + 90, 0, 0, 1);
5605
5606                     skeleton.muscles[i].lastrotate3 = skeleton.muscles[i].rotate3;
5607                     glRotatef(-skeleton.muscles[i].lastrotate3, 0, 1, 0);
5608
5609                     if (playerdetail || skeleton.free == 3) {
5610                         for (j = 0; j < skeleton.muscles[i].numvertices; j++) {
5611                             glMatrixMode(GL_MODELVIEW);                                                 // Select The Modelview Matrix
5612                             glPushMatrix();
5613                             if (skeleton.muscles[i].parent1->label == abdomen || skeleton.muscles[i].parent2->label == abdomen)
5614                                 glTranslatef((skeleton.model[start].vertex[skeleton.muscles[i].vertices[j]].x * (1 - morphness) + skeleton.model[endthing].vertex[skeleton.muscles[i].vertices[j]].x * morphness)*proportionbody.x,
5615                                              (skeleton.model[start].vertex[skeleton.muscles[i].vertices[j]].y * (1 - morphness) + skeleton.model[endthing].vertex[skeleton.muscles[i].vertices[j]].y * morphness)*proportionbody.y,
5616                                              (skeleton.model[start].vertex[skeleton.muscles[i].vertices[j]].z * (1 - morphness) + skeleton.model[endthing].vertex[skeleton.muscles[i].vertices[j]].z * morphness)*proportionbody.z);
5617                             if (skeleton.muscles[i].parent1->label == lefthand || skeleton.muscles[i].parent1->label == righthand || skeleton.muscles[i].parent1->label == leftwrist || skeleton.muscles[i].parent1->label == rightwrist || skeleton.muscles[i].parent1->label == leftelbow || skeleton.muscles[i].parent1->label == rightelbow || skeleton.muscles[i].parent2->label == leftelbow || skeleton.muscles[i].parent2->label == rightelbow)
5618                                 glTranslatef((skeleton.model[start].vertex[skeleton.muscles[i].vertices[j]].x * (1 - morphness) + skeleton.model[endthing].vertex[skeleton.muscles[i].vertices[j]].x * morphness)*proportionarms.x,
5619                                              (skeleton.model[start].vertex[skeleton.muscles[i].vertices[j]].y * (1 - morphness) + skeleton.model[endthing].vertex[skeleton.muscles[i].vertices[j]].y * morphness)*proportionarms.y,
5620                                              (skeleton.model[start].vertex[skeleton.muscles[i].vertices[j]].z * (1 - morphness) + skeleton.model[endthing].vertex[skeleton.muscles[i].vertices[j]].z * morphness)*proportionarms.z);
5621                             if (skeleton.muscles[i].parent1->label == leftfoot || skeleton.muscles[i].parent1->label == rightfoot || skeleton.muscles[i].parent1->label == leftankle || skeleton.muscles[i].parent1->label == rightankle || skeleton.muscles[i].parent1->label == leftknee || skeleton.muscles[i].parent1->label == rightknee || skeleton.muscles[i].parent2->label == leftknee || skeleton.muscles[i].parent2->label == rightknee)
5622                                 glTranslatef((skeleton.model[start].vertex[skeleton.muscles[i].vertices[j]].x * (1 - morphness) + skeleton.model[endthing].vertex[skeleton.muscles[i].vertices[j]].x * morphness)*proportionlegs.x,
5623                                              (skeleton.model[start].vertex[skeleton.muscles[i].vertices[j]].y * (1 - morphness) + skeleton.model[endthing].vertex[skeleton.muscles[i].vertices[j]].y * morphness)*proportionlegs.y,
5624                                              (skeleton.model[start].vertex[skeleton.muscles[i].vertices[j]].z * (1 - morphness) + skeleton.model[endthing].vertex[skeleton.muscles[i].vertices[j]].z * morphness)*proportionlegs.z);
5625                             if (skeleton.muscles[i].parent1->label == head || skeleton.muscles[i].parent2->label == head)
5626                                 glTranslatef((skeleton.model[start].vertex[skeleton.muscles[i].vertices[j]].x * (1 - morphness) + skeleton.model[endthing].vertex[skeleton.muscles[i].vertices[j]].x * morphness)*proportionhead.x,
5627                                              (skeleton.model[start].vertex[skeleton.muscles[i].vertices[j]].y * (1 - morphness) + skeleton.model[endthing].vertex[skeleton.muscles[i].vertices[j]].y * morphness)*proportionhead.y,
5628                                              (skeleton.model[start].vertex[skeleton.muscles[i].vertices[j]].z * (1 - morphness) + skeleton.model[endthing].vertex[skeleton.muscles[i].vertices[j]].z * morphness)*proportionhead.z);
5629                             glGetFloatv(GL_MODELVIEW_MATRIX, M);
5630                             //if(!isnormal(M[12])||!isnormal(M[13])||!isnormal(M[14]))test=0;
5631                             //if(!isnormal(scale))test=1;
5632                             skeleton.drawmodel.vertex[skeleton.muscles[i].vertices[j]].x = M[12] * scale;
5633                             skeleton.drawmodel.vertex[skeleton.muscles[i].vertices[j]].y = M[13] * scale;
5634                             skeleton.drawmodel.vertex[skeleton.muscles[i].vertices[j]].z = M[14] * scale;
5635                             //test=2;
5636                             glPopMatrix();
5637                         }
5638                     }
5639                     if (!playerdetail || skeleton.free == 3) {
5640                         for (j = 0; j < skeleton.muscles[i].numverticeslow; j++) {
5641                             glMatrixMode(GL_MODELVIEW);                                                 // Select The Modelview Matrix
5642                             glPushMatrix();
5643                             if (skeleton.muscles[i].parent1->label == abdomen || skeleton.muscles[i].parent2->label == abdomen)
5644                                 glTranslatef((skeleton.modellow.vertex[skeleton.muscles[i].verticeslow[j]].x)*proportionbody.x,
5645                                              (skeleton.modellow.vertex[skeleton.muscles[i].verticeslow[j]].y)*proportionbody.y,
5646                                              (skeleton.modellow.vertex[skeleton.muscles[i].verticeslow[j]].z)*proportionbody.z);
5647                             if (skeleton.muscles[i].parent1->label == lefthand || skeleton.muscles[i].parent1->label == righthand || skeleton.muscles[i].parent1->label == leftwrist || skeleton.muscles[i].parent1->label == rightwrist || skeleton.muscles[i].parent1->label == leftelbow || skeleton.muscles[i].parent1->label == rightelbow || skeleton.muscles[i].parent2->label == leftelbow || skeleton.muscles[i].parent2->label == rightelbow)
5648                                 glTranslatef((skeleton.modellow.vertex[skeleton.muscles[i].verticeslow[j]].x)*proportionarms.x,
5649                                              (skeleton.modellow.vertex[skeleton.muscles[i].verticeslow[j]].y)*proportionarms.y,
5650                                              (skeleton.modellow.vertex[skeleton.muscles[i].verticeslow[j]].z)*proportionarms.z);
5651                             if (skeleton.muscles[i].parent1->label == leftfoot || skeleton.muscles[i].parent1->label == rightfoot || skeleton.muscles[i].parent1->label == leftankle || skeleton.muscles[i].parent1->label == rightankle || skeleton.muscles[i].parent1->label == leftknee || skeleton.muscles[i].parent1->label == rightknee || skeleton.muscles[i].parent2->label == leftknee || skeleton.muscles[i].parent2->label == rightknee)
5652                                 glTranslatef((skeleton.modellow.vertex[skeleton.muscles[i].verticeslow[j]].x)*proportionlegs.x,
5653                                              (skeleton.modellow.vertex[skeleton.muscles[i].verticeslow[j]].y)*proportionlegs.y,
5654                                              (skeleton.modellow.vertex[skeleton.muscles[i].verticeslow[j]].z)*proportionlegs.z);
5655                             if (skeleton.muscles[i].parent1->label == head || skeleton.muscles[i].parent2->label == head)
5656                                 glTranslatef((skeleton.modellow.vertex[skeleton.muscles[i].verticeslow[j]].x)*proportionhead.x,
5657                                              (skeleton.modellow.vertex[skeleton.muscles[i].verticeslow[j]].y)*proportionhead.y,
5658                                              (skeleton.modellow.vertex[skeleton.muscles[i].verticeslow[j]].z)*proportionhead.z);
5659
5660                             glGetFloatv(GL_MODELVIEW_MATRIX, M);
5661                             skeleton.drawmodellow.vertex[skeleton.muscles[i].verticeslow[j]].x = M[12] * scale;
5662                             skeleton.drawmodellow.vertex[skeleton.muscles[i].verticeslow[j]].y = M[13] * scale;
5663                             skeleton.drawmodellow.vertex[skeleton.muscles[i].verticeslow[j]].z = M[14] * scale;
5664                             glPopMatrix();
5665                         }
5666                     }
5667                     glPopMatrix();
5668                 }
5669                 if (skeleton.clothes && skeleton.muscles[i].numverticesclothes > 0) {
5670                     mid = (skeleton.muscles[i].parent1->position + skeleton.muscles[i].parent2->position) / 2;
5671
5672                     glMatrixMode(GL_MODELVIEW);                                                 // Select The Modelview Matrix
5673                     glPushMatrix();
5674                     glLoadIdentity();
5675                     if (!skeleton.free)glRotatef(tilt2, 1, 0, 0);
5676                     if (!skeleton.free)glRotatef(tilt, 0, 0, 1);
5677                     glTranslatef(mid.x, mid.y, mid.z);
5678                     skeleton.muscles[i].lastrotate1 = skeleton.muscles[i].rotate1;
5679                     glRotatef(-skeleton.muscles[i].lastrotate1 + 90, 0, 1, 0);
5680
5681                     skeleton.muscles[i].lastrotate2 = skeleton.muscles[i].rotate2;
5682                     glRotatef(-skeleton.muscles[i].lastrotate2 + 90, 0, 0, 1);
5683
5684                     skeleton.muscles[i].lastrotate3 = skeleton.muscles[i].rotate3;
5685                     glRotatef(-skeleton.muscles[i].lastrotate3, 0, 1, 0);
5686
5687                     for (j = 0; j < skeleton.muscles[i].numverticesclothes; j++) {
5688                         glMatrixMode(GL_MODELVIEW);                                                     // Select The Modelview Matrix
5689                         glPushMatrix();
5690                         if (skeleton.muscles[i].parent1->label == abdomen || skeleton.muscles[i].parent2->label == abdomen)
5691                             glTranslatef((skeleton.modelclothes.vertex[skeleton.muscles[i].verticesclothes[j]].x)*proportionbody.x,
5692                                          (skeleton.modelclothes.vertex[skeleton.muscles[i].verticesclothes[j]].y)*proportionbody.y,
5693                                          (skeleton.modelclothes.vertex[skeleton.muscles[i].verticesclothes[j]].z)*proportionbody.z);
5694                         if (skeleton.muscles[i].parent1->label == lefthand || skeleton.muscles[i].parent1->label == righthand || skeleton.muscles[i].parent1->label == leftwrist || skeleton.muscles[i].parent1->label == rightwrist || skeleton.muscles[i].parent1->label == leftelbow || skeleton.muscles[i].parent1->label == rightelbow || skeleton.muscles[i].parent2->label == leftelbow || skeleton.muscles[i].parent2->label == rightelbow)
5695                             glTranslatef((skeleton.modelclothes.vertex[skeleton.muscles[i].verticesclothes[j]].x)*proportionarms.x,
5696                                          (skeleton.modelclothes.vertex[skeleton.muscles[i].verticesclothes[j]].y)*proportionarms.y,
5697                                          (skeleton.modelclothes.vertex[skeleton.muscles[i].verticesclothes[j]].z)*proportionarms.z);
5698                         if (skeleton.muscles[i].parent1->label == leftfoot || skeleton.muscles[i].parent1->label == rightfoot || skeleton.muscles[i].parent1->label == leftankle || skeleton.muscles[i].parent1->label == rightankle || skeleton.muscles[i].parent1->label == leftknee || skeleton.muscles[i].parent1->label == rightknee || skeleton.muscles[i].parent2->label == leftknee || skeleton.muscles[i].parent2->label == rightknee)
5699                             glTranslatef((skeleton.modelclothes.vertex[skeleton.muscles[i].verticesclothes[j]].x)*proportionlegs.x,
5700                                          (skeleton.modelclothes.vertex[skeleton.muscles[i].verticesclothes[j]].y)*proportionlegs.y,
5701                                          (skeleton.modelclothes.vertex[skeleton.muscles[i].verticesclothes[j]].z)*proportionlegs.z);
5702                         if (skeleton.muscles[i].parent1->label == head || skeleton.muscles[i].parent2->label == head)
5703                             glTranslatef((skeleton.modelclothes.vertex[skeleton.muscles[i].verticesclothes[j]].x)*proportionhead.x,
5704                                          (skeleton.modelclothes.vertex[skeleton.muscles[i].verticesclothes[j]].y)*proportionhead.y,
5705                                          (skeleton.modelclothes.vertex[skeleton.muscles[i].verticesclothes[j]].z)*proportionhead.z);
5706                         glGetFloatv(GL_MODELVIEW_MATRIX, M);
5707                         skeleton.drawmodelclothes.vertex[skeleton.muscles[i].verticesclothes[j]].x = M[12] * scale;
5708                         skeleton.drawmodelclothes.vertex[skeleton.muscles[i].verticesclothes[j]].y = M[13] * scale;
5709                         skeleton.drawmodelclothes.vertex[skeleton.muscles[i].verticesclothes[j]].z = M[14] * scale;
5710                         glPopMatrix();
5711                     }
5712                     glPopMatrix();
5713                 }
5714                 updatedelay = 1 + (float)(Random() % 100) / 1000;
5715             }
5716             if (skeleton.free != 2 && (skeleton.free == 1 || skeleton.free == 3 || id == 0 || (normalsupdatedelay <= 0) || animTarget == getupfromfrontanim || animTarget == getupfrombackanim || animCurrent == getupfromfrontanim || animCurrent == getupfrombackanim)) {
5717                 normalsupdatedelay = 1;
5718                 if (playerdetail || skeleton.free == 3)skeleton.drawmodel.CalculateNormals(0);
5719                 if (!playerdetail || skeleton.free == 3)skeleton.drawmodellow.CalculateNormals(0);
5720                 if (skeleton.clothes)skeleton.drawmodelclothes.CalculateNormals(0);
5721             } else {
5722                 if (playerdetail || skeleton.free == 3)skeleton.drawmodel.UpdateVertexArrayNoTexNoNorm();
5723                 if (!playerdetail || skeleton.free == 3)skeleton.drawmodellow.UpdateVertexArrayNoTexNoNorm();
5724                 if (skeleton.clothes) {
5725                     skeleton.drawmodelclothes.UpdateVertexArrayNoTexNoNorm();
5726                 }
5727             }
5728         }
5729         framemult = .01;
5730         updatedelaychange = -framemult * 4 * (45 - findDistance(&viewer, &coords) * 1);
5731         if (updatedelaychange > -realmultiplier * 30)updatedelaychange = -realmultiplier * 30;
5732         if (updatedelaychange > -framemult * 4)updatedelaychange = -framemult * 4;
5733         if (skeleton.free == 1)updatedelaychange *= 6;
5734         if (id == 0)updatedelaychange *= 8;
5735         updatedelay += updatedelaychange;
5736
5737         glMatrixMode(GL_MODELVIEW);                                                     // Select The Modelview Matrix
5738         glPushMatrix();
5739         if (!skeleton.free)glTranslatef(coords.x, coords.y - .02, coords.z);
5740         if (skeleton.free)glTranslatef(coords.x, coords.y - .02, coords.z);
5741         if (!skeleton.free)glTranslatef(offset.x * scale, offset.y * scale, offset.z * scale);
5742         if (!skeleton.free)glRotatef(yaw, 0, 1, 0);
5743         if (showpoints) {
5744             glPointSize(5);
5745             glColor4f(.4, 1, .4, 1);
5746             glDisable(GL_LIGHTING);
5747             glDisable(GL_TEXTURE_2D);
5748             glBegin(GL_POINTS);
5749             if (playerdetail)
5750                 for (i = 0; i < skeleton.drawmodel.vertexNum; i++) {
5751                     glVertex3f(skeleton.drawmodel.vertex[i].x, skeleton.drawmodel.vertex[i].y, skeleton.drawmodel.vertex[i].z);
5752                 }
5753             glEnd();
5754             glBegin(GL_LINES);
5755
5756             if (playerdetail)
5757                 for (i = 0; i < skeleton.drawmodel.TriangleNum; i++) {
5758                     glVertex3f(skeleton.drawmodel.vertex[skeleton.drawmodel.Triangles[i].vertex[0]].x, skeleton.drawmodel.vertex[skeleton.drawmodel.Triangles[i].vertex[0]].y, skeleton.drawmodel.vertex[skeleton.drawmodel.Triangles[i].vertex[0]].z);
5759                     glVertex3f(skeleton.drawmodel.vertex[skeleton.drawmodel.Triangles[i].vertex[1]].x, skeleton.drawmodel.vertex[skeleton.drawmodel.Triangles[i].vertex[1]].y, skeleton.drawmodel.vertex[skeleton.drawmodel.Triangles[i].vertex[1]].z);
5760                     glVertex3f(skeleton.drawmodel.vertex[skeleton.drawmodel.Triangles[i].vertex[1]].x, skeleton.drawmodel.vertex[skeleton.drawmodel.Triangles[i].vertex[1]].y, skeleton.drawmodel.vertex[skeleton.drawmodel.Triangles[i].vertex[1]].z);
5761                     glVertex3f(skeleton.drawmodel.vertex[skeleton.drawmodel.Triangles[i].vertex[2]].x, skeleton.drawmodel.vertex[skeleton.drawmodel.Triangles[i].vertex[2]].y, skeleton.drawmodel.vertex[skeleton.drawmodel.Triangles[i].vertex[2]].z);
5762                     glVertex3f(skeleton.drawmodel.vertex[skeleton.drawmodel.Triangles[i].vertex[2]].x, skeleton.drawmodel.vertex[skeleton.drawmodel.Triangles[i].vertex[2]].y, skeleton.drawmodel.vertex[skeleton.drawmodel.Triangles[i].vertex[2]].z);
5763                     glVertex3f(skeleton.drawmodel.vertex[skeleton.drawmodel.Triangles[i].vertex[0]].x, skeleton.drawmodel.vertex[skeleton.drawmodel.Triangles[i].vertex[0]].y, skeleton.drawmodel.vertex[skeleton.drawmodel.Triangles[i].vertex[0]].z);
5764                 }
5765
5766             glEnd();
5767         }
5768
5769         terrainlight = terrain.getLighting(coords.x, coords.z);
5770         distance = distsq(&viewer, &coords);
5771         distance = (viewdistance * viewdistance - (distance - (viewdistance * viewdistance * fadestart)) * (1 / (1 - fadestart))) / viewdistance / viewdistance;
5772         if (distance > 1)distance = 1;
5773         if (distance > 0) {
5774             terrainheight = (coords.y - terrain.getHeight(coords.x, coords.z)) / 3 + 1;
5775             if (terrainheight < 1)terrainheight = 1;
5776             if (terrainheight > 1.7)terrainheight = 1.7;
5777
5778             //burnt=0;
5779             glColor4f((1 - (1 - terrainlight.x) / terrainheight) - burnt, (1 - (1 - terrainlight.y) / terrainheight) - burnt, (1 - (1 - terrainlight.z) / terrainheight) - burnt, distance);
5780             glDisable(GL_BLEND);
5781             glAlphaFunc(GL_GREATER, 0.0001);
5782             glEnable(GL_TEXTURE_2D);
5783             if (cellophane) {
5784                 glDisable(GL_TEXTURE_2D);
5785                 glColor4f(.7, .35, 0, .5);
5786                 glDepthMask(0);
5787                 glEnable(GL_LIGHTING);
5788                 glEnable(GL_BLEND);
5789             }
5790             if (tutoriallevel && id != 0) {
5791                 //glDisable(GL_TEXTURE_2D);
5792                 glColor4f(.7, .7, .7, 0.6);
5793                 glDepthMask(0);
5794                 glEnable(GL_LIGHTING);
5795                 glEnable(GL_BLEND);
5796                 if (canattack && cananger)
5797                     if (animation[animTarget].attack == normalattack || animation[animTarget].attack == reversed) {
5798                         glDisable(GL_TEXTURE_2D);
5799                         glColor4f(1, 0, 0, 0.8);
5800                     }
5801                 glMatrixMode(GL_TEXTURE);
5802                 glPushMatrix();
5803                 glTranslatef(0, -smoketex, 0);
5804                 glTranslatef(-smoketex, 0, 0);
5805             }
5806             if (playerdetail) {
5807                 if (!showpoints) {
5808                     if ((tutoriallevel && id != 0))skeleton.drawmodel.drawdifftex(Sprite::cloudimpacttexture);
5809                     else skeleton.drawmodel.draw();
5810                 }
5811             }
5812             if (!playerdetail) {
5813                 if ((tutoriallevel && id != 0))skeleton.drawmodellow.drawdifftex(Sprite::cloudimpacttexture);
5814                 else skeleton.drawmodellow.drawdifftex(skeleton.drawmodel.textureptr);
5815             }
5816
5817             if (!(animation[animTarget].attack == normalattack || animation[animTarget].attack == reversed))
5818                 if (tutoriallevel && id != 0) {
5819                     glPopMatrix();
5820                     glMatrixMode(GL_MODELVIEW);
5821                     glEnable(GL_TEXTURE_2D);
5822                     glColor4f(.7, .7, .7, 0.6);
5823                     glDepthMask(0);
5824                     glEnable(GL_LIGHTING);
5825                     glEnable(GL_BLEND);
5826                     if (canattack && cananger)
5827                         if (animation[animTarget].attack == normalattack || animation[animTarget].attack == reversed) {
5828                             glDisable(GL_TEXTURE_2D);
5829                             glColor4f(1, 0, 0, 0.8);
5830                         }
5831                     glMatrixMode(GL_TEXTURE);
5832                     glPushMatrix();
5833                     glTranslatef(0, -smoketex * .6, 0);
5834                     glTranslatef(smoketex * .6, 0, 0);
5835                     if (playerdetail) {
5836                         if (!showpoints) {
5837                             if ((tutoriallevel && id != 0))skeleton.drawmodel.drawdifftex(Sprite::cloudimpacttexture);
5838                             else skeleton.drawmodel.draw();
5839                         }
5840                     }
5841                     if (!playerdetail) {
5842                         if ((tutoriallevel && id != 0))skeleton.drawmodellow.drawdifftex(Sprite::cloudimpacttexture);
5843                         else skeleton.drawmodellow.drawdifftex(skeleton.drawmodel.textureptr);
5844                     }
5845                 }
5846
5847
5848             if (tutoriallevel && id != 0) {
5849                 glPopMatrix();
5850                 glMatrixMode(GL_MODELVIEW);
5851                 glEnable(GL_TEXTURE_2D);
5852             }
5853             if (skeleton.clothes) {
5854                 glDepthMask(0);
5855                 glEnable(GL_BLEND);
5856                 if (!immediate)skeleton.drawmodelclothes.draw();
5857                 if (immediate)skeleton.drawmodelclothes.drawimmediate();
5858                 glDepthMask(1);
5859             }
5860         }
5861         glPopMatrix();
5862
5863         if (num_weapons > 0) {
5864             for (k = 0; k < num_weapons; k++) {
5865                 i = weaponids[k];
5866                 if (weaponactive == k) {
5867                     if (weapons[i].getType() != staff) {
5868                         for (j = 0; j < skeleton.num_muscles; j++) {
5869                             if ((skeleton.muscles[j].parent1->label == righthand || skeleton.muscles[j].parent2->label == righthand) && skeleton.muscles[j].numvertices > 0) {
5870                                 weaponattachmuscle = j;
5871                             }
5872                         }
5873                         for (j = 0; j < skeleton.num_muscles; j++) {
5874                             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) {
5875                                 weaponrotatemuscle = j;
5876                             }
5877                         }
5878                         weaponpoint = (skeleton.muscles[weaponattachmuscle].parent1->position + skeleton.muscles[weaponattachmuscle].parent2->position) / 2;
5879                         if (creature == wolftype)weaponpoint = (skeleton.joints[skeleton.jointlabels[rightwrist]].position * .7 + skeleton.joints[skeleton.jointlabels[righthand]].position * .3);
5880                     }
5881                     if (weapons[i].getType() == staff) {
5882                         for (j = 0; j < skeleton.num_muscles; j++) {
5883                             if ((skeleton.muscles[j].parent1->label == righthand || skeleton.muscles[j].parent2->label == righthand) && skeleton.muscles[j].numvertices > 0) {
5884                                 weaponattachmuscle = j;
5885                             }
5886                         }
5887                         for (j = 0; j < skeleton.num_muscles; j++) {
5888                             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) {
5889                                 weaponrotatemuscle = j;
5890                             }
5891                         }
5892                         //weaponpoint=skeleton.joints[skeleton.jointlabels[rightwrist]].position;
5893                         weaponpoint = (skeleton.muscles[weaponattachmuscle].parent1->position + skeleton.muscles[weaponattachmuscle].parent2->position) / 2;
5894                         //weaponpoint+=skeleton.specialforward[1]*.1+(skeleton.joints[skeleton.jointlabels[rightwrist]].position-skeleton.joints[skeleton.jointlabels[rightelbow]].position);
5895                         XYZ tempnormthing, vec1, vec2;
5896                         vec1 = (skeleton.joints[skeleton.jointlabels[rightwrist]].position - skeleton.joints[skeleton.jointlabels[rightelbow]].position);
5897                         vec2 = (skeleton.joints[skeleton.jointlabels[rightwrist]].position - skeleton.joints[skeleton.jointlabels[rightshoulder]].position);
5898                         CrossProduct(&vec1, &vec2, &tempnormthing);
5899                         Normalise(&tempnormthing);
5900                         if (animTarget != staffhitanim && animCurrent != staffhitanim && animTarget != staffgroundsmashanim && animCurrent != staffgroundsmashanim && animTarget != staffspinhitanim && animCurrent != staffspinhitanim)weaponpoint += tempnormthing * .1 - skeleton.specialforward[1] * .3 + (skeleton.joints[skeleton.jointlabels[rightwrist]].position - skeleton.joints[skeleton.jointlabels[rightelbow]].position);
5901                     }
5902                 }
5903                 if (weaponactive != k && weaponstuck != k) {
5904                     if (weapons[i].getType() == knife)weaponpoint = skeleton.joints[skeleton.jointlabels[abdomen]].position + (skeleton.joints[skeleton.jointlabels[righthip]].position - skeleton.joints[skeleton.jointlabels[lefthip]].position) * .1 + (skeleton.joints[skeleton.jointlabels[rightshoulder]].position - skeleton.joints[skeleton.jointlabels[leftshoulder]].position) * .35;
5905                     if (weapons[i].getType() == sword)weaponpoint = skeleton.joints[skeleton.jointlabels[abdomen]].position + (skeleton.joints[skeleton.jointlabels[lefthip]].position - skeleton.joints[skeleton.jointlabels[righthip]].position) * .09 + (skeleton.joints[skeleton.jointlabels[leftshoulder]].position - skeleton.joints[skeleton.jointlabels[rightshoulder]].position) * .33;
5906                     if (weapons[i].getType() == staff)weaponpoint = skeleton.joints[skeleton.jointlabels[abdomen]].position + (skeleton.joints[skeleton.jointlabels[lefthip]].position - skeleton.joints[skeleton.jointlabels[righthip]].position) * .09 + (skeleton.joints[skeleton.jointlabels[leftshoulder]].position - skeleton.joints[skeleton.jointlabels[rightshoulder]].position) * .33;
5907                     for (j = 0; j < skeleton.num_muscles; j++) {
5908                         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) {
5909                             weaponrotatemuscle = j;
5910                         }
5911                     }
5912                 }
5913                 if (weaponstuck == k) {
5914                     if (weaponstuckwhere == 0)weaponpoint = skeleton.joints[skeleton.jointlabels[abdomen]].position * .5 + skeleton.joints[skeleton.jointlabels[neck]].position * .5 - skeleton.forward * .8;
5915                     else weaponpoint = skeleton.joints[skeleton.jointlabels[abdomen]].position * .5 + skeleton.joints[skeleton.jointlabels[neck]].position * .5 + skeleton.forward * .8;
5916                     for (j = 0; j < skeleton.num_muscles; j++) {
5917                         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) {
5918                             weaponrotatemuscle = j;
5919                         }
5920                     }
5921                 }
5922                 if (skeleton.free) {
5923                     weapons[i].position = weaponpoint * scale + coords;
5924                     weapons[i].bigrotation = 0;
5925                     weapons[i].bigtilt = 0;
5926                     weapons[i].bigtilt2 = 0;
5927                 } else {
5928                     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;
5929                     weapons[i].bigrotation = yaw;
5930                     weapons[i].bigtilt = tilt;
5931                     weapons[i].bigtilt2 = tilt2;
5932                 }
5933                 weapons[i].rotation1 = skeleton.muscles[weaponrotatemuscle].lastrotate1;
5934                 weapons[i].rotation2 = skeleton.muscles[weaponrotatemuscle].lastrotate2;
5935                 weapons[i].rotation3 = skeleton.muscles[weaponrotatemuscle].lastrotate3;
5936                 if (weaponactive == k) {
5937                     if (weapons[i].getType() == knife) {
5938                         weapons[i].smallrotation = 180;
5939                         weapons[i].smallrotation2 = 0;
5940                         if (isCrouch() || wasCrouch()) {
5941                             weapons[i].smallrotation2 = 20;
5942                         }
5943                         if (animTarget == hurtidleanim) {
5944                             weapons[i].smallrotation2 = 50;
5945                         }
5946                         if ((animCurrent == crouchstabanim && animTarget == crouchstabanim) || (animCurrent == backhandspringanim && animTarget == backhandspringanim)) {
5947                             XYZ temppoint1, temppoint2, tempforward;
5948                             float distance;
5949
5950                             temppoint1 = skeleton.joints[skeleton.jointlabels[righthand]].position;
5951                             temppoint2 = animation[animCurrent].weapontarget[frameCurrent] * (1 - target) + animation[animTarget].weapontarget[frameTarget] * (target);
5952                             distance = findDistance(&temppoint1, &temppoint2);
5953                             weapons[i].rotation2 = asin((temppoint1.y - temppoint2.y) / distance);
5954                             weapons[i].rotation2 *= 360 / 6.28;
5955                             temppoint1.y = 0;
5956                             temppoint2.y = 0;
5957                             weapons[i].rotation1 = acos((temppoint1.z - temppoint2.z) / findDistance(&temppoint1, &temppoint2));
5958                             weapons[i].rotation1 *= 360 / 6.28;
5959                             weapons[i].rotation3 = 0;
5960                             weapons[i].smallrotation = -90;
5961                             weapons[i].smallrotation2 = 0;
5962                             if (temppoint1.x > temppoint2.x)weapons[i].rotation1 = 360 - weapons[i].rotation1;
5963                         }
5964                         if ((animCurrent == knifeslashreversalanim && animTarget == knifeslashreversalanim) || (animCurrent == knifeslashreversedanim && animTarget == knifeslashreversedanim)) {
5965                             XYZ temppoint1, temppoint2, tempforward;
5966                             float distance;
5967
5968                             temppoint1 = skeleton.joints[skeleton.jointlabels[righthand]].position;
5969                             temppoint2 = animation[animCurrent].weapontarget[frameCurrent] * (1 - target) + animation[animTarget].weapontarget[frameTarget] * (target);
5970                             distance = findDistance(&temppoint1, &temppoint2);
5971                             weapons[i].rotation2 = asin((temppoint1.y - temppoint2.y) / distance);
5972                             weapons[i].rotation2 *= 360 / 6.28;
5973                             temppoint1.y = 0;
5974                             temppoint2.y = 0;
5975                             weapons[i].rotation1 = acos((temppoint1.z - temppoint2.z) / findDistance(&temppoint1, &temppoint2));
5976                             weapons[i].rotation1 *= 360 / 6.28;
5977                             weapons[i].rotation3 = 0;
5978                             weapons[i].smallrotation = 90;
5979                             weapons[i].smallrotation2 = 0;
5980                             if (temppoint1.x > temppoint2.x)weapons[i].rotation1 = 360 - weapons[i].rotation1;
5981                         }
5982                         if (animTarget == knifethrowanim) {
5983                             weapons[i].smallrotation = 90;
5984                             //weapons[i].smallrotation2=-90;
5985                             weapons[i].smallrotation2 = 0;
5986                             weapons[i].rotation1 = 0;
5987                             weapons[i].rotation2 = 0;
5988                             weapons[i].rotation3 = 0;
5989                         }
5990                         if (animTarget == knifesneakattackanim && frameTarget < 5) {
5991                             weapons[i].smallrotation = -90;
5992                             weapons[i].rotation1 = 0;
5993                             weapons[i].rotation2 = 0;
5994                             weapons[i].rotation3 = 0;
5995                         }
5996                     }
5997                     if (weapons[i].getType() == sword) {
5998                         weapons[i].smallrotation = 0;
5999                         weapons[i].smallrotation2 = 0;
6000                         if (animTarget == knifethrowanim) {
6001                             weapons[i].smallrotation = -90;
6002                             weapons[i].smallrotation2 = 0;
6003                             weapons[i].rotation1 = 0;
6004                             weapons[i].rotation2 = 0;
6005                             weapons[i].rotation3 = 0;
6006                         }
6007                         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)) {
6008                             XYZ temppoint1, temppoint2, tempforward;
6009                             float distance;
6010
6011                             temppoint1 = animation[animCurrent].position[skeleton.jointlabels[righthand]][frameCurrent] * (1 - target) + animation[animTarget].position[skeleton.jointlabels[righthand]][frameTarget] * (target); //skeleton.joints[skeleton.jointlabels[righthand]].position;
6012                             temppoint2 = animation[animCurrent].weapontarget[frameCurrent] * (1 - target) + animation[animTarget].weapontarget[frameTarget] * (target);
6013                             distance = findDistance(&temppoint1, &temppoint2);
6014                             weapons[i].rotation2 = asin((temppoint1.y - temppoint2.y) / distance);
6015                             weapons[i].rotation2 *= 360 / 6.28;
6016                             temppoint1.y = 0;
6017                             temppoint2.y = 0;
6018                             weapons[i].rotation1 = acos((temppoint1.z - temppoint2.z) / findDistance(&temppoint1, &temppoint2));
6019                             weapons[i].rotation1 *= 360 / 6.28;
6020                             weapons[i].rotation3 = 0;
6021                             weapons[i].smallrotation = 90;
6022                             weapons[i].smallrotation2 = 0;
6023                             if (temppoint1.x > temppoint2.x)weapons[i].rotation1 = 360 - weapons[i].rotation1;
6024                         }
6025                     }
6026                     if (weapons[i].getType() == staff) {
6027                         weapons[i].smallrotation = 100;
6028                         weapons[i].smallrotation2 = 0;
6029                         if ((animTarget == staffhitanim && animCurrent == staffhitanim) || (animTarget == staffhitreversedanim && animCurrent == staffhitreversedanim) || (animTarget == staffspinhitreversedanim && animCurrent == staffspinhitreversedanim) || (animTarget == staffgroundsmashanim && animCurrent == staffgroundsmashanim) || (animTarget == staffspinhitanim && animCurrent == staffspinhitanim)) {
6030                             XYZ temppoint1, temppoint2, tempforward;
6031                             float distance;
6032
6033                             temppoint1 = animation[animCurrent].position[skeleton.jointlabels[righthand]][frameCurrent] * (1 - target) + animation[animTarget].position[skeleton.jointlabels[righthand]][frameTarget] * (target); //skeleton.joints[skeleton.jointlabels[righthand]].position;
6034                             temppoint2 = animation[animCurrent].weapontarget[frameCurrent] * (1 - target) + animation[animTarget].weapontarget[frameTarget] * (target);
6035                             distance = findDistance(&temppoint1, &temppoint2);
6036                             weapons[i].rotation2 = asin((temppoint1.y - temppoint2.y) / distance);
6037                             weapons[i].rotation2 *= 360 / 6.28;
6038                             temppoint1.y = 0;
6039                             temppoint2.y = 0;
6040                             weapons[i].rotation1 = acos((temppoint1.z - temppoint2.z) / findDistance(&temppoint1, &temppoint2));
6041                             weapons[i].rotation1 *= 360 / 6.28;
6042                             weapons[i].rotation3 = 0;
6043                             weapons[i].smallrotation = 90;
6044                             weapons[i].smallrotation2 = 0;
6045                             if (temppoint1.x > temppoint2.x)weapons[i].rotation1 = 360 - weapons[i].rotation1;
6046                         }
6047                     }
6048                 }
6049                 if (weaponactive != k && weaponstuck != k) {
6050                     if (weapons[i].getType() == knife) {
6051                         weapons[i].smallrotation = -70;
6052                         weapons[i].smallrotation2 = 10;
6053                     }
6054                     if (weapons[i].getType() == sword) {
6055                         weapons[i].smallrotation = -100;
6056                         weapons[i].smallrotation2 = -8;
6057                     }
6058                     if (weapons[i].getType() == staff) {
6059                         weapons[i].smallrotation = -100;
6060                         weapons[i].smallrotation2 = -8;
6061                     }
6062                 }
6063                 if (weaponstuck == k) {
6064                     if (weaponstuckwhere == 0)
6065                         weapons[i].smallrotation = 180;
6066                     else
6067                         weapons[i].smallrotation = 0;
6068                     weapons[i].smallrotation2 = 10;
6069                 }
6070             }
6071         }
6072     }
6073
6074     calcrot = 0;
6075     if (skeleton.free)calcrot = 1;
6076     if (animation[animTarget].attack || isRun() || animTarget == staggerbackhardanim || isFlip() || animTarget == climbanim || animTarget == sneakanim || animTarget == rollanim || animTarget == walkanim || animTarget == backhandspringanim || isFlip() || isWallJump())calcrot = 1;
6077     if (animCurrent != animTarget)calcrot = 1;
6078     //if(id==0)calcrot=1;
6079     if (skeleton.free == 2)calcrot = 0;
6080
6081     return 0;
6082 }
6083
6084
6085 int Person::SphereCheck(XYZ *p1, float radius, XYZ *p, XYZ *move, float *rotate, Model *model)
6086 {
6087     static int i, j;
6088     static float distance;
6089     static float olddistance;
6090     static int intersecting;
6091     static int firstintersecting;
6092     static XYZ point;
6093     static XYZ oldp1;
6094     static XYZ start, end;
6095     static float slopethreshold = -.4;
6096
6097     firstintersecting = -1;
6098
6099     oldp1 = *p1;
6100     *p1 = *p1 - *move;
6101     if (distsq(p1, &model->boundingspherecenter) > radius * radius + model->boundingsphereradius * model->boundingsphereradius)return -1;
6102     if (*rotate)*p1 = DoRotation(*p1, 0, -*rotate, 0);
6103     for (i = 0; i < 4; i++) {
6104         for (j = 0; j < model->TriangleNum; j++) {
6105             if (model->facenormals[j].y <= slopethreshold) {
6106                 intersecting = 0;
6107                 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)));
6108                 if (distance < radius) {
6109                     point = *p1 - model->facenormals[j] * distance;
6110                     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]]))intersecting = 1;
6111                     if (!intersecting)intersecting = sphere_line_intersection(&model->vertex[model->Triangles[j].vertex[0]],
6112                                                          &model->vertex[model->Triangles[j].vertex[1]],
6113                                                          p1, &radius);
6114                     if (!intersecting)intersecting = sphere_line_intersection(&model->vertex[model->Triangles[j].vertex[1]],
6115                                                          &model->vertex[model->Triangles[j].vertex[2]],
6116                                                          p1, &radius);
6117                     if (!intersecting)intersecting = sphere_line_intersection(&model->vertex[model->Triangles[j].vertex[0]],
6118                                                          &model->vertex[model->Triangles[j].vertex[2]],
6119                                                          p1, &radius);
6120                     end = *p1 - point;
6121                     if (dotproduct(&model->facenormals[j], &end) > 0 && intersecting) {
6122                         start = *p1;
6123                         end = *p1;
6124                         end.y -= radius;
6125                         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)) {
6126                             p1->y = point.y + radius;
6127                             if ((animTarget == jumpdownanim || isFlip())) {
6128                                 if (isFlip() && (frameTarget < 5 || animation[animTarget].label[frameTarget] == 7 || animation[animTarget].label[frameTarget] == 4))RagDoll(0);
6129
6130                                 if (animTarget == jumpupanim) {
6131                                     jumppower = -4;
6132                                     animTarget = getIdle();
6133                                 }
6134                                 target = 0;
6135                                 frameTarget = 0;
6136                                 onterrain = 1;
6137
6138                                 if (id == 0) {
6139                                     pause_sound(whooshsound);
6140                                     OPENAL_SetVolume(channels[whooshsound], 0);
6141                                 }
6142
6143                                 if ((animTarget == jumpdownanim || isFlip()) && !wasLanding() && !wasLandhard()) {
6144                                     if (isFlip())jumppower = -4;
6145                                     animTarget = getLanding();
6146                                     emit_sound_at(landsound, coords, 128.);
6147
6148                                     if (id == 0) {
6149                                         envsound[numenvsounds] = coords;
6150                                         envsoundvol[numenvsounds] = 16;
6151                                         envsoundlife[numenvsounds] = .4;
6152                                         numenvsounds++;
6153                                     }
6154                                 }
6155                             }
6156                         }
6157                     }
6158                 }
6159                 if ((distance < olddistance || firstintersecting == -1) && intersecting) {
6160                     olddistance = distance;
6161                     firstintersecting = j;
6162                     *p = point;
6163                 }
6164             }
6165         }
6166         for (j = 0; j < model->TriangleNum; j++) {
6167             if (model->facenormals[j].y > slopethreshold) {
6168                 intersecting = 0;
6169                 start = *p1;
6170                 start.y -= radius / 4;
6171                 distance = abs((model->facenormals[j].x * start.x) + (model->facenormals[j].y * start.y) + (model->facenormals[j].z * start.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)));
6172                 if (distance < radius * .5) {
6173                     point = start - model->facenormals[j] * distance;
6174                     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]]))intersecting = 1;
6175                     if (!intersecting)intersecting = sphere_line_intersection(model->vertex[model->Triangles[j].vertex[0]].x, model->vertex[model->Triangles[j].vertex[0]].y, model->vertex[model->Triangles[j].vertex[0]].z,
6176                                                          model->vertex[model->Triangles[j].vertex[1]].x, model->vertex[model->Triangles[j].vertex[1]].y, model->vertex[model->Triangles[j].vertex[1]].z,
6177                                                          p1->x, p1->y, p1->z, radius / 2);
6178                     if (!intersecting)intersecting = sphere_line_intersection(model->vertex[model->Triangles[j].vertex[1]].x, model->vertex[model->Triangles[j].vertex[1]].y, model->vertex[model->Triangles[j].vertex[1]].z,
6179                                                          model->vertex[model->Triangles[j].vertex[2]].x, model->vertex[model->Triangles[j].vertex[2]].y, model->vertex[model->Triangles[j].vertex[2]].z,
6180                                                          p1->x, p1->y, p1->z, radius / 2);
6181                     if (!intersecting)intersecting = sphere_line_intersection(model->vertex[model->Triangles[j].vertex[0]].x, model->vertex[model->Triangles[j].vertex[0]].y, model->vertex[model->Triangles[j].vertex[0]].z,
6182                                                          model->vertex[model->Triangles[j].vertex[2]].x, model->vertex[model->Triangles[j].vertex[2]].y, model->vertex[model->Triangles[j].vertex[2]].z,
6183                                                          p1->x, p1->y, p1->z, radius / 2);
6184                     end = *p1 - point;
6185                     if (dotproduct(&model->facenormals[j], &end) > 0 && intersecting) {
6186                         if ((animTarget == jumpdownanim || animTarget == jumpupanim || isFlip())) {
6187                             start = velocity;
6188                             velocity -= DoRotation(model->facenormals[j], 0, *rotate, 0) * findLength(&velocity) * abs(normaldotproduct(velocity, DoRotation(model->facenormals[j], 0, *rotate, 0))); //(distance-radius*.5)/multiplier;
6189                             if (findLengthfast(&start) < findLengthfast(&velocity))velocity = start;
6190                         }
6191                         *p1 += model->facenormals[j] * (distance - radius * .5);
6192                     }
6193                 }
6194                 if ((distance < olddistance || firstintersecting == -1) && intersecting) {
6195                     olddistance = distance;
6196                     firstintersecting = j;
6197                     *p = point;
6198                 }
6199             }
6200         }
6201     }
6202     if (*rotate)*p = DoRotation(*p, 0, *rotate, 0);
6203     *p = *p + *move;
6204     if (*rotate)*p1 = DoRotation(*p1, 0, *rotate, 0);
6205     *p1 += *move;
6206     return firstintersecting;
6207 }