]> git.jsancho.org Git - lugaru.git/blobdiff - Source/Objects/Person.cpp
Use victim to attack, not player 0
[lugaru.git] / Source / Objects / Person.cpp
index d0e8f083742ffd22baf8a5b7b864382d29f0af66..5a735c3a0cf5d50ff66f9ab4bb843171449b3a73 100644 (file)
@@ -169,6 +169,7 @@ Person::Person()
 
     victim(nullptr)
     , hasvictim(false)
+    , isplayerfriend(false)
     ,
 
     updatedelay(0)
@@ -7332,9 +7333,9 @@ void Person::doAI()
         }
 
         pause = 0;
-        if (distsqflat(&Person::players[0]->coords, &coords) < 30 &&
-            Person::players[0]->coords.y > coords.y + 2 &&
-            !Person::players[0]->onterrain) {
+        if (distsqflat(&victim->coords, &coords) < 30 &&
+            victim->coords.y > coords.y + 2 &&
+            !victim->onterrain) {
             pause = 1;
         }
 
@@ -7487,17 +7488,18 @@ void Person::doAI()
 
             if ((!Tutorial::active || cananger) &&
                 hostile &&
-                !Person::players[0]->dead &&
-                distsq(&coords, &Person::players[0]->coords) < 400 &&
+                !isPlayerFriend() &&
+                !victim->dead &&
+                distsq(&coords, &victim->coords) < 400 &&
                 occluded < 25) {
-                if (distsq(&coords, &Person::players[0]->coords) < 12 &&
-                    Animation::animations[Person::players[0]->animTarget].height != lowheight &&
+                if (distsq(&coords, &victim->coords) < 12 &&
+                    Animation::animations[victim->animTarget].height != lowheight &&
                     !Game::editorenabled &&
-                    (Person::players[0]->coords.y < coords.y + 5 || Person::players[0]->onterrain)) {
+                    (victim->coords.y < coords.y + 5 || victim->onterrain)) {
                     aitype = attacktypecutoff;
                 }
-                if (distsq(&coords, &Person::players[0]->coords) < 30 &&
-                    Animation::animations[Person::players[0]->animTarget].height == highheight &&
+                if (distsq(&coords, &victim->coords) < 30 &&
+                    Animation::animations[victim->animTarget].height == highheight &&
                     !Game::editorenabled) {
                     aitype = attacktypecutoff;
                 }
@@ -7604,7 +7606,7 @@ void Person::doAI()
             //hearing sounds
             if (!Game::editorenabled) {
                 if (howactive <= typesleeping) {
-                    if (numenvsounds > 0 && (!Tutorial::active || cananger) && hostile) {
+                  if (numenvsounds > 0 && (!Tutorial::active || cananger) && !isPlayerFriend() && hostile) {
                         for (int j = 0; j < numenvsounds; j++) {
                             float vol = howactive == typesleeping ? envsoundvol[j] - 14 : envsoundvol[j];
                             if (vol > 0 && distsq(&coords, &envsound[j]) < 2 * (vol + vol * (creature == rabbittype) * 3)) {
@@ -7624,15 +7626,16 @@ void Person::doAI()
 
             if (howactive < typesleeping &&
                 ((!Tutorial::active || cananger) && hostile) &&
-                !Person::players[0]->dead &&
-                distsq(&coords, &Person::players[0]->coords) < 400 &&
+                !isPlayerFriend() &&
+                !victim->dead &&
+                distsq(&coords, &victim->coords) < 400 &&
                 occluded < 25) {
-                if (distsq(&coords, &Person::players[0]->coords) < 12 &&
-                    Animation::animations[Person::players[0]->animTarget].height != lowheight && !Game::editorenabled) {
+                if (distsq(&coords, &victim->coords) < 12 &&
+                    Animation::animations[victim->animTarget].height != lowheight && !Game::editorenabled) {
                     aitype = attacktypecutoff;
                 }
-                if (distsq(&coords, &Person::players[0]->coords) < 30 &&
-                    Animation::animations[Person::players[0]->animTarget].height == highheight && !Game::editorenabled) {
+                if (distsq(&coords, &victim->coords) < 30 &&
+                    Animation::animations[victim->animTarget].height == highheight && !Game::editorenabled) {
                     aitype = attacktypecutoff;
                 }
 
@@ -7802,7 +7805,7 @@ void Person::doAI()
                 jumpkeydown = 1;
             }
 
-            if (numenvsounds > 0 && ((!Tutorial::active || cananger) && hostile)) {
+            if (numenvsounds > 0 && ((!Tutorial::active || cananger) && !isPlayerFriend() && hostile)) {
                 for (int k = 0; k < numenvsounds; k++) {
                     if (distsq(&coords, &envsound[k]) < 2 * (envsoundvol[k] + envsoundvol[k] * (creature == rabbittype) * 3)) {
                         aitype = attacktypecutoff;
@@ -7810,28 +7813,29 @@ void Person::doAI()
                 }
             }
 
-            if (!Person::players[0]->dead &&
+            if (!victim->dead &&
+                !isPlayerFriend() &&
                 losupdatedelay < 0 &&
                 !Game::editorenabled &&
                 occluded < 2 &&
                 ((!Tutorial::active || cananger) && hostile)) {
                 losupdatedelay = .2;
-                if (distsq(&coords, &Person::players[0]->coords) < 4 && Animation::animations[animTarget].height != lowheight) {
+                if (distsq(&coords, &victim->coords) < 4 && Animation::animations[animTarget].height != lowheight) {
                     aitype = attacktypecutoff;
                     lastseentime = 1;
                 }
                 if (abs(Random() % 2) || Animation::animations[animTarget].height != lowheight) {
                     //TODO: factor out canSeePlayer()
-                    if (distsq(&coords, &Person::players[0]->coords) < 400) {
-                        if (normaldotproduct(facing, Person::players[0]->coords - coords) > 0) {
+                    if (distsq(&coords, &victim->coords) < 400) {
+                        if (normaldotproduct(facing, victim->coords - coords) > 0) {
                             if ((Object::checkcollide(
                                      DoRotation(jointPos(head), 0, yaw, 0) *
                                              scale +
                                          coords,
-                                     DoRotation(Person::players[0]->jointPos(head), 0, Person::players[0]->yaw, 0) *
-                                             Person::players[0]->scale +
-                                         Person::players[0]->coords) == -1) ||
-                                (Person::players[0]->animTarget == hanganim && normaldotproduct(Person::players[0]->facing, coords - Person::players[0]->coords) < 0)) {
+                                     DoRotation(victim->jointPos(head), 0, victim->yaw, 0) *
+                                             victim->scale +
+                                         victim->coords) == -1) ||
+                                (victim->animTarget == hanganim && normaldotproduct(victim->facing, coords - victim->coords) < 0)) {
                                 /* //TODO: changed j to 0 on a whim, make sure this is correct
                                 (Person::players[j]->animTarget==hanganim&&normaldotproduct(
                                     Person::players[j]->facing,coords-Person::players[j]->coords)<0)
@@ -7892,7 +7896,7 @@ void Person::doAI()
                     } else {
                         ally = 0;
                     }
-                    lastseen = Person::players[0]->coords;
+                    lastseen = victim->coords;
                     lastseentime = 12;
                 }
 
@@ -7996,13 +8000,13 @@ void Person::doAI()
 
                 lastseentime = 12;
 
-                if (!Person::players[0]->dead && ((!Tutorial::active || cananger) && hostile)) {
+                if (!victim->dead && !isPlayerFriend() && ((!Tutorial::active || cananger) && hostile)) {
                     if (ally < 0 || hasWeapon() || lastchecktime <= 0) {
                         aitype = attacktypecutoff;
                         lastseentime = 1;
                     }
                 }
-                if (!Person::players[0]->dead) {
+                if (!victim->dead) {
                     if (ally >= 0) {
                         if (weapons[ally].owner != -1 ||
                             distsq(&coords, &weapons[ally].position) > 16) {
@@ -8059,18 +8063,18 @@ void Person::doAI()
             aiupdatedelay -= multiplier;
             //dodge or reverse rabbit kicks, knife throws, flips
             if (damage < damagetolerance * 2 / 3) {
-                if ((Person::players[0]->animTarget == rabbitkickanim ||
-                     Person::players[0]->animTarget == knifethrowanim ||
-                     (Person::players[0]->isFlip() &&
-                      normaldotproduct(Person::players[0]->facing, Person::players[0]->coords - coords) < 0)) &&
-                    !Person::players[0]->skeleton.free &&
+                if ((victim->animTarget == rabbitkickanim ||
+                     victim->animTarget == knifethrowanim ||
+                     (victim->isFlip() &&
+                      normaldotproduct(victim->facing, victim->coords - coords) < 0)) &&
+                    !victim->skeleton.free &&
                     (aiupdatedelay < .1)) {
                     attackkeydown = 0;
                     if (isIdle()) {
                         crouchkeydown = 1;
                     }
-                    if (Person::players[0]->animTarget != rabbitkickanim && Person::players[0]->hasWeapon()) {
-                        if (weapons[Person::players[0]->weaponids[0]].getType() == knife) {
+                    if (victim->animTarget != rabbitkickanim && victim->hasWeapon()) {
+                        if (weapons[victim->weaponids[0]].getType() == knife) {
                             if (isIdle() || isCrouch() || isRun() || isFlip()) {
                                 if (abs(Random() % 2) == 0) {
                                     setTargetAnimation(backhandspringanim);
@@ -8090,11 +8094,11 @@ void Person::doAI()
                 }
             }
             //get confused by flips
-            if (Person::players[0]->isFlip() &&
-                !Person::players[0]->skeleton.free &&
-                Person::players[0]->animTarget != walljumprightkickanim &&
-                Person::players[0]->animTarget != walljumpleftkickanim) {
-                if (distsq(&Person::players[0]->coords, &coords) < 25) {
+            if (victim->isFlip() &&
+                !victim->skeleton.free &&
+                victim->animTarget != walljumprightkickanim &&
+                victim->animTarget != walljumpleftkickanim) {
+                if (distsq(&victim->coords, &coords) < 25) {
                     if ((1 - damage / damagetolerance) > .5) {
                         stunned = 1;
                     }
@@ -8123,8 +8127,8 @@ void Person::doAI()
             if (damage < damagetolerance / 2) {
                 if (Animation::animations[animTarget].height != highheight) {
                     if (damage < damagetolerance * .5 &&
-                        ((Person::players[0]->animTarget == walljumprightkickanim ||
-                          Person::players[0]->animTarget == walljumpleftkickanim) &&
+                        ((victim->animTarget == walljumprightkickanim ||
+                          victim->animTarget == walljumpleftkickanim) &&
                          ((aiupdatedelay < .15 &&
                            difficulty == 2) ||
                           (aiupdatedelay < .08 &&
@@ -8163,9 +8167,9 @@ void Person::doAI()
                 }
             }
             //lose sight of player in the air (?)
-            if (Person::players[0]->coords.y > coords.y + 5 &&
-                Animation::animations[Person::players[0]->animTarget].height != highheight &&
-                !Person::players[0]->onterrain) {
+            if (victim->coords.y > coords.y + 5 &&
+                Animation::animations[victim->animTarget].height != highheight &&
+                !victim->onterrain) {
                 aitype = pathfindtype;
                 finalfinaltarget = waypoints[waypoint];
                 finalpathfindpoint = -1;
@@ -8190,23 +8194,23 @@ void Person::doAI()
                 }
                 rabbitkickenabled = Random() % 2;
                 //chase player
-                XYZ rotatetarget = Person::players[0]->coords + Person::players[0]->velocity;
-                XYZ targetpoint = Person::players[0]->coords;
+                XYZ rotatetarget = victim->coords + victim->velocity;
+                XYZ targetpoint = victim->coords;
                 float vellength = findLength(&velocity);
                 if (vellength != 0 &&
-                    distsq(&Person::players[0]->coords, &coords) < distsq(&rotatetarget, &coords)) {
-                    targetpoint += Person::players[0]->velocity *
-                                   findDistance(&Person::players[0]->coords, &coords) / vellength;
+                    distsq(&victim->coords, &coords) < distsq(&rotatetarget, &coords)) {
+                    targetpoint += victim->velocity *
+                                   findDistance(&victim->coords, &coords) / vellength;
                 }
                 targetyaw = roughDirectionTo(coords, targetpoint);
                 lookyaw = targetyaw;
                 aiupdatedelay = .2 + fabs((float)(Random() % 100) / 1000);
 
-                if (distsq(&coords, &Person::players[0]->coords) > 5 && (!Person::players[0]->hasWeapon() || hasWeapon())) {
+                if (distsq(&coords, &victim->coords) > 5 && (!victim->hasWeapon() || hasWeapon())) {
                     forwardkeydown = 1;
-                } else if ((distsq(&coords, &Person::players[0]->coords) > 16 ||
-                            distsq(&coords, &Person::players[0]->coords) < 9) &&
-                           Person::players[0]->hasWeapon()) {
+                } else if ((distsq(&coords, &victim->coords) > 16 ||
+                            distsq(&coords, &victim->coords) < 9) &&
+                           victim->hasWeapon()) {
                     forwardkeydown = 1;
                 } else if (Random() % 6 == 0 || (creature == wolftype && Random() % 3 == 0)) {
                     forwardkeydown = 1;
@@ -8214,7 +8218,7 @@ void Person::doAI()
                     forwardkeydown = 0;
                 }
                 //chill out around the corpse
-                if (Person::players[0]->dead) {
+                if (victim->dead) {
                     forwardkeydown = 0;
                     if (Random() % 10 == 0) {
                         forwardkeydown = 1;
@@ -8245,7 +8249,7 @@ void Person::doAI()
                 } else {
                     attackkeydown = 0;
                 }
-                if (isRun() && Random() % 6 && distsq(&coords, &Person::players[0]->coords) > 7) {
+                if (isRun() && Random() % 6 && distsq(&coords, &victim->coords) > 7) {
                     attackkeydown = 0;
                 }
 
@@ -8301,17 +8305,17 @@ void Person::doAI()
                     jumpkeydown = 0;
                 }
                 if (collided > .8 && jumppower >= 5 ||
-                    distsq(&coords, &Person::players[0]->coords) > 400 &&
+                    distsq(&coords, &victim->coords) > 400 &&
                         onterrain &&
                         creature == rabbittype) {
                     jumpkeydown = 1;
                 }
                 //TODO: why are we controlling the human?
-                if (normaldotproduct(facing, Person::players[0]->coords - coords) > 0) {
-                    Person::players[0]->jumpkeydown = 0;
+                if (normaldotproduct(facing, victim->coords - coords) > 0) {
+                    victim->jumpkeydown = 0;
                 }
-                if (Person::players[0]->animTarget == jumpdownanim &&
-                    distsq(&Person::players[0]->coords, &coords) < 40) {
+                if (victim->animTarget == jumpdownanim &&
+                    distsq(&victim->coords, &coords) < 40) {
                     crouchkeydown = 1;
                 }
                 if (jumpkeydown) {
@@ -8325,9 +8329,9 @@ void Person::doAI()
                 }
 
                 XYZ facing = coords;
-                XYZ flatfacing = Person::players[0]->coords;
+                XYZ flatfacing = victim->coords;
                 facing.y += jointPos(head).y * scale;
-                flatfacing.y += Person::players[0]->jointPos(head).y * Person::players[0]->scale;
+                flatfacing.y += victim->jointPos(head).y * victim->scale;
                 if (occluded >= 2) {
                     if (-1 != Object::checkcollide(facing, flatfacing)) {
                         if (!pause) {
@@ -8338,7 +8342,7 @@ void Person::doAI()
                              weaponstuck == -1)) {
                             aitype = searchtype;
                             lastchecktime = 12;
-                            lastseen = Person::players[0]->coords;
+                            lastseen = victim->coords;
                             lastseentime = 12;
                         }
                     } else {
@@ -8347,17 +8351,18 @@ void Person::doAI()
                 }
             }
         }
-        if (Animation::animations[Person::players[0]->animTarget].height == highheight &&
+        if (Animation::animations[victim->animTarget].height == highheight &&
             (aitype == attacktypecutoff ||
              aitype == searchtype)) {
-            if (Person::players[0]->coords.y > terrain.getHeight(Person::players[0]->coords.x, Person::players[0]->coords.z) + 10) {
-                XYZ test = Person::players[0]->coords;
+            if (victim->coords.y > terrain.getHeight(victim->coords.x, victim->coords.z) + 10) {
+                XYZ test = victim->coords;
                 test.y -= 40;
-                if (-1 == Object::checkcollide(Person::players[0]->coords, test)) {
+                if (-1 == Object::checkcollide(victim->coords, test)) {
                     stunned = 1;
                 }
             }
         }
+
         //stunned
         if (aitype == passivetype && !(numwaypoints > 1) ||
             stunned > 0 ||
@@ -8376,6 +8381,32 @@ void Person::doAI()
             throwkeydown = 0;
         }
 
+        if (stunned < 1 && isPlayerFriend()) {
+            // friends follow player
+            if (!Person::players[0]->dead &&
+                distsq(&coords, &Person::players[0]->coords) > 5) {
+                XYZ rotatetarget = Person::players[0]->coords + Person::players[0]->velocity;
+                XYZ targetpoint = Person::players[0]->coords;
+                velocity = (targetpoint - coords);
+                velocity.y += 2;
+                float vellength = findLength(&velocity);
+                if (vellength != 0 &&
+                    distsq(&Person::players[0]->coords, &coords) < distsq(&rotatetarget, &coords)) {
+                    targetpoint += Person::players[0]->velocity *
+                                   findDistance(&Person::players[0]->coords, &coords) / vellength;
+                }
+                targetyaw = roughDirectionTo(coords, targetpoint);
+                lookyaw = targetyaw;
+                forwardkeydown = 1;
+                aitype = pathfindtype;
+            }
+
+            // friends help player with its enemies
+            if (Game::musictype == stream_fighttheme) {
+              aitype = attacktypecutoff;
+            }
+        }
+
         XYZ facing;
         facing = 0;
         facing.z = -1;
@@ -8389,6 +8420,9 @@ void Person::doAI()
         } else if (howactive >= typesleeping) {
             targetheadyaw = targetyaw;
             targetheadpitch = 0;
+        } else if (isPlayerFriend()) {
+            targetheadyaw = 180 - roughDirectionTo(coords, Person::players[0]->coords);
+            targetheadpitch = pitchTo(coords, Person::players[0]->coords);
         } else {
             if (interestdelay <= 0) {
                 interestdelay = .7 + (float)(abs(Random() % 100)) / 100;