]> git.jsancho.org Git - lugaru.git/blobdiff - Source/Objects/Person.cpp
Added hasClaws property for PersonType
[lugaru.git] / Source / Objects / Person.cpp
index ece23ecddef6221a84d89f341e9dc73b3b5c0253..ff699a1cae6109729496d30d7a3f06130250d029 100644 (file)
@@ -42,8 +42,6 @@ extern float slomodelay;
 extern bool cellophane;
 extern float texdetail;
 extern float realtexdetail;
-extern GLubyte bloodText[512 * 512 * 3];
-extern GLubyte wolfbloodText[512 * 512 * 3];
 extern int bloodtoggle;
 extern bool autoslomo;
 extern float camerashake;
@@ -74,24 +72,7 @@ extern float envsoundlife[30];
 
 extern XYZ windvector;
 
-std::vector<std::shared_ptr<Person>> Person::players(1, std::shared_ptr<Person>(new Person()));
-std::vector<PersonType> PersonType::types;
-
-void PersonType::Load()
-{
-    types.resize(2);
-
-    types[wolftype].proportions[0] = 1.1;
-    types[wolftype].proportions[1] = 1.1;
-    types[wolftype].proportions[2] = 1.1;
-    types[wolftype].proportions[3] = 1.1;
-
-    types[rabbittype].proportions[0] = 1.2;
-    types[rabbittype].proportions[1] = 1.05;
-    types[rabbittype].proportions[2] = 1;
-    types[rabbittype].proportions[3] = 1.1;
-    types[rabbittype].proportions[3].y = 1.05;
-}
+std::vector<std::shared_ptr<Person>> Person::players;
 
 Person::Person()
     : whichpatchx(0)
@@ -149,30 +130,24 @@ Person::Person()
     , skiddingdelay(0)
     , deathbleeding(0)
     , tempdeltav(0)
-    ,
 
-    damagetolerance(200)
+    , damagetolerance(0)
     , damage(0)
     , permanentdamage(0)
     , superpermanentdamage(0)
     , lastcollide(0)
     , dead(0)
-    ,
 
-    jumppower(5)
+    jumppower(5)
     , onground(false)
-    ,
 
-    wentforweapon(0)
-    ,
+    , wentforweapon(0)
 
-    calcrot(false)
-    ,
+    , calcrot(false)
 
-    facing()
-    ,
+    , facing()
 
-    bleeding(0)
+    bleeding(0)
     , bleedx(0)
     , bleedy(0)
     , direction(0)
@@ -361,17 +336,15 @@ Person::Person()
     , neckspurtdelay(0)
     , neckspurtparticledelay(0)
     , neckspurtamount(0)
-    ,
 
-    whichskin(0)
+    whichskin(0)
     , rabbitkickragdoll(false)
-    ,
 
-    tempanimation()
-    ,
+    , tempanimation("Tempanim", lowheight, neutral)
 
-    jumpclimb(false)
+    jumpclimb(false)
 {
+    damagetolerance = PersonType::types[creature].defaultDamageTolerance;
     setProportions(1, 1, 1, 1);
 }
 
@@ -454,55 +427,44 @@ Person::Person(FILE* tfile, int mapvers, unsigned i)
 
     loaded = true;
 
+    damagetolerance = PersonType::types[creature].defaultDamageTolerance;
+
     if (scale < 0) {
-        if (creature == wolftype) {
-            scale = .23;
-            damagetolerance = 300;
-        } else {
-            scale = .2;
-        }
+        scale = PersonType::types[creature].defaultScale;
     }
 
     oldcoords = coords;
     realoldcoords = coords;
 }
 
+void Person::changeCreatureType(person_type type)
+{
+    creature = type;
+    whichskin = 0;
+    skeletonLoad(type == rabbittype);
+    scale = PersonType::types[creature].defaultScale;
+    damagetolerance = PersonType::types[creature].defaultDamageTolerance;
+}
+
 void Person::skeletonLoad(bool clothes)
 {
     skeleton.id = id;
-    if (creature != wolftype) {
-        skeleton.Load(
-            "Skeleton/BasicFigure",
-            "Skeleton/BasicFigureLow",
-            "Skeleton/RabbitBelt",
-            "Models/Body.solid",
-            "Models/Body2.solid",
-            "Models/Body3.solid",
-            "Models/Body4.solid",
-            "Models/Body5.solid",
-            "Models/Body6.solid",
-            "Models/Body7.solid",
-            "Models/BodyLow.solid",
-            "Models/Belt.solid",
-            clothes);
-    } else {
-        skeleton.Load(
-            "Skeleton/BasicFigureWolf",
-            "Skeleton/BasicFigureWolfLow",
-            "Skeleton/RabbitBelt",
-            "Models/Wolf.solid",
-            "Models/Wolf2.solid",
-            "Models/Wolf3.solid",
-            "Models/Wolf4.solid",
-            "Models/Wolf5.solid",
-            "Models/Wolf6.solid",
-            "Models/Wolf7.solid",
-            "Models/WolfLow.solid",
-            "Models/Belt.solid",
-            clothes);
-    }
-
-    skeleton.drawmodel.textureptr.load(creatureskin[creature][whichskin], 1, &skeleton.skinText[0], &skeleton.skinsize);
+    skeleton.Load(
+        PersonType::types[creature].figureFileName,
+        PersonType::types[creature].lowFigureFileName,
+        PersonType::types[creature].clothesFileName,
+        PersonType::types[creature].modelFileNames[0],
+        PersonType::types[creature].modelFileNames[1],
+        PersonType::types[creature].modelFileNames[2],
+        PersonType::types[creature].modelFileNames[3],
+        PersonType::types[creature].modelFileNames[4],
+        PersonType::types[creature].modelFileNames[5],
+        PersonType::types[creature].modelFileNames[6],
+        PersonType::types[creature].lowModelFileName,
+        PersonType::types[creature].modelClothesFileName,
+        clothes);
+
+    skeleton.drawmodel.textureptr.load(PersonType::types[creature].skins[whichskin], 1, &skeleton.skinText[0], &skeleton.skinsize);
 }
 
 void Person::setProportions(float head, float body, float arms, float legs)
@@ -513,7 +475,12 @@ void Person::setProportions(float head, float body, float arms, float legs)
     proportions[3] = legs;
 }
 
-XYZ Person::getProportion(int part) const
+float Person::getProportion(int part) const
+{
+    return proportions[part];
+}
+
+XYZ Person::getProportionXYZ(int part) const
 {
     XYZ prop = PersonType::types[creature].proportions[part] * proportions[part];
     if (cellophane) {
@@ -534,7 +501,7 @@ void Person::CheckKick()
     }
 
     if (Animation::animations[victim->animTarget].height != lowheight) {
-        float damagemult = (creature == wolftype ? 2.5 : 1.) * power * power;
+        float damagemult = PersonType::types[creature].power * power * power;
         XYZ relative = velocity;
         relative.y = 0;
         Normalise(&relative);
@@ -622,20 +589,15 @@ void Person::CatchFire()
  */
 int Person::getIdle()
 {
-    if (Dialog::inDialog() && (howactive == typeactive) && (creature == rabbittype)) {
-        return talkidleanim;
+    if (Dialog::inDialog() && (howactive == typeactive) && PersonType::types[creature].hasAnimTalkIdle()) {
+        return PersonType::types[creature].animTalkIdle;
     }
     if (hasvictim && (victim != this->shared_from_this())) {
         if ((!victim->dead && victim->aitype != passivetype &&
              victim->aitype != searchtype && aitype != passivetype && aitype != searchtype &&
              victim->id < Person::players.size())) {
             if ((aitype == playercontrolled && stunned <= 0 && weaponactive == -1) || pause) {
-                if (creature == rabbittype) {
-                    return fightidleanim;
-                }
-                if (creature == wolftype) {
-                    return wolfidle;
-                }
+                return PersonType::types[creature].animFightIdle;
             }
             if (aitype == playercontrolled && stunned <= 0 && weaponactive != -1) {
                 if (weapons[weaponids[weaponactive]].getType() == knife) {
@@ -680,13 +642,7 @@ int Person::getIdle()
     if (howactive == typedead4) {
         return dead4anim;
     }
-    if (creature == rabbittype) {
-        return bounceidleanim;
-    }
-    if (creature == wolftype) {
-        return wolfidle;
-    }
-    return 0;
+    return PersonType::types[creature].animBounceIdle;
 }
 
 /* FUNCTION
@@ -694,13 +650,7 @@ int Person::getIdle()
  */
 int Person::getCrouch()
 {
-    if (creature == rabbittype) {
-        return crouchanim;
-    }
-    if (creature == wolftype) {
-        return wolfcrouchanim;
-    }
-    return 0;
+    return PersonType::types[creature].animCrouch;
 }
 
 /* FUNCTION
@@ -708,59 +658,32 @@ int Person::getCrouch()
  */
 int Person::getRun()
 {
-    if (creature == rabbittype && (!superruntoggle || weaponactive != -1)) {
-        return runanim;
-    }
-    if (creature == wolftype && (!superruntoggle)) {
-        return wolfrunanim;
-    }
-
-    if (creature == rabbittype && (superruntoggle && weaponactive == -1)) {
-        return rabbitrunninganim;
-    }
-    if (creature == wolftype && (superruntoggle)) {
-        return wolfrunninganim;
+    if (superruntoggle && (weaponactive == -1)) {
+        return PersonType::types[creature].animRunning;
+    } else {
+        return PersonType::types[creature].animRun;
     }
-    return 0;
 }
 
 /* FUNCTION
  */
 int Person::getStop()
 {
-    if (creature == rabbittype) {
-        return stopanim;
-    }
-    if (creature == wolftype) {
-        return wolfstopanim;
-    }
-    return 0;
+    return PersonType::types[creature].animStop;
 }
 
 /* FUNCTION
  */
 int Person::getLanding()
 {
-    if (creature == rabbittype) {
-        return landanim;
-    }
-    if (creature == wolftype) {
-        return wolflandanim;
-    }
-    return 0;
+    return PersonType::types[creature].animLanding;
 }
 
 /* FUNCTION
  */
 int Person::getLandhard()
 {
-    if (creature == rabbittype) {
-        return landhardanim;
-    }
-    if (creature == wolftype) {
-        return wolflandhardanim;
-    }
-    return 0;
+    return PersonType::types[creature].animLandingHard;
 }
 
 /* EFFECT
@@ -834,17 +757,9 @@ void Person::DoBlood(float howmuch, int which)
             bleeding = howmuch + (float)abs(Random() % 100) / 200 - .25;
             bleedxint = 0;
             bleedyint = 0;
-            if (creature == rabbittype) {
-                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) {
-                    bleedxint = abs(Random() % 512);
-                    bleedyint = abs(Random() % 512);
-                }
-            }
-            if (creature == wolftype) {
-                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) {
-                    bleedxint = abs(Random() % 512);
-                    bleedyint = abs(Random() % 512);
-                }
+            while (PersonType::types[creature].bloodText[bleedxint * 512 * 3 + bleedyint * 3 + 0] > which + 4 || PersonType::types[creature].bloodText[bleedxint * 512 * 3 + bleedyint * 3 + 0] < which - 4 || bleedxint < 10 || bleedyint < 10 || bleedxint > 500 || bleedyint > 500) {
+                bleedxint = abs(Random() % 512);
+                bleedyint = abs(Random() % 512);
             }
             bleedy = bleedxint;
             bleedx = bleedyint;
@@ -957,42 +872,20 @@ void Person::DoBloodBig(float howmuch, int which)
         int endx = 0;
         int endy = 0;
         GLubyte color;
-        if (creature == rabbittype) {
-            for (i = 0; i < 512; i++) {
-                for (j = 0; j < 512; j++) {
-                    if (bloodText[i * 512 * 3 + j * 3 + 0] <= which + 4 && bloodText[i * 512 * 3 + j * 3 + 0] >= which - 4) {
-                        if (i < startx) {
-                            startx = i;
-                        }
-                        if (j < starty) {
-                            starty = j;
-                        }
-                        if (i > endx) {
-                            endx = i;
-                        }
-                        if (j > endy) {
-                            endy = j;
-                        }
+        for (i = 0; i < 512; i++) {
+            for (j = 0; j < 512; j++) {
+                if (PersonType::types[creature].bloodText[i * 512 * 3 + j * 3 + 0] <= which + 4 && PersonType::types[creature].bloodText[i * 512 * 3 + j * 3 + 0] >= which - 4) {
+                    if (i < startx) {
+                        startx = i;
                     }
-                }
-            }
-        }
-        if (creature == wolftype) {
-            for (i = 0; i < 512; i++) {
-                for (j = 0; j < 512; j++) {
-                    if (wolfbloodText[i * 512 * 3 + j * 3 + 0] <= which + 4 && wolfbloodText[i * 512 * 3 + j * 3 + 0] >= which - 4) {
-                        if (i < startx) {
-                            startx = i;
-                        }
-                        if (j < starty) {
-                            starty = j;
-                        }
-                        if (i > endx) {
-                            endx = i;
-                        }
-                        if (j > endy) {
-                            endy = j;
-                        }
+                    if (j < starty) {
+                        starty = j;
+                    }
+                    if (i > endx) {
+                        endx = i;
+                    }
+                    if (j > endy) {
+                        endy = j;
                     }
                 }
             }
@@ -1029,33 +922,16 @@ void Person::DoBloodBig(float howmuch, int which)
 
         int texdetailint = realtexdetail;
         int where;
-        if (creature == rabbittype) {
-            for (i = startx; i < endx; i++) {
-                for (j = starty; j < endy; j++) {
-                    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) {
-                        color = Random() % 85 + 170;
-                        where = i * skeleton.skinsize * 3 + j * 3;
-                        if (skeleton.skinText[where + 0] > color / 2) {
-                            skeleton.skinText[where + 0] = color / 2;
-                        }
-                        skeleton.skinText[where + 1] = 0;
-                        skeleton.skinText[where + 2] = 0;
-                    }
-                }
-            }
-        }
-        if (creature == wolftype) {
-            for (i = startx; i < endx; i++) {
-                for (j = starty; j < endy; j++) {
-                    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) {
-                        color = Random() % 85 + 170;
-                        where = i * skeleton.skinsize * 3 + j * 3;
-                        if (skeleton.skinText[where + 0] > color / 2) {
-                            skeleton.skinText[where + 0] = color / 2;
-                        }
-                        skeleton.skinText[where + 1] = 0;
-                        skeleton.skinText[where + 2] = 0;
+        for (i = startx; i < endx; i++) {
+            for (j = starty; j < endy; j++) {
+                if (PersonType::types[creature].bloodText[(i * texdetailint - offsetx) * 512 * 3 + (j * texdetailint - offsety) * 3 + 0] <= which + 4 && PersonType::types[creature].bloodText[(i * texdetailint - offsetx) * 512 * 3 + (j * texdetailint - offsety) * 3 + 0] >= which - 4) {
+                    color = Random() % 85 + 170;
+                    where = i * skeleton.skinsize * 3 + j * 3;
+                    if (skeleton.skinText[where + 0] > color / 2) {
+                        skeleton.skinText[where + 0] = color / 2;
                     }
+                    skeleton.skinText[where + 1] = 0;
+                    skeleton.skinText[where + 2] = 0;
                 }
             }
         }
@@ -1064,17 +940,9 @@ void Person::DoBloodBig(float howmuch, int which)
 
         bleedxint = 0;
         bleedyint = 0;
-        if (creature == rabbittype) {
-            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) {
-                bleedxint = abs(Random() % 512);
-                bleedyint = abs(Random() % 512);
-            }
-        }
-        if (creature == wolftype) {
-            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) {
-                bleedxint = abs(Random() % 512);
-                bleedyint = abs(Random() % 512);
-            }
+        while (PersonType::types[creature].bloodText[bleedxint * 512 * 3 + bleedyint * 3 + 0] > which + 4 || PersonType::types[creature].bloodText[bleedxint * 512 * 3 + bleedyint * 3 + 0] < which - 4 || bleedxint < 10 || bleedyint < 10 || bleedxint > 500 || bleedyint > 500) {
+            bleedxint = abs(Random() % 512);
+            bleedyint = abs(Random() % 512);
         }
         bleedy = bleedxint + offsetx;
         bleedx = bleedyint + offsety;
@@ -1208,42 +1076,20 @@ bool Person::DoBloodBigWhere(float howmuch, int which, XYZ where)
             int endx = 0;
             int endy = 0;
             GLubyte color;
-            if (creature == rabbittype) {
-                for (i = 0; i < 512; i++) {
-                    for (j = 0; j < 512; j++) {
-                        if (bloodText[i * 512 * 3 + j * 3 + 0] <= which + 4 && bloodText[i * 512 * 3 + j * 3 + 0] >= which - 4) {
-                            if (i < startx) {
-                                startx = i;
-                            }
-                            if (j < starty) {
-                                starty = j;
-                            }
-                            if (i > endx) {
-                                endx = i;
-                            }
-                            if (j > endy) {
-                                endy = j;
-                            }
+            for (i = 0; i < 512; i++) {
+                for (j = 0; j < 512; j++) {
+                    if (PersonType::types[creature].bloodText[i * 512 * 3 + j * 3 + 0] <= which + 4 && PersonType::types[creature].bloodText[i * 512 * 3 + j * 3 + 0] >= which - 4) {
+                        if (i < startx) {
+                            startx = i;
                         }
-                    }
-                }
-            }
-            if (creature == wolftype) {
-                for (i = 0; i < 512; i++) {
-                    for (j = 0; j < 512; j++) {
-                        if (wolfbloodText[i * 512 * 3 + j * 3 + 0] <= which + 4 && wolfbloodText[i * 512 * 3 + j * 3 + 0] >= which - 4) {
-                            if (i < startx) {
-                                startx = i;
-                            }
-                            if (j < starty) {
-                                starty = j;
-                            }
-                            if (i > endx) {
-                                endx = i;
-                            }
-                            if (j > endy) {
-                                endy = j;
-                            }
+                        if (j < starty) {
+                            starty = j;
+                        }
+                        if (i > endx) {
+                            endx = i;
+                        }
+                        if (j > endy) {
+                            endy = j;
                         }
                     }
                 }
@@ -1279,49 +1125,24 @@ bool Person::DoBloodBigWhere(float howmuch, int which, XYZ where)
 
             int texdetailint = realtexdetail;
             int where;
-            if (creature == rabbittype) {
-                for (i = startx; i < endx; i++) {
-                    for (j = starty; j < endy; j++) {
-                        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) {
-                            color = Random() % 85 + 170;
-                            where = i * skeleton.skinsize * 3 + j * 3;
-                            if (skeleton.skinText[where + 0] > color / 2) {
-                                skeleton.skinText[where + 0] = color / 2;
-                            }
-                            skeleton.skinText[where + 1] = 0;
-                            skeleton.skinText[where + 2] = 0;
-                        } 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) {
-                            color = Random() % 85 + 170;
-                            where = i * skeleton.skinsize * 3 + j * 3;
-                            if (skeleton.skinText[where + 0] > color / 2) {
-                                skeleton.skinText[where + 0] = color / 2;
-                            }
-                            skeleton.skinText[where + 1] = 0;
-                            skeleton.skinText[where + 2] = 0;
+            for (i = startx; i < endx; i++) {
+                for (j = starty; j < endy; j++) {
+                    if (PersonType::types[creature].bloodText[(i * texdetailint - offsetx) * 512 * 3 + (j * texdetailint - offsety) * 3 + 0] <= which + 4 && PersonType::types[creature].bloodText[(i * texdetailint - offsetx) * 512 * 3 + (j * texdetailint - offsety) * 3 + 0] >= which - 4) {
+                        color = Random() % 85 + 170;
+                        where = i * skeleton.skinsize * 3 + j * 3;
+                        if (skeleton.skinText[where + 0] > color / 2) {
+                            skeleton.skinText[where + 0] = color / 2;
                         }
-                    }
-                }
-            }
-            if (creature == wolftype) {
-                for (i = startx; i < endx; i++) {
-                    for (j = starty; j < endy; j++) {
-                        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) {
-                            color = Random() % 85 + 170;
-                            where = i * skeleton.skinsize * 3 + j * 3;
-                            if (skeleton.skinText[where + 0] > color / 2) {
-                                skeleton.skinText[where + 0] = color / 2;
-                            }
-                            skeleton.skinText[where + 1] = 0;
-                            skeleton.skinText[where + 2] = 0;
-                        } 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) {
-                            color = Random() % 85 + 170;
-                            where = i * skeleton.skinsize * 3 + j * 3;
-                            if (skeleton.skinText[where + 0] > color / 2) {
-                                skeleton.skinText[where + 0] = color / 2;
-                            }
-                            skeleton.skinText[where + 1] = 0;
-                            skeleton.skinText[where + 2] = 0;
+                        skeleton.skinText[where + 1] = 0;
+                        skeleton.skinText[where + 2] = 0;
+                    } else if (PersonType::types[creature].bloodText[(i * texdetailint - offsetx) * 512 * 3 + (j * texdetailint - offsety) * 3 + 0] <= 160 + 4 && PersonType::types[creature].bloodText[(i * texdetailint - offsetx) * 512 * 3 + (j * texdetailint - offsety) * 3 + 0] >= 160 - 4) {
+                        color = Random() % 85 + 170;
+                        where = i * skeleton.skinsize * 3 + j * 3;
+                        if (skeleton.skinText[where + 0] > color / 2) {
+                            skeleton.skinText[where + 0] = color / 2;
                         }
+                        skeleton.skinText[where + 1] = 0;
+                        skeleton.skinText[where + 2] = 0;
                     }
                 }
             }
@@ -2269,8 +2090,7 @@ void Person::DoAnimations()
                     if (victim->aitype == gethelptype) {
                         victim->DoDamage(victim->damagetolerance - victim->damage);
                     }
-                    //victim->DoDamage(30);
-                    if (creature == wolftype) {
+                    if (PersonType::types[creature].hasClaws) {
                         DoBloodBig(0, 255);
                         emit_sound_at(clawslicesound, victim->coords);
                         victim->spurt = 1;
@@ -2388,34 +2208,7 @@ void Person::DoAnimations()
                             if (targetFrame().label == 4 && aitype != playercontrolled) {
                                 if (Animation::animations[animTarget].attack != neutral) {
                                     unsigned r = abs(Random() % 4);
-                                    if (creature == rabbittype) {
-                                        if (r == 0) {
-                                            whichsound = rabbitattacksound;
-                                        }
-                                        if (r == 1) {
-                                            whichsound = rabbitattack2sound;
-                                        }
-                                        if (r == 2) {
-                                            whichsound = rabbitattack3sound;
-                                        }
-                                        if (r == 3) {
-                                            whichsound = rabbitattack4sound;
-                                        }
-                                    }
-                                    if (creature == wolftype) {
-                                        if (r == 0) {
-                                            whichsound = barksound;
-                                        }
-                                        if (r == 1) {
-                                            whichsound = bark2sound;
-                                        }
-                                        if (r == 2) {
-                                            whichsound = bark3sound;
-                                        }
-                                        if (r == 3) {
-                                            whichsound = barkgrowlsound;
-                                        }
-                                    }
+                                    whichsound = PersonType::types[creature].soundsAttack[r];
                                     speechdelay = .3;
                                 }
                             }
@@ -2439,7 +2232,7 @@ void Person::DoAnimations()
             animCurrent = animTarget;
             frameTarget++;
 
-            if (animTarget == removeknifeanim && Animation::animations[animTarget].frames[frameCurrent].label == 5) {
+            if (animCurrent == removeknifeanim && currentFrame().label == 5) {
                 for (unsigned i = 0; i < weapons.size(); i++) {
                     if (weapons[i].owner == -1) {
                         if (distsqflat(&coords, &weapons[i].position) < 4 && weaponactive == -1) {
@@ -2455,7 +2248,7 @@ void Person::DoAnimations()
                 }
             }
 
-            if (animTarget == crouchremoveknifeanim && Animation::animations[animTarget].frames[frameCurrent].label == 5) {
+            if (animCurrent == crouchremoveknifeanim && currentFrame().label == 5) {
                 for (unsigned i = 0; i < weapons.size(); i++) {
                     bool willwork = true;
                     if (weapons[i].owner != -1) {
@@ -2541,7 +2334,7 @@ void Person::DoAnimations()
                 }
             }
 
-            if (animCurrent == drawleftanim && Animation::animations[animTarget].frames[frameCurrent].label == 5) {
+            if (animCurrent == drawleftanim && currentFrame().label == 5) {
                 if (weaponactive == -1) {
                     weaponactive = 0;
                 } else if (weaponactive == 0) {
@@ -2641,31 +2434,28 @@ void Person::DoAnimations()
             }
 
             //Move impacts
-            float damagemult = 1 * power;
-            if (creature == wolftype) {
-                damagemult = 2.5 * power;
-            }
+            float damagemult = PersonType::types[creature].power * power;
             if (hasvictim) {
                 damagemult /= victim->damagetolerance / 200;
             }
             if ((Animation::animations[animTarget].attack == normalattack || animTarget == walljumprightkickanim || animTarget == walljumpleftkickanim) && (!feint) && (victim->skeleton.free != 2 || animTarget == killanim || animTarget == dropkickanim || animTarget == crouchstabanim || animTarget == swordgroundstabanim || animTarget == staffgroundsmashanim)) {
-                if (animTarget == spinkickanim && Animation::animations[animTarget].frames[frameCurrent].label == 5) {
+                if (animCurrent == spinkickanim && currentFrame().label == 5) {
                     if (distsq(&coords, &victim->coords) < (scale * 5) * (scale * 5) * 3 && Animation::animations[victim->animTarget].height != lowheight) {
                         escapednum = 0;
                         if (id == 0) {
                             camerashake += .4;
                         }
-                        if (Random() % 2 || creature == wolftype) {
+                        if (Random() % 2 || PersonType::types[creature].hasClaws) {
                             victim->spurt = 1;
                             DoBlood(.2, 250);
-                            if (creature == wolftype) {
+                            if (PersonType::types[creature].hasClaws) {
                                 DoBloodBig(0, 250);
                             }
                         }
                         if (!Tutorial::active) {
                             emit_sound_at(heavyimpactsound, victim->coords, 128.);
                         }
-                        if (creature == wolftype) {
+                        if (PersonType::types[creature].hasClaws) {
                             emit_sound_at(clawslicesound, victim->coords, 128.);
                             victim->spurt = 1;
                             victim->DoBloodBig(2 / victim->armorhead, 175);
@@ -2687,20 +2477,20 @@ void Person::DoAnimations()
                     }
                 }
 
-                if (animTarget == wolfslapanim && Animation::animations[animTarget].frames[frameCurrent].label == 5) {
+                if (animCurrent == wolfslapanim && currentFrame().label == 5) {
                     if (distsq(&coords, &victim->coords) < (scale * 5) * (scale * 5) * 3 && Animation::animations[victim->animTarget].height != lowheight) {
                         escapednum = 0;
                         if (id == 0) {
                             camerashake += .4;
                         }
-                        if (Random() % 2 || creature == wolftype) {
+                        if (Random() % 2 || PersonType::types[creature].hasClaws) {
                             victim->spurt = 1;
-                            if (creature == wolftype) {
+                            if (PersonType::types[creature].hasClaws) {
                                 DoBloodBig(0, 235);
                             }
                         }
                         emit_sound_at(whooshhitsound, victim->coords);
-                        if (creature == wolftype) {
+                        if (PersonType::types[creature].hasClaws) {
                             emit_sound_at(clawslicesound, victim->coords, 128.);
                             victim->spurt = 1;
                             victim->DoBloodBig(2, 175);
@@ -2722,7 +2512,7 @@ void Person::DoAnimations()
                     }
                 }
 
-                if (animTarget == walljumprightkickanim && Animation::animations[animTarget].frames[frameCurrent].label == 5) {
+                if (animCurrent == walljumprightkickanim && currentFrame().label == 5) {
                     if (distsq(&coords, &victim->coords) < (scale * 5) * (scale * 5) * 3 && Animation::animations[victim->animTarget].height != lowheight) {
                         escapednum = 0;
                         if (id == 0) {
@@ -2733,7 +2523,7 @@ void Person::DoAnimations()
                         if (!Tutorial::active) {
                             emit_sound_at(heavyimpactsound, victim->coords, 160.);
                         }
-                        if (creature == wolftype) {
+                        if (PersonType::types[creature].hasClaws) {
                             emit_sound_at(clawslicesound, victim->coords, 128.);
                             victim->spurt = 1;
                             victim->DoBloodBig(2 / victim->armorhead, 175);
@@ -2759,7 +2549,7 @@ void Person::DoAnimations()
                     }
                 }
 
-                if (animTarget == walljumpleftkickanim && Animation::animations[animTarget].frames[frameCurrent].label == 5) {
+                if (animCurrent == walljumpleftkickanim && currentFrame().label == 5) {
                     if (distsq(&coords, &victim->coords) < (scale * 5) * (scale * 5) * 3 && Animation::animations[victim->animTarget].height != lowheight) {
                         escapednum = 0;
                         if (id == 0) {
@@ -2770,7 +2560,7 @@ void Person::DoAnimations()
                         if (!Tutorial::active) {
                             emit_sound_at(heavyimpactsound, victim->coords, 160.);
                         }
-                        if (creature == wolftype) {
+                        if (PersonType::types[creature].hasClaws) {
                             emit_sound_at(clawslicesound, victim->coords, 128.);
                             victim->spurt = 1;
                             victim->DoBloodBig(2 / victim->armorhead, 175);
@@ -2796,7 +2586,7 @@ void Person::DoAnimations()
                     }
                 }
 
-                if (animTarget == blockhighleftstrikeanim && Animation::animations[animTarget].frames[frameCurrent].label == 5) {
+                if (animCurrent == blockhighleftstrikeanim && currentFrame().label == 5) {
                     if (distsq(&coords, &victim->coords) < (scale * 5) * (scale * 5) * 3 && Animation::animations[victim->animTarget].height != lowheight) {
                         escapednum = 0;
                         if (id == 0) {
@@ -2821,7 +2611,7 @@ void Person::DoAnimations()
                     }
                 }
 
-                if (animTarget == killanim && Animation::animations[animTarget].frames[frameCurrent].label == 8) {
+                if (animCurrent == killanim && currentFrame().label == 8) {
                     if (distsq(&coords, &victim->coords) < (scale * 5) * (scale * 5) * 3 && victim->dead) {
                         escapednum = 0;
                         if (id == 0) {
@@ -2856,7 +2646,7 @@ void Person::DoAnimations()
                     }
                 }
 
-                if (animTarget == killanim && Animation::animations[animTarget].frames[frameCurrent].label == 5) {
+                if (animCurrent == killanim && currentFrame().label == 5) {
                     if (distsq(&coords, &victim->coords) < (scale * 5) * (scale * 5) * 9 && victim->dead) {
                         escapednum = 0;
                         if (id == 0) {
@@ -2882,7 +2672,7 @@ void Person::DoAnimations()
                     }
                 }
 
-                if (animTarget == dropkickanim && Animation::animations[animTarget].frames[frameCurrent].label == 7) {
+                if (animCurrent == dropkickanim && currentFrame().label == 7) {
                     if (distsq(&coords, &victim->coords) < (scale * 5) * (scale * 5) * 9 && victim->skeleton.free) {
                         escapednum = 0;
                         if (id == 0) {
@@ -2924,7 +2714,7 @@ void Person::DoAnimations()
                     }
                 }
 
-                if ((animTarget == crouchstabanim || animTarget == swordgroundstabanim) && Animation::animations[animTarget].frames[frameCurrent].label == 5) {
+                if ((animCurrent == crouchstabanim || animCurrent == swordgroundstabanim) && currentFrame().label == 5) {
 
                     if (hasvictim) {
                         if (!victim->skeleton.free) {
@@ -3021,7 +2811,7 @@ void Person::DoAnimations()
                     }
                 }
 
-                if ((animTarget == crouchstabanim || animTarget == swordgroundstabanim) && Animation::animations[animTarget].frames[frameCurrent].label == 6) {
+                if ((animCurrent == crouchstabanim || animCurrent == swordgroundstabanim) && currentFrame().label == 6) {
                     if (!hasvictim) {
                         emit_sound_at(knifedrawsound, coords, 128);
                     }
@@ -3125,7 +2915,7 @@ void Person::DoAnimations()
                     }
                 }
 
-                if (animTarget == upunchanim && Animation::animations[animTarget].frames[frameCurrent].label == 5) {
+                if (animCurrent == upunchanim && currentFrame().label == 5) {
                     if (distsq(&coords, &victim->coords) < (scale * 5) * (scale * 5) * 3) {
                         escapednum = 0;
                         if (id == 0) {
@@ -3163,7 +2953,7 @@ void Person::DoAnimations()
                     }
                 }
 
-                if (animTarget == winduppunchanim && Animation::animations[animTarget].frames[frameCurrent].label == 5) {
+                if (animCurrent == winduppunchanim && currentFrame().label == 5) {
                     if (distsq(&coords, &victim->coords) < (scale * 5) * (scale * 5) * 2) {
                         escapednum = 0;
                         if (id == 0) {
@@ -3210,7 +3000,7 @@ void Person::DoAnimations()
                     }
                 }
 
-                if (animTarget == blockhighleftanim && Animation::animations[animTarget].frames[frameCurrent].label == 5) {
+                if (animCurrent == blockhighleftanim && currentFrame().label == 5) {
                     if (distsq(&coords, &victim->coords) < (scale * 5) * (scale * 5) * 4) {
                         if (victim->id == 0) {
                             camerashake += .4;
@@ -3221,7 +3011,7 @@ void Person::DoAnimations()
                     }
                 }
 
-                if (animTarget == swordslashparryanim && Animation::animations[animTarget].frames[frameCurrent].label == 5) {
+                if (animCurrent == swordslashparryanim && currentFrame().label == 5) {
                     if (distsq(&coords, &victim->coords) < (scale * 5) * (scale * 5) * 4) {
                         if (victim->id == 0) {
                             camerashake += .4;
@@ -3246,7 +3036,7 @@ void Person::DoAnimations()
                     }
                 }
 
-                if (animTarget == knifethrowanim && Animation::animations[animTarget].frames[frameCurrent].label == 5) {
+                if (animCurrent == knifethrowanim && currentFrame().label == 5) {
                     if (weaponactive != -1) {
                         escapednum = 0;
                         XYZ aim;
@@ -3261,9 +3051,9 @@ void Person::DoAnimations()
                     }
                 }
 
-                if (animTarget == knifeslashstartanim && Animation::animations[animTarget].frames[frameCurrent].label == 5) {
+                if (animCurrent == knifeslashstartanim && currentFrame().label == 5) {
                     if (hasvictim) {
-                        if (distsq(&coords, &victim->coords) < (scale * 5) * (scale * 5) * 4.5 && /*Animation::animations[victim->animTarget].height!=lowheight&&*/ victim->animTarget != dodgebackanim && victim->animTarget != rollanim) {
+                        if (distsq(&coords, &victim->coords) < (scale * 5) * (scale * 5) * 4.5 && victim->animTarget != dodgebackanim && victim->animTarget != rollanim) {
                             escapednum = 0;
                             if (!Tutorial::active) {
                                 victim->DoBloodBig(1.5 / victim->armorhigh, 225);
@@ -3318,7 +3108,7 @@ void Person::DoAnimations()
                         }
                     }
                 }
-                if (animTarget == swordslashanim && Animation::animations[animTarget].frames[frameCurrent].label == 5 && victim->animTarget != rollanim) {
+                if (animCurrent == swordslashanim && currentFrame().label == 5 && victim->animTarget != rollanim) {
                     if (distsq(&coords, &victim->coords) < (scale * 5) * (scale * 5) * 6.5 && victim->animTarget != dodgebackanim) {
                         if (victim->weaponactive == -1 || normaldotproduct(victim->facing, victim->coords - coords) > 0 || (Random() % 2 == 0)) {
                             award_bonus(id, Slashbonus);
@@ -3403,7 +3193,7 @@ void Person::DoAnimations()
                     }
                 }
 
-                if (animTarget == staffhitanim && Animation::animations[animTarget].frames[frameCurrent].label == 5 && victim->animTarget != rollanim) {
+                if (animCurrent == staffhitanim && currentFrame().label == 5 && victim->animTarget != rollanim) {
                     if (distsq(&coords, &victim->coords) < (scale * 5) * (scale * 5) * 6.5 && victim->animTarget != dodgebackanim && victim->animTarget != sweepanim) {
                         if (!Tutorial::active) {
                             weapons[weaponids[0]].damage += .4 + float(abs(Random() % 100) - 50) / 250;
@@ -3411,7 +3201,7 @@ void Person::DoAnimations()
                             if (id == 0) {
                                 camerashake += .4;
                             }
-                            if (Random() % 2 || creature == wolftype) {
+                            if (Random() % 2 || PersonType::types[creature].hasClaws) {
                                 victim->spurt = 1;
                             }
                             emit_sound_at(staffheadsound, victim->coords);
@@ -3438,7 +3228,7 @@ void Person::DoAnimations()
                     }
                 }
 
-                if (animTarget == staffspinhitanim && Animation::animations[animTarget].frames[frameCurrent].label == 5 && victim->animTarget != rollanim) {
+                if (animCurrent == staffspinhitanim && currentFrame().label == 5 && victim->animTarget != rollanim) {
                     if (distsq(&coords, &victim->coords) < (scale * 5) * (scale * 5) * 6.5 && victim->animTarget != dodgebackanim && victim->animTarget != sweepanim) {
                         if (!Tutorial::active) {
                             weapons[weaponids[0]].damage += .6 + float(abs(Random() % 100) - 50) / 250;
@@ -3446,7 +3236,7 @@ void Person::DoAnimations()
                             if (id == 0) {
                                 camerashake += .4;
                             }
-                            if (Random() % 2 || creature == wolftype) {
+                            if (Random() % 2 || PersonType::types[creature].hasClaws) {
                                 victim->spurt = 1;
                             }
                             emit_sound_at(staffheadsound, victim->coords);
@@ -3471,7 +3261,7 @@ void Person::DoAnimations()
                     }
                 }
 
-                if (animTarget == staffgroundsmashanim && Animation::animations[animTarget].frames[frameCurrent].label == 5) {
+                if (animCurrent == staffgroundsmashanim && currentFrame().label == 5) {
                     if (distsq(&coords, &victim->coords) < (scale * 5) * (scale * 5) * 6.5) {
                         escapednum = 0;
                         if (!Tutorial::active) {
@@ -3481,7 +3271,7 @@ void Person::DoAnimations()
                             if (id == 0) {
                                 camerashake += .4;
                             }
-                            if (Random() % 2 || creature == wolftype) {
+                            if (Random() % 2 || PersonType::types[creature].hasClaws) {
                                 victim->spurt = 1;
                             }
                             emit_sound_at(staffbodysound, victim->coords);
@@ -3523,7 +3313,7 @@ void Person::DoAnimations()
                     }
                 }
 
-                if (animTarget == lowkickanim && Animation::animations[animTarget].frames[frameCurrent].label == 5) {
+                if (animCurrent == lowkickanim && currentFrame().label == 5) {
                     if (distsq(&coords, &victim->coords) < (scale * 5) * (scale * 5) * 3 && Animation::animations[victim->animTarget].height != highheight) {
                         escapednum = 0;
                         if (id == 0) {
@@ -3554,7 +3344,7 @@ void Person::DoAnimations()
                             if (victim->howactive == typesleeping) {
                                 victim->DoDamage(damagemult * 150 / victim->protectionhead);
                             }
-                            if (creature == wolftype) {
+                            if (PersonType::types[creature].hasClaws) {
                                 emit_sound_at(clawslicesound, victim->coords, 128.);
                                 victim->spurt = 1;
                                 victim->DoBloodBig(2 / victim->armorhead, 175);
@@ -3576,7 +3366,7 @@ void Person::DoAnimations()
                             }
                             victim->Puff(abdomen);
                             victim->DoDamage(damagemult * 30 / victim->protectionhigh);
-                            if (creature == wolftype) {
+                            if (PersonType::types[creature].hasClaws) {
                                 emit_sound_at(clawslicesound, victim->coords, 128.);
                                 victim->spurt = 1;
                                 victim->DoBloodBig(2 / victim->armorhigh, 170);
@@ -3585,7 +3375,7 @@ void Person::DoAnimations()
                     }
                 }
 
-                if (animTarget == sweepanim && Animation::animations[animTarget].frames[frameCurrent].label == 5) {
+                if (animCurrent == sweepanim && currentFrame().label == 5) {
                     if ((victim->animTarget != jumpupanim) &&
                         (distsq(&coords, &victim->coords) < (scale * 5) * (scale * 5) * 3) &&
                         (victim != this->shared_from_this())) {
@@ -3647,7 +3437,7 @@ void Person::DoAnimations()
                 }
             }
             if (Animation::animations[animTarget].attack == reversal && (!victim->feint || (victim->lastattack == victim->lastattack2 && victim->lastattack2 == victim->lastattack3 && Random() % 2) || animTarget == knifefollowanim)) {
-                if (animTarget == spinkickreversalanim && Animation::animations[animTarget].frames[frameCurrent].label == 7) {
+                if (animCurrent == spinkickreversalanim && currentFrame().label == 7) {
                     escapednum = 0;
                     if (id == 0) {
                         camerashake += .4;
@@ -3659,7 +3449,7 @@ void Person::DoAnimations()
                     if (!Tutorial::active) {
                         emit_sound_at(heavyimpactsound, victim->coords, 128.);
                     }
-                    if (creature == wolftype) {
+                    if (PersonType::types[creature].hasClaws) {
                         emit_sound_at(clawslicesound, victim->coords, 128);
                         victim->spurt = 1;
                         victim->DoBloodBig(2 / victim->armorhigh, 170);
@@ -3692,7 +3482,7 @@ void Person::DoAnimations()
                     }
                 }
 
-                if (animTarget == staffhitreversalanim && Animation::animations[animTarget].frames[frameCurrent].label == 5) {
+                if (animCurrent == staffhitreversalanim && currentFrame().label == 5) {
                     escapednum = 0;
                     if (id == 0) {
                         camerashake += .4;
@@ -3715,7 +3505,7 @@ void Person::DoAnimations()
                     victim->DoDamage(damagemult * 70 / victim->protectionhigh);
                 }
 
-                if (animTarget == staffspinhitreversalanim && Animation::animations[animTarget].frames[frameCurrent].label == 7) {
+                if (animCurrent == staffspinhitreversalanim && currentFrame().label == 7) {
                     escapednum = 0;
                     if (id == 0) {
                         camerashake += .4;
@@ -3745,7 +3535,7 @@ void Person::DoAnimations()
                     victim->DoDamage(damagemult * 70 / victim->protectionhigh);
                 }
 
-                if (animTarget == upunchreversalanim && Animation::animations[animTarget].frames[frameCurrent].label == 7) {
+                if (animCurrent == upunchreversalanim && currentFrame().label == 7) {
                     escapednum = 0;
                     victim->RagDoll(1);
                     XYZ relative;
@@ -3771,17 +3561,17 @@ void Person::DoAnimations()
                     award_bonus(id, Reversal);
 
                     bool doslice;
-                    doslice = 0;
-                    if (weaponactive != -1 || creature == wolftype) {
-                        doslice = 1;
-                    }
-                    if (creature == rabbittype && weaponactive != -1) {
-                        if (weapons[weaponids[0]].getType() == staff) {
-                            doslice = 0;
-                        }
+                    if (weaponactive == -1) {
+                        doslice = PersonType::types[creature].hasClaws;
+                    } else {
+                        doslice = (weapons[weaponids[0]].getType() != staff);
                     }
                     if (doslice) {
-                        if (weaponactive != -1) {
+                        if (weaponactive == -1) {
+                            emit_sound_at(clawslicesound, victim->coords, 128.);
+                            victim->spurt = 1;
+                            victim->DoBloodBig(2 / victim->armorhigh, 175);
+                        } else {
                             victim->DoBloodBig(2 / victim->armorhigh, 225);
                             emit_sound_at(knifeslicesound, victim->coords);
                             if (bloodtoggle && !weapons[weaponids[weaponactive]].bloody) {
@@ -3789,15 +3579,10 @@ void Person::DoAnimations()
                             }
                             weapons[weaponids[weaponactive]].blooddrip += 3;
                         }
-                        if (weaponactive == -1 && creature == wolftype) {
-                            emit_sound_at(clawslicesound, victim->coords, 128.);
-                            victim->spurt = 1;
-                            victim->DoBloodBig(2 / victim->armorhigh, 175);
-                        }
                     }
                 }
 
-                if (animTarget == swordslashreversalanim && Animation::animations[animTarget].frames[frameCurrent].label == 7) {
+                if (animCurrent == swordslashreversalanim && currentFrame().label == 7) {
                     escapednum = 0;
                     victim->RagDoll(1);
                     XYZ relative;
@@ -3820,7 +3605,7 @@ void Person::DoAnimations()
                     award_bonus(id, swordreversebonus);
                 }
 
-                if (hasvictim && animTarget == knifeslashreversalanim && Animation::animations[animTarget].frames[frameCurrent].label == 7) {
+                if (hasvictim && animCurrent == knifeslashreversalanim && currentFrame().label == 7) {
                     escapednum = 0;
                     if (id == 0) {
                         camerashake += .4;
@@ -3848,7 +3633,7 @@ void Person::DoAnimations()
                     award_bonus(id, Reversal);
                 }
 
-                if (hasvictim && animTarget == sneakattackanim && Animation::animations[animTarget].frames[frameCurrent].label == 7) {
+                if (hasvictim && animCurrent == sneakattackanim && currentFrame().label == 7) {
                     escapednum = 0;
                     victim->RagDoll(0);
                     victim->skeleton.spinny = 0;
@@ -3865,17 +3650,17 @@ void Person::DoAnimations()
                     victim->damage = victim->damagetolerance;
                     victim->permanentdamage = victim->damagetolerance - 1;
                     bool doslice;
-                    doslice = 0;
-                    if (weaponactive != -1 || creature == wolftype) {
-                        doslice = 1;
-                    }
-                    if (creature == rabbittype && weaponactive != -1) {
-                        if (weapons[weaponids[0]].getType() == staff) {
-                            doslice = 0;
-                        }
+                    if (weaponactive == -1) {
+                        doslice = PersonType::types[creature].hasClaws;
+                    } else {
+                        doslice = (weapons[weaponids[0]].getType() != staff);
                     }
                     if (doslice) {
-                        if (weaponactive != -1) {
+                        if (weaponactive == -1) {
+                            emit_sound_at(clawslicesound, victim->coords, 128.);
+                            victim->spurt = 1;
+                            victim->DoBloodBig(2, 175);
+                        } else {
                             victim->DoBloodBig(200, 225);
                             emit_sound_at(knifeslicesound, victim->coords);
                             if (bloodtoggle) {
@@ -3883,17 +3668,11 @@ void Person::DoAnimations()
                             }
                             weapons[weaponids[weaponactive]].blooddrip += 5;
                         }
-
-                        if (creature == wolftype && weaponactive == -1) {
-                            emit_sound_at(clawslicesound, victim->coords, 128.);
-                            victim->spurt = 1;
-                            victim->DoBloodBig(2, 175);
-                        }
                     }
                     award_bonus(id, spinecrusher);
                 }
 
-                if (hasvictim && (animTarget == knifefollowanim || animTarget == knifesneakattackanim) && Animation::animations[animTarget].frames[frameCurrent].label == 5) {
+                if (hasvictim && (animCurrent == knifefollowanim || animCurrent == knifesneakattackanim) && currentFrame().label == 5) {
                     if (weaponactive != -1 && victim->bloodloss < victim->damagetolerance) {
                         escapednum = 0;
                         if (animTarget == knifefollowanim) {
@@ -3938,7 +3717,7 @@ void Person::DoAnimations()
                     }
                 }
 
-                if (hasvictim && (animTarget == knifefollowanim || animTarget == knifesneakattackanim) && Animation::animations[animTarget].frames[frameCurrent].label == 6) {
+                if (hasvictim && (animCurrent == knifefollowanim || animCurrent == knifesneakattackanim) && currentFrame().label == 6) {
                     escapednum = 0;
                     victim->velocity = 0;
                     for (unsigned i = 0; i < victim->skeleton.joints.size(); i++) {
@@ -3971,7 +3750,7 @@ void Person::DoAnimations()
                     }
                 }
 
-                if (hasvictim && (animTarget == swordsneakattackanim) && Animation::animations[animTarget].frames[frameCurrent].label == 5) {
+                if (hasvictim && (animCurrent == swordsneakattackanim) && currentFrame().label == 5) {
                     if (weaponactive != -1 && victim->bloodloss < victim->damagetolerance) {
                         award_bonus(id, backstab);
 
@@ -4000,7 +3779,7 @@ void Person::DoAnimations()
                     }
                 }
 
-                if (hasvictim && animTarget == swordsneakattackanim && Animation::animations[animTarget].frames[frameCurrent].label == 6) {
+                if (hasvictim && animCurrent == swordsneakattackanim && currentFrame().label == 6) {
                     escapednum = 0;
                     victim->velocity = 0;
                     for (unsigned i = 0; i < victim->skeleton.joints.size(); i++) {
@@ -4027,7 +3806,7 @@ void Person::DoAnimations()
                     }
                 }
 
-                if (animTarget == sweepreversalanim && Animation::animations[animTarget].frames[frameCurrent].label == 7) {
+                if (animCurrent == sweepreversalanim && currentFrame().label == 7) {
                     escapednum = 0;
                     if (id == 0) {
                         camerashake += .4;
@@ -4042,17 +3821,17 @@ void Person::DoAnimations()
                         }
                     }
                     bool doslice;
-                    doslice = 0;
-                    if (weaponactive != -1 || creature == wolftype) {
-                        doslice = 1;
-                    }
-                    if (creature == rabbittype && weaponactive != -1) {
-                        if (weapons[weaponids[0]].getType() == staff) {
-                            doslice = 0;
-                        }
+                    if (weaponactive == -1) {
+                        doslice = PersonType::types[creature].hasClaws;
+                    } else {
+                        doslice = (weapons[weaponids[0]].getType() != staff);
                     }
                     if (doslice) {
-                        if (weaponactive != -1) {
+                        if (weaponactive == -1) {
+                            emit_sound_at(clawslicesound, victim->coords, 128.);
+                            victim->spurt = 1;
+                            victim->DoBloodBig(2 / victim->armorhead, 175);
+                        } else {
                             victim->DoBloodBig(2 / victim->armorhead, 225);
                             emit_sound_at(knifeslicesound, victim->coords);
                             if (bloodtoggle && !weapons[weaponids[weaponactive]].bloody) {
@@ -4060,11 +3839,6 @@ void Person::DoAnimations()
                             }
                             weapons[weaponids[weaponactive]].blooddrip += 3;
                         }
-                        if (weaponactive == -1 && creature == wolftype) {
-                            emit_sound_at(clawslicesound, victim->coords, 128.);
-                            victim->spurt = 1;
-                            victim->DoBloodBig(2 / victim->armorhead, 175);
-                        }
                     }
 
                     award_bonus(id, Reversal);
@@ -4089,7 +3863,7 @@ void Person::DoAnimations()
                     victim->velocity = 0;
                 }
 
-                if (animTarget == sweepreversalanim && ((Animation::animations[animTarget].frames[frameCurrent].label == 9 && victim->damage < victim->damagetolerance) || (Animation::animations[animTarget].frames[frameCurrent].label == 7 && victim->damage > victim->damagetolerance))) {
+                if (animCurrent == sweepreversalanim && ((currentFrame().label == 9 && victim->damage < victim->damagetolerance) || (currentFrame().label == 7 && victim->damage > victim->damagetolerance))) {
                     escapednum = 0;
                     victim->RagDoll(0);
                     XYZ relative;
@@ -4113,7 +3887,7 @@ void Person::DoAnimations()
             }
 
             //Animation end
-            if (frameTarget > int(Animation::animations[animCurrent].frames.size()) - 1) {
+            if (frameTarget >= int(Animation::animations[animCurrent].frames.size())) {
                 frameTarget = 0;
                 if (wasStop()) {
                     animTarget = getIdle();
@@ -4586,6 +4360,11 @@ void Person::DoAnimations()
                 frameCurrent = frameTarget;
                 target = 1;
             }
+
+            if (frameCurrent >= int(Animation::animations[animCurrent].frames.size())) {
+                frameCurrent = Animation::animations[animCurrent].frames.size() - 1;
+            }
+
             oldrot = rot;
             rot = targetrot * target;
             yaw += rot - oldrot;
@@ -4594,9 +4373,7 @@ void Person::DoAnimations()
                 oldrot = 0;
                 targetrot = 0;
             }
-            if (frameCurrent >= int(Animation::animations[animCurrent].frames.size())) {
-                frameCurrent = Animation::animations[animCurrent].frames.size() - 1;
-            }
+
             if (animCurrent != oldanimCurrent || animTarget != oldanimTarget || ((frameCurrent != oldframeCurrent || frameTarget != oldframeTarget) && !calcrot)) {
                 //Old rotates
                 for (unsigned i = 0; i < skeleton.joints.size(); i++) {
@@ -5926,21 +5703,8 @@ void Person::DoStuff()
             int whichsound = -1;
             if (speechdelay <= 0) {
                 unsigned int i = abs(Random() % 4);
-                if (creature == rabbittype) {
-                    if (i == 0) {
-                        whichsound = rabbitchitter;
-                    }
-                    if (i == 1) {
-                        whichsound = rabbitchitter2;
-                    }
-                }
-                if (creature == wolftype) {
-                    if (i == 0) {
-                        whichsound = growlsound;
-                    }
-                    if (i == 1) {
-                        whichsound = growl2sound;
-                    }
+                if (i < 2) {
+                    whichsound = PersonType::types[creature].soundsTalk[i];
                 }
             }
             speechdelay = .3;
@@ -6729,24 +6493,24 @@ int Person::DrawSkeleton()
                             glMatrixMode(GL_MODELVIEW);
                             glPushMatrix();
                             if (p1 == abdomen || p2 == abdomen) {
-                                glTranslatef((v0.x * (1 - morphness) + v1.x * morphness) * getProportion(1).x,
-                                             (v0.y * (1 - morphness) + v1.y * morphness) * getProportion(1).y,
-                                             (v0.z * (1 - morphness) + v1.z * morphness) * getProportion(1).z);
+                                glTranslatef((v0.x * (1 - morphness) + v1.x * morphness) * getProportionXYZ(1).x,
+                                             (v0.y * (1 - morphness) + v1.y * morphness) * getProportionXYZ(1).y,
+                                             (v0.z * (1 - morphness) + v1.z * morphness) * getProportionXYZ(1).z);
                             }
                             if (p1 == lefthand || p1 == righthand || p1 == leftwrist || p1 == rightwrist || p1 == leftelbow || p1 == rightelbow || p2 == leftelbow || p2 == rightelbow) {
-                                glTranslatef((v0.x * (1 - morphness) + v1.x * morphness) * getProportion(2).x,
-                                             (v0.y * (1 - morphness) + v1.y * morphness) * getProportion(2).y,
-                                             (v0.z * (1 - morphness) + v1.z * morphness) * getProportion(2).z);
+                                glTranslatef((v0.x * (1 - morphness) + v1.x * morphness) * getProportionXYZ(2).x,
+                                             (v0.y * (1 - morphness) + v1.y * morphness) * getProportionXYZ(2).y,
+                                             (v0.z * (1 - morphness) + v1.z * morphness) * getProportionXYZ(2).z);
                             }
                             if (p1 == leftfoot || p1 == rightfoot || p1 == leftankle || p1 == rightankle || p1 == leftknee || p1 == rightknee || p2 == leftknee || p2 == rightknee) {
-                                glTranslatef((v0.x * (1 - morphness) + v1.x * morphness) * getProportion(3).x,
-                                             (v0.y * (1 - morphness) + v1.y * morphness) * getProportion(3).y,
-                                             (v0.z * (1 - morphness) + v1.z * morphness) * getProportion(3).z);
+                                glTranslatef((v0.x * (1 - morphness) + v1.x * morphness) * getProportionXYZ(3).x,
+                                             (v0.y * (1 - morphness) + v1.y * morphness) * getProportionXYZ(3).y,
+                                             (v0.z * (1 - morphness) + v1.z * morphness) * getProportionXYZ(3).z);
                             }
                             if (p1 == head || p2 == head) {
-                                glTranslatef((v0.x * (1 - morphness) + v1.x * morphness) * getProportion(0).x,
-                                             (v0.y * (1 - morphness) + v1.y * morphness) * getProportion(0).y,
-                                             (v0.z * (1 - morphness) + v1.z * morphness) * getProportion(0).z);
+                                glTranslatef((v0.x * (1 - morphness) + v1.x * morphness) * getProportionXYZ(0).x,
+                                             (v0.y * (1 - morphness) + v1.y * morphness) * getProportionXYZ(0).y,
+                                             (v0.z * (1 - morphness) + v1.z * morphness) * getProportionXYZ(0).z);
                             }
                             glGetFloatv(GL_MODELVIEW_MATRIX, M);
                             skeleton.drawmodel.vertex[skeleton.muscles[i].vertices[j]].x = M[12] * scale;
@@ -6761,24 +6525,24 @@ int Person::DrawSkeleton()
                             glMatrixMode(GL_MODELVIEW);
                             glPushMatrix();
                             if (p1 == abdomen || p2 == abdomen) {
-                                glTranslatef(v0.x * getProportion(1).x,
-                                             v0.y * getProportion(1).y,
-                                             v0.z * getProportion(1).z);
+                                glTranslatef(v0.x * getProportionXYZ(1).x,
+                                             v0.y * getProportionXYZ(1).y,
+                                             v0.z * getProportionXYZ(1).z);
                             }
                             if (p1 == lefthand || p1 == righthand || p1 == leftwrist || p1 == rightwrist || p1 == leftelbow || p1 == rightelbow || p2 == leftelbow || p2 == rightelbow) {
-                                glTranslatef(v0.x * getProportion(2).x,
-                                             v0.y * getProportion(2).y,
-                                             v0.z * getProportion(2).z);
+                                glTranslatef(v0.x * getProportionXYZ(2).x,
+                                             v0.y * getProportionXYZ(2).y,
+                                             v0.z * getProportionXYZ(2).z);
                             }
                             if (p1 == leftfoot || p1 == rightfoot || p1 == leftankle || p1 == rightankle || p1 == leftknee || p1 == rightknee || p2 == leftknee || p2 == rightknee) {
-                                glTranslatef(v0.x * getProportion(3).x,
-                                             v0.y * getProportion(3).y,
-                                             v0.z * getProportion(3).z);
+                                glTranslatef(v0.x * getProportionXYZ(3).x,
+                                             v0.y * getProportionXYZ(3).y,
+                                             v0.z * getProportionXYZ(3).z);
                             }
                             if (p1 == head || p2 == head) {
-                                glTranslatef(v0.x * getProportion(0).x,
-                                             v0.y * getProportion(0).y,
-                                             v0.z * getProportion(0).z);
+                                glTranslatef(v0.x * getProportionXYZ(0).x,
+                                             v0.y * getProportionXYZ(0).y,
+                                             v0.z * getProportionXYZ(0).z);
                             }
 
                             glGetFloatv(GL_MODELVIEW_MATRIX, M);
@@ -6817,24 +6581,24 @@ int Person::DrawSkeleton()
                         glMatrixMode(GL_MODELVIEW);
                         glPushMatrix();
                         if (p1 == abdomen || p2 == abdomen) {
-                            glTranslatef(v0.x * getProportion(1).x,
-                                         v0.y * getProportion(1).y,
-                                         v0.z * getProportion(1).z);
+                            glTranslatef(v0.x * getProportionXYZ(1).x,
+                                         v0.y * getProportionXYZ(1).y,
+                                         v0.z * getProportionXYZ(1).z);
                         }
                         if (p1 == lefthand || p1 == righthand || p1 == leftwrist || p1 == rightwrist || p1 == leftelbow || p1 == rightelbow || p2 == leftelbow || p2 == rightelbow) {
-                            glTranslatef(v0.x * getProportion(2).x,
-                                         v0.y * getProportion(2).y,
-                                         v0.z * getProportion(2).z);
+                            glTranslatef(v0.x * getProportionXYZ(2).x,
+                                         v0.y * getProportionXYZ(2).y,
+                                         v0.z * getProportionXYZ(2).z);
                         }
                         if (p1 == leftfoot || p1 == rightfoot || p1 == leftankle || p1 == rightankle || p1 == leftknee || p1 == rightknee || p2 == leftknee || p2 == rightknee) {
-                            glTranslatef(v0.x * getProportion(3).x,
-                                         v0.y * getProportion(3).y,
-                                         v0.z * getProportion(3).z);
+                            glTranslatef(v0.x * getProportionXYZ(3).x,
+                                         v0.y * getProportionXYZ(3).y,
+                                         v0.z * getProportionXYZ(3).z);
                         }
                         if (p1 == head || p2 == head) {
-                            glTranslatef(v0.x * getProportion(0).x,
-                                         v0.y * getProportion(0).y,
-                                         v0.z * getProportion(0).z);
+                            glTranslatef(v0.x * getProportionXYZ(0).x,
+                                         v0.y * getProportionXYZ(0).y,
+                                         v0.z * getProportionXYZ(0).z);
                         }
                         glGetFloatv(GL_MODELVIEW_MATRIX, M);
                         skeleton.drawmodelclothes.vertex[skeleton.muscles[i].verticesclothes[j]].x = M[12] * scale;