From: Côme Chilliet Date: Mon, 19 Dec 2016 22:03:27 +0000 (+0100) Subject: Moved doAI in Person class X-Git-Url: https://git.jsancho.org/?a=commitdiff_plain;h=635516adc7915de50d38cd01345871a07a24c390;p=lugaru.git Moved doAI in Person class Had to change weapons[i] for weapons[k) which might change behavior, test needed. (but weapons[i] is bogus anyway, i was a person id) --- diff --git a/Source/GameTick.cpp b/Source/GameTick.cpp index a400c22..f4b9a7c 100644 --- a/Source/GameTick.cpp +++ b/Source/GameTick.cpp @@ -369,51 +369,6 @@ void Game::SetUpLighting() light.ambient[2] *= (skyboxlightb + average) / 2; } -int findPathDist(int start, int end) -{ - int smallestcount, count, connected; - int last, last2, last3, last4; - int closest; - - smallestcount = 1000; - for (int i = 0; i < 50; i++) { - count = 0; - last = start; - last2 = -1; - last3 = -1; - last4 = -1; - while (last != end && count < 30) { - closest = -1; - for (int j = 0; j < numpathpoints; j++) { - if (j != last && j != last2 && j != last3 && j != last4) { - connected = 0; - if (numpathpointconnect[j]) - for (int k = 0; k < numpathpointconnect[j]; k++) { - if (pathpointconnect[j][k] == last)connected = 1; - } - if (!connected) - if (numpathpointconnect[last]) - for (int k = 0; k < numpathpointconnect[last]; k++) { - if (pathpointconnect[last][k] == j)connected = 1; - } - if (connected) - if (closest == -1 || Random() % 2 == 0) { - closest = j; - } - } - } - last4 = last3; - last3 = last2; - last2 = last; - last = closest; - count++; - } - if (count < smallestcount) - smallestcount = count; - } - return smallestcount; -} - void Setenvironment(int which) { LOGFUNC; @@ -2856,985 +2811,6 @@ void doPlayerCollisions() } } -void doAI(unsigned i) -{ - static bool connected; - if (Person::players[i]->aitype != playercontrolled && !Dialog::inDialog()) { - Person::players[i]->jumpclimb = 0; - //disable movement in editor - if (editorenabled) - Person::players[i]->stunned = 1; - - Person::players[i]->pause = 0; - if (distsqflat(&Person::players[0]->coords, &Person::players[i]->coords) < 30 && - Person::players[0]->coords.y > Person::players[i]->coords.y + 2 && - !Person::players[0]->onterrain) - Person::players[i]->pause = 1; - - //pathfinding - if (Person::players[i]->aitype == pathfindtype) { - if (Person::players[i]->finalpathfindpoint == -1) { - float closestdistance; - float tempdist; - int closest; - XYZ colpoint; - closest = -1; - closestdistance = -1; - for (int j = 0; j < numpathpoints; j++) { - if (closest == -1 || distsq(&Person::players[i]->finalfinaltarget, &pathpoint[j]) < closestdistance) { - closestdistance = distsq(&Person::players[i]->finalfinaltarget, &pathpoint[j]); - closest = j; - Person::players[i]->finaltarget = pathpoint[j]; - } - } - Person::players[i]->finalpathfindpoint = closest; - for (int j = 0; j < numpathpoints; j++) { - for (int k = 0; k < numpathpointconnect[j]; k++) { - DistancePointLine(&Person::players[i]->finalfinaltarget, &pathpoint[j], &pathpoint[pathpointconnect[j][k]], &tempdist, &colpoint); - if (sq(tempdist) < closestdistance) - if (findDistance(&colpoint, &pathpoint[j]) + findDistance(&colpoint, &pathpoint[pathpointconnect[j][k]]) < - findDistance(&pathpoint[j], &pathpoint[pathpointconnect[j][k]]) + .1) { - closestdistance = sq(tempdist); - closest = j; - Person::players[i]->finaltarget = colpoint; - } - } - } - Person::players[i]->finalpathfindpoint = closest; - - } - if (Person::players[i]->targetpathfindpoint == -1) { - float closestdistance; - float tempdist; - int closest; - XYZ colpoint; - closest = -1; - closestdistance = -1; - if (Person::players[i]->lastpathfindpoint == -1) { - for (int j = 0; j < numpathpoints; j++) { - if (j != Person::players[i]->lastpathfindpoint) - if (closest == -1 || (distsq(&Person::players[i]->coords, &pathpoint[j]) < closestdistance)) { - closestdistance = distsq(&Person::players[i]->coords, &pathpoint[j]); - closest = j; - } - } - Person::players[i]->targetpathfindpoint = closest; - for (int j = 0; j < numpathpoints; j++) - if (j != Person::players[i]->lastpathfindpoint) - for (int k = 0; k < numpathpointconnect[j]; k++) { - DistancePointLine(&Person::players[i]->coords, &pathpoint[j], &pathpoint[pathpointconnect[j][k]], &tempdist, &colpoint ); - if (sq(tempdist) < closestdistance) { - if (findDistance(&colpoint, &pathpoint[j]) + findDistance(&colpoint, &pathpoint[pathpointconnect[j][k]]) < - findDistance(&pathpoint[j], &pathpoint[pathpointconnect[j][k]]) + .1) { - closestdistance = sq(tempdist); - closest = j; - } - } - } - Person::players[i]->targetpathfindpoint = closest; - } else { - for (int j = 0; j < numpathpoints; j++) - if (j != Person::players[i]->lastpathfindpoint && - j != Person::players[i]->lastpathfindpoint2 && - j != Person::players[i]->lastpathfindpoint3 && - j != Person::players[i]->lastpathfindpoint4) { - connected = 0; - if (numpathpointconnect[j]) - for (int k = 0; k < numpathpointconnect[j]; k++) - if (pathpointconnect[j][k] == Person::players[i]->lastpathfindpoint) - connected = 1; - if (!connected) - if (numpathpointconnect[Person::players[i]->lastpathfindpoint]) - for (int k = 0; k < numpathpointconnect[Person::players[i]->lastpathfindpoint]; k++) - if (pathpointconnect[Person::players[i]->lastpathfindpoint][k] == j) - connected = 1; - if (connected) { - tempdist = findPathDist(j, Person::players[i]->finalpathfindpoint); - if (closest == -1 || tempdist < closestdistance) { - closestdistance = tempdist; - closest = j; - } - } - } - Person::players[i]->targetpathfindpoint = closest; - } - } - Person::players[i]->losupdatedelay -= multiplier; - - Person::players[i]->targetyaw = roughDirectionTo(Person::players[i]->coords, pathpoint[Person::players[i]->targetpathfindpoint]); - Person::players[i]->lookyaw = Person::players[i]->targetyaw; - - //reached target point - if (distsqflat(&Person::players[i]->coords, &pathpoint[Person::players[i]->targetpathfindpoint]) < .6) { - Person::players[i]->lastpathfindpoint4 = Person::players[i]->lastpathfindpoint3; - Person::players[i]->lastpathfindpoint3 = Person::players[i]->lastpathfindpoint2; - Person::players[i]->lastpathfindpoint2 = Person::players[i]->lastpathfindpoint; - Person::players[i]->lastpathfindpoint = Person::players[i]->targetpathfindpoint; - if (Person::players[i]->lastpathfindpoint2 == -1) - Person::players[i]->lastpathfindpoint2 = Person::players[i]->lastpathfindpoint; - if (Person::players[i]->lastpathfindpoint3 == -1) - Person::players[i]->lastpathfindpoint3 = Person::players[i]->lastpathfindpoint2; - if (Person::players[i]->lastpathfindpoint4 == -1) - Person::players[i]->lastpathfindpoint4 = Person::players[i]->lastpathfindpoint3; - Person::players[i]->targetpathfindpoint = -1; - } - if ( distsqflat(&Person::players[i]->coords, &Person::players[i]->finalfinaltarget) < - distsqflat(&Person::players[i]->coords, &Person::players[i]->finaltarget) || - distsqflat(&Person::players[i]->coords, &Person::players[i]->finaltarget) < .6 * sq(Person::players[i]->scale * 5) || - Person::players[i]->lastpathfindpoint == Person::players[i]->finalpathfindpoint) { - Person::players[i]->aitype = passivetype; - } - - Person::players[i]->forwardkeydown = 1; - Person::players[i]->leftkeydown = 0; - Person::players[i]->backkeydown = 0; - Person::players[i]->rightkeydown = 0; - Person::players[i]->crouchkeydown = 0; - Person::players[i]->attackkeydown = 0; - Person::players[i]->throwkeydown = 0; - - if (Person::players[i]->avoidcollided > .8 && !Person::players[i]->jumpkeydown && Person::players[i]->collided < .8) - Person::players[i]->targetyaw += 90 * (Person::players[i]->whichdirection * 2 - 1); - - if (Person::players[i]->collided < 1 || Person::players[i]->animTarget != jumpupanim) - Person::players[i]->jumpkeydown = 0; - if ((Person::players[i]->collided > .8 && Person::players[i]->jumppower >= 5)) - Person::players[i]->jumpkeydown = 1; - - if ((!Tutorial::active || cananger) && - hostile && - !Person::players[0]->dead && - distsq(&Person::players[i]->coords, &Person::players[0]->coords) < 400 && - Person::players[i]->occluded < 25) { - if (distsq(&Person::players[i]->coords, &Person::players[0]->coords) < 12 && - Animation::animations[Person::players[0]->animTarget].height != lowheight && - !editorenabled && - (Person::players[0]->coords.y < Person::players[i]->coords.y + 5 || Person::players[0]->onterrain)) - Person::players[i]->aitype = attacktypecutoff; - if (distsq(&Person::players[i]->coords, &Person::players[0]->coords) < 30 && - Animation::animations[Person::players[0]->animTarget].height == highheight && - !editorenabled) - Person::players[i]->aitype = attacktypecutoff; - - if (Person::players[i]->losupdatedelay < 0 && !editorenabled && Person::players[i]->occluded < 2) { - Person::players[i]->losupdatedelay = .2; - for (unsigned j = 0; j < Person::players.size(); j++) - if (j == 0 || Person::players[j]->skeleton.free || Person::players[j]->aitype != passivetype) - if (abs(Random() % 2) || Animation::animations[Person::players[j]->animTarget].height != lowheight || j != 0) - if (distsq(&Person::players[i]->coords, &Person::players[j]->coords) < 400) - if (normaldotproduct(Person::players[i]->facing, Person::players[j]->coords - Person::players[i]->coords) > 0) - if (Person::players[j]->coords.y < Person::players[i]->coords.y + 5 || Person::players[j]->onterrain) - if (!Person::players[j]->isWallJump() && -1 == Object::checkcollide( - DoRotation(Person::players[i]->jointPos(head), 0, Person::players[i]->yaw, 0) - *Person::players[i]->scale + Person::players[i]->coords, - DoRotation(Person::players[j]->jointPos(head), 0, Person::players[j]->yaw, 0) - *Person::players[j]->scale + Person::players[j]->coords) || - (Person::players[j]->animTarget == hanganim && - normaldotproduct(Person::players[j]->facing, Person::players[i]->coords - Person::players[j]->coords) < 0)) { - Person::players[i]->aitype = searchtype; - Person::players[i]->lastchecktime = 12; - Person::players[i]->lastseen = Person::players[j]->coords; - Person::players[i]->lastseentime = 12; - } - } - } - if (Person::players[i]->aitype == attacktypecutoff && musictype != 2) - if (Person::players[i]->creature != wolftype) { - Person::players[i]->stunned = .6; - Person::players[i]->surprised = .6; - } - } - - if (Person::players[i]->aitype != passivetype && leveltime > .5) - Person::players[i]->howactive = typeactive; - - if (Person::players[i]->aitype == passivetype) { - Person::players[i]->aiupdatedelay -= multiplier; - Person::players[i]->losupdatedelay -= multiplier; - Person::players[i]->lastseentime += multiplier; - Person::players[i]->pausetime -= multiplier; - if (Person::players[i]->lastseentime > 1) - Person::players[i]->lastseentime = 1; - - if (Person::players[i]->aiupdatedelay < 0) { - if (Person::players[i]->numwaypoints > 1 && Person::players[i]->howactive == typeactive && Person::players[i]->pausetime <= 0) { - Person::players[i]->targetyaw = roughDirectionTo(Person::players[i]->coords, Person::players[i]->waypoints[Person::players[i]->waypoint]); - Person::players[i]->lookyaw = Person::players[i]->targetyaw; - Person::players[i]->aiupdatedelay = .05; - - if (distsqflat(&Person::players[i]->coords, &Person::players[i]->waypoints[Person::players[i]->waypoint]) < 1) { - if (Person::players[i]->waypointtype[Person::players[i]->waypoint] == wppause) - Person::players[i]->pausetime = 4; - Person::players[i]->waypoint++; - if (Person::players[i]->waypoint > Person::players[i]->numwaypoints - 1) - Person::players[i]->waypoint = 0; - - } - } - - if (Person::players[i]->numwaypoints > 1 && Person::players[i]->howactive == typeactive && Person::players[i]->pausetime <= 0) - Person::players[i]->forwardkeydown = 1; - else - Person::players[i]->forwardkeydown = 0; - Person::players[i]->leftkeydown = 0; - Person::players[i]->backkeydown = 0; - Person::players[i]->rightkeydown = 0; - Person::players[i]->crouchkeydown = 0; - Person::players[i]->attackkeydown = 0; - Person::players[i]->throwkeydown = 0; - - if (Person::players[i]->avoidcollided > .8 && !Person::players[i]->jumpkeydown && Person::players[i]->collided < .8) { - if (!Person::players[i]->avoidsomething) - Person::players[i]->targetyaw += 90 * (Person::players[i]->whichdirection * 2 - 1); - else { - XYZ leftpos, rightpos; - float leftdist, rightdist; - leftpos = Person::players[i]->coords + DoRotation(Person::players[i]->facing, 0, 90, 0); - rightpos = Person::players[i]->coords - DoRotation(Person::players[i]->facing, 0, 90, 0); - leftdist = distsq(&leftpos, &Person::players[i]->avoidwhere); - rightdist = distsq(&rightpos, &Person::players[i]->avoidwhere); - if (leftdist < rightdist) - Person::players[i]->targetyaw += 90; - else - Person::players[i]->targetyaw -= 90; - } - } - } - if (Person::players[i]->collided < 1 || Person::players[i]->animTarget != jumpupanim) - Person::players[i]->jumpkeydown = 0; - if ((Person::players[i]->collided > .8 && Person::players[i]->jumppower >= 5)) - Person::players[i]->jumpkeydown = 1; - - - //hearing sounds - if (!editorenabled) { - if (Person::players[i]->howactive <= typesleeping) - if (numenvsounds > 0 && (!Tutorial::active || cananger) && hostile) - for (int j = 0; j < numenvsounds; j++) { - float vol = Person::players[i]->howactive == typesleeping ? envsoundvol[j] - 14 : envsoundvol[j]; - if (vol > 0 && distsq(&Person::players[i]->coords, &envsound[j]) < - 2 * (vol + vol * (Person::players[i]->creature == rabbittype) * 3)) - Person::players[i]->aitype = attacktypecutoff; - } - - if (Person::players[i]->aitype != passivetype) { - if (Person::players[i]->howactive == typesleeping) - Person::players[i]->setAnimation(getupfromfrontanim); - Person::players[i]->howactive = typeactive; - } - } - - if (Person::players[i]->howactive < typesleeping && - ((!Tutorial::active || cananger) && hostile) && - !Person::players[0]->dead && - distsq(&Person::players[i]->coords, &Person::players[0]->coords) < 400 && - Person::players[i]->occluded < 25) { - if (distsq(&Person::players[i]->coords, &Person::players[0]->coords) < 12 && - Animation::animations[Person::players[0]->animTarget].height != lowheight && !editorenabled) - Person::players[i]->aitype = attacktypecutoff; - if (distsq(&Person::players[i]->coords, &Person::players[0]->coords) < 30 && - Animation::animations[Person::players[0]->animTarget].height == highheight && !editorenabled) - Person::players[i]->aitype = attacktypecutoff; - - //wolf smell - if (Person::players[i]->creature == wolftype) { - XYZ windsmell; - for (unsigned j = 0; j < Person::players.size(); j++) { - if (j == 0 || (Person::players[j]->dead && Person::players[j]->bloodloss > 0)) { - float smelldistance = 50; - if (j == 0 && Person::players[j]->num_weapons > 0) { - if (weapons[Person::players[j]->weaponids[0]].bloody) - smelldistance = 100; - if (Person::players[j]->num_weapons == 2) - if (weapons[Person::players[j]->weaponids[1]].bloody) - smelldistance = 100; - } - if (j != 0) - smelldistance = 100; - windsmell = windvector; - Normalise(&windsmell); - windsmell = windsmell * 2 + Person::players[j]->coords; - if (distsq(&Person::players[i]->coords, &windsmell) < smelldistance && !editorenabled) - Person::players[i]->aitype = attacktypecutoff; - } - } - } - - if (Person::players[i]->howactive < typesleeping && Person::players[i]->losupdatedelay < 0 && !editorenabled && Person::players[i]->occluded < 2) { - Person::players[i]->losupdatedelay = .2; - for (unsigned j = 0; j < Person::players.size(); j++) { - if (j == 0 || Person::players[j]->skeleton.free || Person::players[j]->aitype != passivetype) { - if (abs(Random() % 2) || Animation::animations[Person::players[j]->animTarget].height != lowheight || j != 0) - if (distsq(&Person::players[i]->coords, &Person::players[j]->coords) < 400) - if (normaldotproduct(Person::players[i]->facing, Person::players[j]->coords - Person::players[i]->coords) > 0) - if ((-1 == Object::checkcollide( - DoRotation(Person::players[i]->jointPos(head), 0, Person::players[i]->yaw, 0)* - Person::players[i]->scale + Person::players[i]->coords, - DoRotation(Person::players[j]->jointPos(head), 0, Person::players[j]->yaw, 0)* - Person::players[j]->scale + Person::players[j]->coords) && - !Person::players[j]->isWallJump()) || - (Person::players[j]->animTarget == hanganim && - normaldotproduct(Person::players[j]->facing, Person::players[i]->coords - Person::players[j]->coords) < 0)) { - Person::players[i]->lastseentime -= .2; - if (j == 0 && Animation::animations[Person::players[j]->animTarget].height == lowheight) - Person::players[i]->lastseentime -= .4; - else - Person::players[i]->lastseentime -= .6; - } - if (Person::players[i]->lastseentime <= 0) { - Person::players[i]->aitype = searchtype; - Person::players[i]->lastchecktime = 12; - Person::players[i]->lastseen = Person::players[j]->coords; - Person::players[i]->lastseentime = 12; - } - } - } - } - } - //alerted surprise - if (Person::players[i]->aitype == attacktypecutoff && musictype != 2) { - if (Person::players[i]->creature != wolftype) { - Person::players[i]->stunned = .6; - Person::players[i]->surprised = .6; - } - if (Person::players[i]->creature == wolftype) { - Person::players[i]->stunned = .47; - Person::players[i]->surprised = .47; - } - numseen++; - } - } - - //search for player - int j; - if (Person::players[i]->aitype == searchtype) { - Person::players[i]->aiupdatedelay -= multiplier; - Person::players[i]->losupdatedelay -= multiplier; - if (!Person::players[i]->pause) - Person::players[i]->lastseentime -= multiplier; - Person::players[i]->lastchecktime -= multiplier; - - if (Person::players[i]->isRun() && !Person::players[i]->onground) { - if (Person::players[i]->coords.y > terrain.getHeight(Person::players[i]->coords.x, Person::players[i]->coords.z) + 10) { - XYZ test2 = Person::players[i]->coords + Person::players[i]->facing; - test2.y += 5; - XYZ test = Person::players[i]->coords + Person::players[i]->facing; - test.y -= 10; - j = Object::checkcollide(test2, test, Person::players[i]->laststanding); - if (j == -1) - j = Object::checkcollide(test2, test); - if (j == -1) { - Person::players[i]->velocity = 0; - Person::players[i]->setAnimation(Person::players[i]->getStop()); - Person::players[i]->targetyaw += 180; - Person::players[i]->stunned = .5; - //Person::players[i]->aitype=passivetype; - Person::players[i]->aitype = pathfindtype; - Person::players[i]->finalfinaltarget = Person::players[i]->waypoints[Person::players[i]->waypoint]; - Person::players[i]->finalpathfindpoint = -1; - Person::players[i]->targetpathfindpoint = -1; - Person::players[i]->lastpathfindpoint = -1; - Person::players[i]->lastpathfindpoint2 = -1; - Person::players[i]->lastpathfindpoint3 = -1; - Person::players[i]->lastpathfindpoint4 = -1; - } else - Person::players[i]->laststanding = j; - } - } - //check out last seen location - if (Person::players[i]->aiupdatedelay < 0) { - Person::players[i]->targetyaw = roughDirectionTo(Person::players[i]->coords, Person::players[i]->lastseen); - Person::players[i]->lookyaw = Person::players[i]->targetyaw; - Person::players[i]->aiupdatedelay = .05; - Person::players[i]->forwardkeydown = 1; - - if (distsqflat(&Person::players[i]->coords, &Person::players[i]->lastseen) < 1 * sq(Person::players[i]->scale * 5) || Person::players[i]->lastchecktime < 0) { - Person::players[i]->forwardkeydown = 0; - Person::players[i]->aiupdatedelay = 1; - Person::players[i]->lastseen.x += (float(Random() % 100) - 50) / 25; - Person::players[i]->lastseen.z += (float(Random() % 100) - 50) / 25; - Person::players[i]->lastchecktime = 3; - } - - Person::players[i]->leftkeydown = 0; - Person::players[i]->backkeydown = 0; - Person::players[i]->rightkeydown = 0; - Person::players[i]->crouchkeydown = 0; - Person::players[i]->attackkeydown = 0; - Person::players[i]->throwkeydown = 0; - - if (Person::players[i]->avoidcollided > .8 && !Person::players[i]->jumpkeydown && Person::players[i]->collided < .8) { - if (!Person::players[i]->avoidsomething) - Person::players[i]->targetyaw += 90 * (Person::players[i]->whichdirection * 2 - 1); - else { - XYZ leftpos, rightpos; - float leftdist, rightdist; - leftpos = Person::players[i]->coords + DoRotation(Person::players[i]->facing, 0, 90, 0); - rightpos = Person::players[i]->coords - DoRotation(Person::players[i]->facing, 0, 90, 0); - leftdist = distsq(&leftpos, &Person::players[i]->avoidwhere); - rightdist = distsq(&rightpos, &Person::players[i]->avoidwhere); - if (leftdist < rightdist) - Person::players[i]->targetyaw += 90; - else - Person::players[i]->targetyaw -= 90; - } - } - } - if (Person::players[i]->collided < 1 || Person::players[i]->animTarget != jumpupanim) - Person::players[i]->jumpkeydown = 0; - if ((Person::players[i]->collided > .8 && Person::players[i]->jumppower >= 5)) - Person::players[i]->jumpkeydown = 1; - - if (numenvsounds > 0 && ((!Tutorial::active || cananger) && hostile)) - for (int k = 0; k < numenvsounds; k++) { - if (distsq(&Person::players[i]->coords, &envsound[k]) < 2 * (envsoundvol[k] + envsoundvol[k] * (Person::players[i]->creature == rabbittype) * 3)) { - Person::players[i]->aitype = attacktypecutoff; - } - } - - if (!Person::players[0]->dead && - Person::players[i]->losupdatedelay < 0 && - !editorenabled && - Person::players[i]->occluded < 2 && - ((!Tutorial::active || cananger) && hostile)) { - Person::players[i]->losupdatedelay = .2; - if (distsq(&Person::players[i]->coords, &Person::players[0]->coords) < 4 && Animation::animations[Person::players[i]->animTarget].height != lowheight) { - Person::players[i]->aitype = attacktypecutoff; - Person::players[i]->lastseentime = 1; - } - if (abs(Random() % 2) || Animation::animations[Person::players[i]->animTarget].height != lowheight) - //TODO: factor out canSeePlayer() - if (distsq(&Person::players[i]->coords, &Person::players[0]->coords) < 400) - if (normaldotproduct(Person::players[i]->facing, Person::players[0]->coords - Person::players[i]->coords) > 0) - if ((Object::checkcollide( - DoRotation(Person::players[i]->jointPos(head), 0, Person::players[i]->yaw, 0)* - Person::players[i]->scale + Person::players[i]->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, Person::players[i]->coords - Person::players[0]->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,Person::players[i]->coords-Person::players[j]->coords)<0) - */ - Person::players[i]->aitype = attacktypecutoff; - Person::players[i]->lastseentime = 1; - } - } - //player escaped - if (Person::players[i]->lastseentime < 0) { - //Person::players[i]->aitype=passivetype; - numescaped++; - Person::players[i]->aitype = pathfindtype; - Person::players[i]->finalfinaltarget = Person::players[i]->waypoints[Person::players[i]->waypoint]; - Person::players[i]->finalpathfindpoint = -1; - Person::players[i]->targetpathfindpoint = -1; - Person::players[i]->lastpathfindpoint = -1; - Person::players[i]->lastpathfindpoint2 = -1; - Person::players[i]->lastpathfindpoint3 = -1; - Person::players[i]->lastpathfindpoint4 = -1; - } - } - - if (Person::players[i]->aitype != gethelptype) - Person::players[i]->runninghowlong = 0; - - //get help from buddies - if (Person::players[i]->aitype == gethelptype) { - Person::players[i]->runninghowlong += multiplier; - Person::players[i]->aiupdatedelay -= multiplier; - - if (Person::players[i]->aiupdatedelay < 0 || Person::players[i]->ally == 0) { - Person::players[i]->aiupdatedelay = .2; - - //find closest ally - //TODO: factor out closest search somehow - if (!Person::players[i]->ally) { - int closest = -1; - float closestdist = -1; - for (unsigned k = 0; k < Person::players.size(); k++) { - if (k != i && k != 0 && !Person::players[k]->dead && - Person::players[k]->howactive < typedead1 && - !Person::players[k]->skeleton.free && - Person::players[k]->aitype == passivetype) { - float distance = distsq(&Person::players[i]->coords, &Person::players[k]->coords); - if (closestdist == -1 || distance < closestdist) { - closestdist = distance; - closest = k; - } - closest = k; - } - } - if (closest != -1) - Person::players[i]->ally = closest; - else - Person::players[i]->ally = 0; - Person::players[i]->lastseen = Person::players[0]->coords; - Person::players[i]->lastseentime = 12; - } - - - Person::players[i]->lastchecktime = 12; - - XYZ facing = Person::players[i]->coords; - XYZ flatfacing = Person::players[Person::players[i]->ally]->coords; - facing.y += Person::players[i]->jointPos(head).y * Person::players[i]->scale; - flatfacing.y += Person::players[Person::players[i]->ally]->jointPos(head).y * Person::players[Person::players[i]->ally]->scale; - if (-1 != Object::checkcollide(facing, flatfacing)) - Person::players[i]->lastseentime -= .1; - - //no available ally, run back to player - if (Person::players[i]->ally <= 0 || - Person::players[Person::players[i]->ally]->skeleton.free || - Person::players[Person::players[i]->ally]->aitype != passivetype || - Person::players[i]->lastseentime <= 0) { - Person::players[i]->aitype = searchtype; - Person::players[i]->lastseentime = 12; - } - - //seek out ally - if (Person::players[i]->ally > 0) { - Person::players[i]->targetyaw = roughDirectionTo(Person::players[i]->coords, Person::players[Person::players[i]->ally]->coords); - Person::players[i]->lookyaw = Person::players[i]->targetyaw; - Person::players[i]->aiupdatedelay = .05; - Person::players[i]->forwardkeydown = 1; - - if (distsqflat(&Person::players[i]->coords, &Person::players[Person::players[i]->ally]->coords) < 3) { - Person::players[i]->aitype = searchtype; - Person::players[i]->lastseentime = 12; - Person::players[Person::players[i]->ally]->aitype = searchtype; - if (Person::players[Person::players[i]->ally]->lastseentime < Person::players[i]->lastseentime) { - Person::players[Person::players[i]->ally]->lastseen = Person::players[i]->lastseen; - Person::players[Person::players[i]->ally]->lastseentime = Person::players[i]->lastseentime; - Person::players[Person::players[i]->ally]->lastchecktime = Person::players[i]->lastchecktime; - } - } - - if (Person::players[i]->avoidcollided > .8 && !Person::players[i]->jumpkeydown && Person::players[i]->collided < .8) { - if (!Person::players[i]->avoidsomething) - Person::players[i]->targetyaw += 90 * (Person::players[i]->whichdirection * 2 - 1); - else { - XYZ leftpos, rightpos; - float leftdist, rightdist; - leftpos = Person::players[i]->coords + DoRotation(Person::players[i]->facing, 0, 90, 0); - rightpos = Person::players[i]->coords - DoRotation(Person::players[i]->facing, 0, 90, 0); - leftdist = distsq(&leftpos, &Person::players[i]->avoidwhere); - rightdist = distsq(&rightpos, &Person::players[i]->avoidwhere); - if (leftdist < rightdist) - Person::players[i]->targetyaw += 90; - else - Person::players[i]->targetyaw -= 90; - } - } - } - - Person::players[i]->leftkeydown = 0; - Person::players[i]->backkeydown = 0; - Person::players[i]->rightkeydown = 0; - Person::players[i]->crouchkeydown = 0; - Person::players[i]->attackkeydown = 0; - } - if (Person::players[i]->collided < 1 || Person::players[i]->animTarget != jumpupanim) - Person::players[i]->jumpkeydown = 0; - if (Person::players[i]->collided > .8 && Person::players[i]->jumppower >= 5) - Person::players[i]->jumpkeydown = 1; - } - - //retreiving a weapon on the ground - if (Person::players[i]->aitype == getweapontype) { - Person::players[i]->aiupdatedelay -= multiplier; - Person::players[i]->lastchecktime -= multiplier; - - if (Person::players[i]->aiupdatedelay < 0) { - Person::players[i]->aiupdatedelay = .2; - - //ALLY IS WEPON - if (Person::players[i]->ally < 0) { - int closest = -1; - float closestdist = -1; - for (unsigned k = 0; k < weapons.size(); k++) - if (weapons[k].owner == -1) { - float distance = distsq(&Person::players[i]->coords, &weapons[k].position); - if (closestdist == -1 || distance < closestdist) { - closestdist = distance; - closest = k; - } - closest = k; - } - if (closest != -1) - Person::players[i]->ally = closest; - else - Person::players[i]->ally = -1; - } - - Person::players[i]->lastseentime = 12; - - if (!Person::players[0]->dead && ((!Tutorial::active || cananger) && hostile)) - if (Person::players[i]->ally < 0 || Person::players[i]->weaponactive != -1 || Person::players[i]->lastchecktime <= 0) { - Person::players[i]->aitype = attacktypecutoff; - Person::players[i]->lastseentime = 1; - } - if (!Person::players[0]->dead) - if (Person::players[i]->ally >= 0) { - if (weapons[Person::players[i]->ally].owner != -1 || - distsq(&Person::players[i]->coords, &weapons[Person::players[i]->ally].position) > 16) { - Person::players[i]->aitype = attacktypecutoff; - Person::players[i]->lastseentime = 1; - } - //TODO: factor these out as moveToward() - Person::players[i]->targetyaw = roughDirectionTo(Person::players[i]->coords, weapons[Person::players[i]->ally].position); - Person::players[i]->lookyaw = Person::players[i]->targetyaw; - Person::players[i]->aiupdatedelay = .05; - Person::players[i]->forwardkeydown = 1; - - - if (Person::players[i]->avoidcollided > .8 && !Person::players[i]->jumpkeydown && Person::players[i]->collided < .8) { - if (!Person::players[i]->avoidsomething) - Person::players[i]->targetyaw += 90 * (Person::players[i]->whichdirection * 2 - 1); - else { - XYZ leftpos, rightpos; - float leftdist, rightdist; - leftpos = Person::players[i]->coords + DoRotation(Person::players[i]->facing, 0, 90, 0); - rightpos = Person::players[i]->coords - DoRotation(Person::players[i]->facing, 0, 90, 0); - leftdist = distsq(&leftpos, &Person::players[i]->avoidwhere); - rightdist = distsq(&rightpos, &Person::players[i]->avoidwhere); - if (leftdist < rightdist) - Person::players[i]->targetyaw += 90; - else - Person::players[i]->targetyaw -= 90; - } - } - } - - Person::players[i]->leftkeydown = 0; - Person::players[i]->backkeydown = 0; - Person::players[i]->rightkeydown = 0; - Person::players[i]->attackkeydown = 0; - Person::players[i]->throwkeydown = 1; - Person::players[i]->crouchkeydown = 0; - if (Person::players[i]->animTarget != crouchremoveknifeanim && - Person::players[i]->animTarget != removeknifeanim) - Person::players[i]->throwtogglekeydown = 0; - Person::players[i]->drawkeydown = 0; - } - if (Person::players[i]->collided < 1 || Person::players[i]->animTarget != jumpupanim) - Person::players[i]->jumpkeydown = 0; - if ((Person::players[i]->collided > .8 && Person::players[i]->jumppower >= 5)) - Person::players[i]->jumpkeydown = 1; - } - - if (Person::players[i]->aitype == attacktypecutoff) { - Person::players[i]->aiupdatedelay -= multiplier; - //dodge or reverse rabbit kicks, knife throws, flips - if (Person::players[i]->damage < Person::players[i]->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 - Person::players[i]->coords) < 0)) && - !Person::players[0]->skeleton.free && - (Person::players[i]->aiupdatedelay < .1)) { - Person::players[i]->attackkeydown = 0; - if (Person::players[i]->isIdle()) - Person::players[i]->crouchkeydown = 1; - if (Person::players[0]->animTarget != rabbitkickanim && Person::players[0]->weaponactive != -1) { - if (weapons[Person::players[0]->weaponids[0]].getType() == knife) { - if (Person::players[i]->isIdle() || Person::players[i]->isCrouch() || Person::players[i]->isRun() || Person::players[i]->isFlip()) { - if (abs(Random() % 2) == 0) - Person::players[i]->setAnimation(backhandspringanim); - else - Person::players[i]->setAnimation(rollanim); - Person::players[i]->targetyaw += 90 * (abs(Random() % 2) * 2 - 1); - Person::players[i]->wentforweapon = 0; - } - if (Person::players[i]->animTarget == jumpupanim || Person::players[i]->animTarget == jumpdownanim) - Person::players[i]->setAnimation(flipanim); - } - } - Person::players[i]->forwardkeydown = 0; - Person::players[i]->aiupdatedelay = .02; - } - //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, &Person::players[i]->coords) < 25) - if ((1 - Person::players[i]->damage / Person::players[i]->damagetolerance) > .5) - Person::players[i]->stunned = 1; - } - //go for weapon on the ground - if (Person::players[i]->wentforweapon < 3) - for (unsigned k = 0; k < weapons.size(); k++) - if (Person::players[i]->creature != wolftype) - if (Person::players[i]->num_weapons == 0 && - weapons[k].owner == -1 && - weapons[i].velocity.x == 0 && - weapons[i].velocity.z == 0 && - weapons[i].velocity.y == 0) { - if (distsq(&Person::players[i]->coords, &weapons[k].position) < 16) { - Person::players[i]->wentforweapon++; - Person::players[i]->lastchecktime = 6; - Person::players[i]->aitype = getweapontype; - Person::players[i]->ally = -1; - } - } - //dodge/reverse walljump kicks - if (Person::players[i]->damage < Person::players[i]->damagetolerance / 2) - if (Animation::animations[Person::players[i]->animTarget].height != highheight) - if (Person::players[i]->damage < Person::players[i]->damagetolerance * .5 && - ((Person::players[0]->animTarget == walljumprightkickanim || - Person::players[0]->animTarget == walljumpleftkickanim) && - ((Person::players[i]->aiupdatedelay < .15 && - difficulty == 2) || - (Person::players[i]->aiupdatedelay < .08 && - difficulty != 2)))) { - Person::players[i]->crouchkeydown = 1; - } - //walked off a ledge (?) - if (Person::players[i]->isRun() && !Person::players[i]->onground) - if (Person::players[i]->coords.y > terrain.getHeight(Person::players[i]->coords.x, Person::players[i]->coords.z) + 10) { - XYZ test2 = Person::players[i]->coords + Person::players[i]->facing; - test2.y += 5; - XYZ test = Person::players[i]->coords + Person::players[i]->facing; - test.y -= 10; - j = Object::checkcollide(test2, test, Person::players[i]->laststanding); - if (j == -1) - j = Object::checkcollide(test2, test); - if (j == -1) { - Person::players[i]->velocity = 0; - Person::players[i]->setAnimation(Person::players[i]->getStop()); - Person::players[i]->targetyaw += 180; - Person::players[i]->stunned = .5; - Person::players[i]->aitype = pathfindtype; - Person::players[i]->finalfinaltarget = Person::players[i]->waypoints[Person::players[i]->waypoint]; - Person::players[i]->finalpathfindpoint = -1; - Person::players[i]->targetpathfindpoint = -1; - Person::players[i]->lastpathfindpoint = -1; - Person::players[i]->lastpathfindpoint2 = -1; - Person::players[i]->lastpathfindpoint3 = -1; - Person::players[i]->lastpathfindpoint4 = -1; - } else - Person::players[i]->laststanding = j; - } - //lose sight of player in the air (?) - if (Person::players[0]->coords.y > Person::players[i]->coords.y + 5 && - Animation::animations[Person::players[0]->animTarget].height != highheight && - !Person::players[0]->onterrain) { - Person::players[i]->aitype = pathfindtype; - Person::players[i]->finalfinaltarget = Person::players[i]->waypoints[Person::players[i]->waypoint]; - Person::players[i]->finalpathfindpoint = -1; - Person::players[i]->targetpathfindpoint = -1; - Person::players[i]->lastpathfindpoint = -1; - Person::players[i]->lastpathfindpoint2 = -1; - Person::players[i]->lastpathfindpoint3 = -1; - Person::players[i]->lastpathfindpoint4 = -1; - } - //it's time to think (?) - if (Person::players[i]->aiupdatedelay < 0 && - !Animation::animations[Person::players[i]->animTarget].attack && - Person::players[i]->animTarget != staggerbackhighanim && - Person::players[i]->animTarget != staggerbackhardanim && - Person::players[i]->animTarget != backhandspringanim && - Person::players[i]->animTarget != dodgebackanim) { - //draw weapon - if (Person::players[i]->weaponactive == -1 && Person::players[i]->num_weapons > 0) - Person::players[i]->drawkeydown = Random() % 2; - else - Person::players[i]->drawkeydown = 0; - Person::players[i]->rabbitkickenabled = Random() % 2; - //chase player - XYZ rotatetarget = Person::players[0]->coords + Person::players[0]->velocity; - XYZ targetpoint = Person::players[0]->coords; - if (distsq(&Person::players[0]->coords, &Person::players[i]->coords) < - distsq(&rotatetarget, &Person::players[i]->coords)) - targetpoint += Person::players[0]->velocity * - findDistance(&Person::players[0]->coords, &Person::players[i]->coords) / findLength(&Person::players[i]->velocity); - Person::players[i]->targetyaw = roughDirectionTo(Person::players[i]->coords, targetpoint); - Person::players[i]->lookyaw = Person::players[i]->targetyaw; - Person::players[i]->aiupdatedelay = .2 + fabs((float)(Random() % 100) / 1000); - - if (distsq(&Person::players[i]->coords, &Person::players[0]->coords) > 5 && (Person::players[0]->weaponactive == -1 || Person::players[i]->weaponactive != -1)) - Person::players[i]->forwardkeydown = 1; - else if ((distsq(&Person::players[i]->coords, &Person::players[0]->coords) > 16 || - distsq(&Person::players[i]->coords, &Person::players[0]->coords) < 9) && - Person::players[0]->weaponactive != -1) - Person::players[i]->forwardkeydown = 1; - else if (Random() % 6 == 0 || (Person::players[i]->creature == wolftype && Random() % 3 == 0)) - Person::players[i]->forwardkeydown = 1; - else - Person::players[i]->forwardkeydown = 0; - //chill out around the corpse - if (Person::players[0]->dead) { - Person::players[i]->forwardkeydown = 0; - if (Random() % 10 == 0) - Person::players[i]->forwardkeydown = 1; - if (Random() % 100 == 0) { - Person::players[i]->aitype = pathfindtype; - Person::players[i]->finalfinaltarget = Person::players[i]->waypoints[Person::players[i]->waypoint]; - Person::players[i]->finalpathfindpoint = -1; - Person::players[i]->targetpathfindpoint = -1; - Person::players[i]->lastpathfindpoint = -1; - Person::players[i]->lastpathfindpoint2 = -1; - Person::players[i]->lastpathfindpoint3 = -1; - Person::players[i]->lastpathfindpoint4 = -1; - } - } - Person::players[i]->leftkeydown = 0; - Person::players[i]->backkeydown = 0; - Person::players[i]->rightkeydown = 0; - Person::players[i]->crouchkeydown = 0; - Person::players[i]->throwkeydown = 0; - - if (Person::players[i]->avoidcollided > .8 && !Person::players[i]->jumpkeydown && Person::players[i]->collided < .8) - Person::players[i]->targetyaw += 90 * (Person::players[i]->whichdirection * 2 - 1); - //attack!!! - if (Random() % 2 == 0 || Person::players[i]->weaponactive != -1 || Person::players[i]->creature == wolftype) - Person::players[i]->attackkeydown = 1; - else - Person::players[i]->attackkeydown = 0; - if (Person::players[i]->isRun() && Random() % 6 && distsq(&Person::players[i]->coords, &Person::players[0]->coords) > 7) - Person::players[i]->attackkeydown = 0; - - //TODO: wat - if (Person::players[i]->aitype != playercontrolled && - (Person::players[i]->isIdle() || - Person::players[i]->isCrouch() || - Person::players[i]->isRun())) { - int target = -2; - for (unsigned j = 0; j < Person::players.size(); j++) - if (j != i && !Person::players[j]->skeleton.free && - Person::players[j]->hasvictim && - (Tutorial::active && reversaltrain || - Random() % 2 == 0 && difficulty == 2 || - Random() % 4 == 0 && difficulty == 1 || - Random() % 8 == 0 && difficulty == 0 || - Person::players[j]->lastattack2 == Person::players[j]->animTarget && - Person::players[j]->lastattack3 == Person::players[j]->animTarget && - (Random() % 2 == 0 || difficulty == 2) || - (Person::players[i]->isIdle() || Person::players[i]->isRun()) && - Person::players[j]->weaponactive != -1 || - Person::players[j]->animTarget == swordslashanim && - Person::players[i]->weaponactive != -1 || - Person::players[j]->animTarget == staffhitanim || - Person::players[j]->animTarget == staffspinhitanim)) - if (distsq(&Person::players[j]->coords, &Person::players[j]->victim->coords) < 4 && - Person::players[j]->victim == Person::players[i] && - (Person::players[j]->animTarget == sweepanim || - Person::players[j]->animTarget == spinkickanim || - Person::players[j]->animTarget == staffhitanim || - Person::players[j]->animTarget == staffspinhitanim || - Person::players[j]->animTarget == winduppunchanim || - Person::players[j]->animTarget == upunchanim || - Person::players[j]->animTarget == wolfslapanim || - Person::players[j]->animTarget == knifeslashstartanim || - Person::players[j]->animTarget == swordslashanim && - (distsq(&Person::players[j]->coords, &Person::players[i]->coords) < 2 || - Person::players[i]->weaponactive != -1))) { - if (target >= 0) - target = -1; - else - target = j; - } - if (target >= 0) - Person::players[target]->Reverse(); - } - - if (Person::players[i]->collided < 1) - Person::players[i]->jumpkeydown = 0; - if (Person::players[i]->collided > .8 && Person::players[i]->jumppower >= 5 || - distsq(&Person::players[i]->coords, &Person::players[0]->coords) > 400 && - Person::players[i]->onterrain && - Person::players[i]->creature == rabbittype) - Person::players[i]->jumpkeydown = 1; - //TODO: why are we controlling the human? - if (normaldotproduct(Person::players[i]->facing, Person::players[0]->coords - Person::players[i]->coords) > 0) - Person::players[0]->jumpkeydown = 0; - if (Person::players[0]->animTarget == jumpdownanim && - distsq(&Person::players[0]->coords, &Person::players[i]->coords) < 40) - Person::players[i]->crouchkeydown = 1; - if (Person::players[i]->jumpkeydown) - Person::players[i]->attackkeydown = 0; - - if (Tutorial::active) - if (!canattack) - Person::players[i]->attackkeydown = 0; - - - XYZ facing = Person::players[i]->coords; - XYZ flatfacing = Person::players[0]->coords; - facing.y += Person::players[i]->jointPos(head).y * Person::players[i]->scale; - flatfacing.y += Person::players[0]->jointPos(head).y * Person::players[0]->scale; - if (Person::players[i]->occluded >= 2) - if (-1 != Object::checkcollide(facing, flatfacing)) { - if (!Person::players[i]->pause) - Person::players[i]->lastseentime -= .2; - if (Person::players[i]->lastseentime <= 0 && - (Person::players[i]->creature != wolftype || - Person::players[i]->weaponstuck == -1)) { - Person::players[i]->aitype = searchtype; - Person::players[i]->lastchecktime = 12; - Person::players[i]->lastseen = Person::players[0]->coords; - Person::players[i]->lastseentime = 12; - } - } else - Person::players[i]->lastseentime = 1; - } - } - if (Animation::animations[Person::players[0]->animTarget].height == highheight && - (Person::players[i]->aitype == attacktypecutoff || - Person::players[i]->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; - test.y -= 40; - if (-1 == Object::checkcollide(Person::players[0]->coords, test)) - Person::players[i]->stunned = 1; - } - //stunned - if (Person::players[i]->aitype == passivetype && !(Person::players[i]->numwaypoints > 1) || - Person::players[i]->stunned > 0 || - Person::players[i]->pause && Person::players[i]->damage > Person::players[i]->superpermanentdamage) { - if (Person::players[i]->pause) - Person::players[i]->lastseentime = 1; - Person::players[i]->targetyaw = Person::players[i]->yaw; - Person::players[i]->forwardkeydown = 0; - Person::players[i]->leftkeydown = 0; - Person::players[i]->backkeydown = 0; - Person::players[i]->rightkeydown = 0; - Person::players[i]->jumpkeydown = 0; - Person::players[i]->attackkeydown = 0; - Person::players[i]->crouchkeydown = 0; - Person::players[i]->throwkeydown = 0; - } - - - XYZ facing; - facing = 0; - facing.z = -1; - - XYZ flatfacing = DoRotation(facing, 0, Person::players[i]->yaw + 180, 0); - facing = flatfacing; - - if (Person::players[i]->aitype == attacktypecutoff) { - Person::players[i]->targetheadyaw = 180 - roughDirectionTo(Person::players[i]->coords, Person::players[0]->coords); - Person::players[i]->targetheadpitch = pitchTo(Person::players[i]->coords, Person::players[0]->coords); - } else if (Person::players[i]->howactive >= typesleeping) { - Person::players[i]->targetheadyaw = Person::players[i]->targetyaw; - Person::players[i]->targetheadpitch = 0; - } else { - if (Person::players[i]->interestdelay <= 0) { - Person::players[i]->interestdelay = .7 + (float)(abs(Random() % 100)) / 100; - Person::players[i]->headtarget = Person::players[i]->coords; - Person::players[i]->headtarget.x += (float)(abs(Random() % 200) - 100) / 100; - Person::players[i]->headtarget.z += (float)(abs(Random() % 200) - 100) / 100; - Person::players[i]->headtarget.y += (float)(abs(Random() % 200) - 100) / 300; - Person::players[i]->headtarget += Person::players[i]->facing * 1.5; - } - Person::players[i]->targetheadyaw = 180 - roughDirectionTo(Person::players[i]->coords, Person::players[i]->headtarget); - Person::players[i]->targetheadpitch = pitchTo(Person::players[i]->coords, Person::players[i]->headtarget); - } - } -} - void Game::Tick() { static XYZ facing, flatfacing; @@ -4469,7 +3445,7 @@ void Game::Tick() if (Person::players[i]->collided > .8) Person::players[i]->avoidcollided = 0; - doAI(i); + Person::players[i]->doAI(); if (Animation::animations[Person::players[i]->animTarget].attack == reversed) { //Person::players[i]->targetyaw=Person::players[i]->yaw; diff --git a/Source/Objects/Person.cpp b/Source/Objects/Person.cpp index 9969e61..ced39db 100644 --- a/Source/Objects/Person.cpp +++ b/Source/Objects/Person.cpp @@ -67,6 +67,13 @@ extern float hostiletime; extern bool gamestarted; +extern XYZ envsound[30]; +extern float envsoundvol[30]; +extern int numenvsounds; +extern float envsoundlife[30]; + +extern XYZ windvector; + std::vector> Person::players(1, std::shared_ptr(new Person())); Person::Person() : @@ -6820,6 +6827,51 @@ int Person::SphereCheck(XYZ *p1, float radius, XYZ *p, XYZ *move, float *rotate, return firstintersecting; } +int findPathDist(int start, int end) +{ + int smallestcount, count, connected; + int last, last2, last3, last4; + int closest; + + smallestcount = 1000; + for (int i = 0; i < 50; i++) { + count = 0; + last = start; + last2 = -1; + last3 = -1; + last4 = -1; + while (last != end && count < 30) { + closest = -1; + for (int j = 0; j < Game::numpathpoints; j++) { + if (j != last && j != last2 && j != last3 && j != last4) { + connected = 0; + if (Game::numpathpointconnect[j]) + for (int k = 0; k < Game::numpathpointconnect[j]; k++) { + if (Game::pathpointconnect[j][k] == last)connected = 1; + } + if (!connected) + if (Game::numpathpointconnect[last]) + for (int k = 0; k < Game::numpathpointconnect[last]; k++) { + if (Game::pathpointconnect[last][k] == j)connected = 1; + } + if (connected) + if (closest == -1 || Random() % 2 == 0) { + closest = j; + } + } + } + last4 = last3; + last3 = last2; + last2 = last; + last = closest; + count++; + } + if (count < smallestcount) + smallestcount = count; + } + return smallestcount; +} + void Person::takeWeapon(int weaponId) { weaponactive = 0; @@ -6892,3 +6944,987 @@ bool Person::addClothes(const int& clothesId) return 0; } } + +extern float sq(float n); +extern float roughDirectionTo(XYZ start, XYZ end); +extern float pitchTo(XYZ start, XYZ end); + +void Person::doAI() +{ + if (aitype != playercontrolled && !Dialog::inDialog()) { + jumpclimb = 0; + //disable movement in editor + if (Game::editorenabled) + stunned = 1; + + pause = 0; + if (distsqflat(&Person::players[0]->coords, &coords) < 30 && + Person::players[0]->coords.y > coords.y + 2 && + !Person::players[0]->onterrain) + pause = 1; + + //pathfinding + if (aitype == pathfindtype) { + if (finalpathfindpoint == -1) { + float closestdistance; + float tempdist; + int closest; + XYZ colpoint; + closest = -1; + closestdistance = -1; + for (int j = 0; j < Game::numpathpoints; j++) { + if (closest == -1 || distsq(&finalfinaltarget, &Game::pathpoint[j]) < closestdistance) { + closestdistance = distsq(&finalfinaltarget, &Game::pathpoint[j]); + closest = j; + finaltarget = Game::pathpoint[j]; + } + } + finalpathfindpoint = closest; + for (int j = 0; j < Game::numpathpoints; j++) { + for (int k = 0; k < Game::numpathpointconnect[j]; k++) { + DistancePointLine(&finalfinaltarget, &Game::pathpoint[j], &Game::pathpoint[Game::pathpointconnect[j][k]], &tempdist, &colpoint); + if (sq(tempdist) < closestdistance) + if (findDistance(&colpoint, &Game::pathpoint[j]) + findDistance(&colpoint, &Game::pathpoint[Game::pathpointconnect[j][k]]) < + findDistance(&Game::pathpoint[j], &Game::pathpoint[Game::pathpointconnect[j][k]]) + .1) { + closestdistance = sq(tempdist); + closest = j; + finaltarget = colpoint; + } + } + } + finalpathfindpoint = closest; + + } + if (targetpathfindpoint == -1) { + float closestdistance; + float tempdist; + int closest; + XYZ colpoint; + closest = -1; + closestdistance = -1; + if (lastpathfindpoint == -1) { + for (int j = 0; j < Game::numpathpoints; j++) { + if (j != lastpathfindpoint) + if (closest == -1 || (distsq(&coords, &Game::pathpoint[j]) < closestdistance)) { + closestdistance = distsq(&coords, &Game::pathpoint[j]); + closest = j; + } + } + targetpathfindpoint = closest; + for (int j = 0; j < Game::numpathpoints; j++) + if (j != lastpathfindpoint) + for (int k = 0; k < Game::numpathpointconnect[j]; k++) { + DistancePointLine(&coords, &Game::pathpoint[j], &Game::pathpoint[Game::pathpointconnect[j][k]], &tempdist, &colpoint ); + if (sq(tempdist) < closestdistance) { + if (findDistance(&colpoint, &Game::pathpoint[j]) + findDistance(&colpoint, &Game::pathpoint[Game::pathpointconnect[j][k]]) < + findDistance(&Game::pathpoint[j], &Game::pathpoint[Game::pathpointconnect[j][k]]) + .1) { + closestdistance = sq(tempdist); + closest = j; + } + } + } + targetpathfindpoint = closest; + } else { + for (int j = 0; j < Game::numpathpoints; j++) + if (j != lastpathfindpoint && + j != lastpathfindpoint2 && + j != lastpathfindpoint3 && + j != lastpathfindpoint4) { + bool connected = 0; + if (Game::numpathpointconnect[j]) + for (int k = 0; k < Game::numpathpointconnect[j]; k++) + if (Game::pathpointconnect[j][k] == lastpathfindpoint) + connected = 1; + if (!connected) + if (Game::numpathpointconnect[lastpathfindpoint]) + for (int k = 0; k < Game::numpathpointconnect[lastpathfindpoint]; k++) + if (Game::pathpointconnect[lastpathfindpoint][k] == j) + connected = 1; + if (connected) { + tempdist = findPathDist(j, finalpathfindpoint); + if (closest == -1 || tempdist < closestdistance) { + closestdistance = tempdist; + closest = j; + } + } + } + targetpathfindpoint = closest; + } + } + losupdatedelay -= multiplier; + + targetyaw = roughDirectionTo(coords, Game::pathpoint[targetpathfindpoint]); + lookyaw = targetyaw; + + //reached target point + if (distsqflat(&coords, &Game::pathpoint[targetpathfindpoint]) < .6) { + lastpathfindpoint4 = lastpathfindpoint3; + lastpathfindpoint3 = lastpathfindpoint2; + lastpathfindpoint2 = lastpathfindpoint; + lastpathfindpoint = targetpathfindpoint; + if (lastpathfindpoint2 == -1) + lastpathfindpoint2 = lastpathfindpoint; + if (lastpathfindpoint3 == -1) + lastpathfindpoint3 = lastpathfindpoint2; + if (lastpathfindpoint4 == -1) + lastpathfindpoint4 = lastpathfindpoint3; + targetpathfindpoint = -1; + } + if ( distsqflat(&coords, &finalfinaltarget) < + distsqflat(&coords, &finaltarget) || + distsqflat(&coords, &finaltarget) < .6 * sq(scale * 5) || + lastpathfindpoint == finalpathfindpoint) { + aitype = passivetype; + } + + forwardkeydown = 1; + leftkeydown = 0; + backkeydown = 0; + rightkeydown = 0; + crouchkeydown = 0; + attackkeydown = 0; + throwkeydown = 0; + + if (avoidcollided > .8 && !jumpkeydown && collided < .8) + targetyaw += 90 * (whichdirection * 2 - 1); + + if (collided < 1 || animTarget != jumpupanim) + jumpkeydown = 0; + if ((collided > .8 && jumppower >= 5)) + jumpkeydown = 1; + + if ((!Tutorial::active || cananger) && + hostile && + !Person::players[0]->dead && + distsq(&coords, &Person::players[0]->coords) < 400 && + occluded < 25) { + if (distsq(&coords, &Person::players[0]->coords) < 12 && + Animation::animations[Person::players[0]->animTarget].height != lowheight && + !Game::editorenabled && + (Person::players[0]->coords.y < coords.y + 5 || Person::players[0]->onterrain)) + aitype = attacktypecutoff; + if (distsq(&coords, &Person::players[0]->coords) < 30 && + Animation::animations[Person::players[0]->animTarget].height == highheight && + !Game::editorenabled) + aitype = attacktypecutoff; + + if (losupdatedelay < 0 && !Game::editorenabled && occluded < 2) { + losupdatedelay = .2; + for (unsigned j = 0; j < Person::players.size(); j++) + if (j == 0 || Person::players[j]->skeleton.free || Person::players[j]->aitype != passivetype) + if (abs(Random() % 2) || Animation::animations[Person::players[j]->animTarget].height != lowheight || j != 0) + if (distsq(&coords, &Person::players[j]->coords) < 400) + if (normaldotproduct(facing, Person::players[j]->coords - coords) > 0) + if (Person::players[j]->coords.y < coords.y + 5 || Person::players[j]->onterrain) + if (!Person::players[j]->isWallJump() && -1 == Object::checkcollide( + DoRotation(jointPos(head), 0, yaw, 0) + *scale + coords, + DoRotation(Person::players[j]->jointPos(head), 0, Person::players[j]->yaw, 0) + *Person::players[j]->scale + Person::players[j]->coords) || + (Person::players[j]->animTarget == hanganim && + normaldotproduct(Person::players[j]->facing, coords - Person::players[j]->coords) < 0)) { + aitype = searchtype; + lastchecktime = 12; + lastseen = Person::players[j]->coords; + lastseentime = 12; + } + } + } + if (aitype == attacktypecutoff && Game::musictype != 2) + if (creature != wolftype) { + stunned = .6; + surprised = .6; + } + } + + if (aitype != passivetype && Game::leveltime > .5) + howactive = typeactive; + + if (aitype == passivetype) { + aiupdatedelay -= multiplier; + losupdatedelay -= multiplier; + lastseentime += multiplier; + pausetime -= multiplier; + if (lastseentime > 1) + lastseentime = 1; + + if (aiupdatedelay < 0) { + if (numwaypoints > 1 && howactive == typeactive && pausetime <= 0) { + targetyaw = roughDirectionTo(coords, waypoints[waypoint]); + lookyaw = targetyaw; + aiupdatedelay = .05; + + if (distsqflat(&coords, &waypoints[waypoint]) < 1) { + if (waypointtype[waypoint] == wppause) + pausetime = 4; + waypoint++; + if (waypoint > numwaypoints - 1) + waypoint = 0; + + } + } + + if (numwaypoints > 1 && howactive == typeactive && pausetime <= 0) + forwardkeydown = 1; + else + forwardkeydown = 0; + leftkeydown = 0; + backkeydown = 0; + rightkeydown = 0; + crouchkeydown = 0; + attackkeydown = 0; + throwkeydown = 0; + + if (avoidcollided > .8 && !jumpkeydown && collided < .8) { + if (!avoidsomething) + targetyaw += 90 * (whichdirection * 2 - 1); + else { + XYZ leftpos, rightpos; + float leftdist, rightdist; + leftpos = coords + DoRotation(facing, 0, 90, 0); + rightpos = coords - DoRotation(facing, 0, 90, 0); + leftdist = distsq(&leftpos, &avoidwhere); + rightdist = distsq(&rightpos, &avoidwhere); + if (leftdist < rightdist) + targetyaw += 90; + else + targetyaw -= 90; + } + } + } + if (collided < 1 || animTarget != jumpupanim) + jumpkeydown = 0; + if ((collided > .8 && jumppower >= 5)) + jumpkeydown = 1; + + + //hearing sounds + if (!Game::editorenabled) { + if (howactive <= typesleeping) + if (numenvsounds > 0 && (!Tutorial::active || cananger) && 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)) + aitype = attacktypecutoff; + } + + if (aitype != passivetype) { + if (howactive == typesleeping) + setAnimation(getupfromfrontanim); + howactive = typeactive; + } + } + + if (howactive < typesleeping && + ((!Tutorial::active || cananger) && hostile) && + !Person::players[0]->dead && + distsq(&coords, &Person::players[0]->coords) < 400 && + occluded < 25) { + if (distsq(&coords, &Person::players[0]->coords) < 12 && + Animation::animations[Person::players[0]->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) + aitype = attacktypecutoff; + + //wolf smell + if (creature == wolftype) { + XYZ windsmell; + for (unsigned j = 0; j < Person::players.size(); j++) { + if (j == 0 || (Person::players[j]->dead && Person::players[j]->bloodloss > 0)) { + float smelldistance = 50; + if (j == 0 && Person::players[j]->num_weapons > 0) { + if (weapons[Person::players[j]->weaponids[0]].bloody) + smelldistance = 100; + if (Person::players[j]->num_weapons == 2) + if (weapons[Person::players[j]->weaponids[1]].bloody) + smelldistance = 100; + } + if (j != 0) + smelldistance = 100; + windsmell = windvector; + Normalise(&windsmell); + windsmell = windsmell * 2 + Person::players[j]->coords; + if (distsq(&coords, &windsmell) < smelldistance && !Game::editorenabled) + aitype = attacktypecutoff; + } + } + } + + if (howactive < typesleeping && losupdatedelay < 0 && !Game::editorenabled && occluded < 2) { + losupdatedelay = .2; + for (unsigned j = 0; j < Person::players.size(); j++) { + if (j == 0 || Person::players[j]->skeleton.free || Person::players[j]->aitype != passivetype) { + if (abs(Random() % 2) || Animation::animations[Person::players[j]->animTarget].height != lowheight || j != 0) + if (distsq(&coords, &Person::players[j]->coords) < 400) + if (normaldotproduct(facing, Person::players[j]->coords - coords) > 0) + if ((-1 == Object::checkcollide( + DoRotation(jointPos(head), 0, yaw, 0)* + scale + coords, + DoRotation(Person::players[j]->jointPos(head), 0, Person::players[j]->yaw, 0)* + Person::players[j]->scale + Person::players[j]->coords) && + !Person::players[j]->isWallJump()) || + (Person::players[j]->animTarget == hanganim && + normaldotproduct(Person::players[j]->facing, coords - Person::players[j]->coords) < 0)) { + lastseentime -= .2; + if (j == 0 && Animation::animations[Person::players[j]->animTarget].height == lowheight) + lastseentime -= .4; + else + lastseentime -= .6; + } + if (lastseentime <= 0) { + aitype = searchtype; + lastchecktime = 12; + lastseen = Person::players[j]->coords; + lastseentime = 12; + } + } + } + } + } + //alerted surprise + if (aitype == attacktypecutoff && Game::musictype != 2) { + if (creature != wolftype) { + stunned = .6; + surprised = .6; + } + if (creature == wolftype) { + stunned = .47; + surprised = .47; + } + numseen++; + } + } + + //search for player + int j; + if (aitype == searchtype) { + aiupdatedelay -= multiplier; + losupdatedelay -= multiplier; + if (!pause) + lastseentime -= multiplier; + lastchecktime -= multiplier; + + if (isRun() && !onground) { + if (coords.y > terrain.getHeight(coords.x, coords.z) + 10) { + XYZ test2 = coords + facing; + test2.y += 5; + XYZ test = coords + facing; + test.y -= 10; + j = Object::checkcollide(test2, test, laststanding); + if (j == -1) + j = Object::checkcollide(test2, test); + if (j == -1) { + velocity = 0; + setAnimation(getStop()); + targetyaw += 180; + stunned = .5; + //aitype=passivetype; + aitype = pathfindtype; + finalfinaltarget = waypoints[waypoint]; + finalpathfindpoint = -1; + targetpathfindpoint = -1; + lastpathfindpoint = -1; + lastpathfindpoint2 = -1; + lastpathfindpoint3 = -1; + lastpathfindpoint4 = -1; + } else + laststanding = j; + } + } + //check out last seen location + if (aiupdatedelay < 0) { + targetyaw = roughDirectionTo(coords, lastseen); + lookyaw = targetyaw; + aiupdatedelay = .05; + forwardkeydown = 1; + + if (distsqflat(&coords, &lastseen) < 1 * sq(scale * 5) || lastchecktime < 0) { + forwardkeydown = 0; + aiupdatedelay = 1; + lastseen.x += (float(Random() % 100) - 50) / 25; + lastseen.z += (float(Random() % 100) - 50) / 25; + lastchecktime = 3; + } + + leftkeydown = 0; + backkeydown = 0; + rightkeydown = 0; + crouchkeydown = 0; + attackkeydown = 0; + throwkeydown = 0; + + if (avoidcollided > .8 && !jumpkeydown && collided < .8) { + if (!avoidsomething) + targetyaw += 90 * (whichdirection * 2 - 1); + else { + XYZ leftpos, rightpos; + float leftdist, rightdist; + leftpos = coords + DoRotation(facing, 0, 90, 0); + rightpos = coords - DoRotation(facing, 0, 90, 0); + leftdist = distsq(&leftpos, &avoidwhere); + rightdist = distsq(&rightpos, &avoidwhere); + if (leftdist < rightdist) + targetyaw += 90; + else + targetyaw -= 90; + } + } + } + if (collided < 1 || animTarget != jumpupanim) + jumpkeydown = 0; + if ((collided > .8 && jumppower >= 5)) + jumpkeydown = 1; + + if (numenvsounds > 0 && ((!Tutorial::active || cananger) && hostile)) + for (int k = 0; k < numenvsounds; k++) { + if (distsq(&coords, &envsound[k]) < 2 * (envsoundvol[k] + envsoundvol[k] * (creature == rabbittype) * 3)) { + aitype = attacktypecutoff; + } + } + + if (!Person::players[0]->dead && + 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) { + 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 ((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)) { + /* //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) + */ + aitype = attacktypecutoff; + lastseentime = 1; + } + } + //player escaped + if (lastseentime < 0) { + //aitype=passivetype; + numescaped++; + aitype = pathfindtype; + finalfinaltarget = waypoints[waypoint]; + finalpathfindpoint = -1; + targetpathfindpoint = -1; + lastpathfindpoint = -1; + lastpathfindpoint2 = -1; + lastpathfindpoint3 = -1; + lastpathfindpoint4 = -1; + } + } + + if (aitype != gethelptype) + runninghowlong = 0; + + //get help from buddies + if (aitype == gethelptype) { + runninghowlong += multiplier; + aiupdatedelay -= multiplier; + + if (aiupdatedelay < 0 || ally == 0) { + aiupdatedelay = .2; + + //find closest ally + //TODO: factor out closest search somehow + if (!ally) { + int closest = -1; + float closestdist = -1; + for (unsigned k = 0; k < Person::players.size(); k++) { + if ((k != id) && (k != 0) && !Person::players[k]->dead && + (Person::players[k]->howactive < typedead1) && + !Person::players[k]->skeleton.free && + (Person::players[k]->aitype == passivetype)) { + float distance = distsq(&coords, &Person::players[k]->coords); + if (closestdist == -1 || distance < closestdist) { + closestdist = distance; + closest = k; + } + closest = k; + } + } + if (closest != -1) { + ally = closest; + } else { + ally = 0; + } + lastseen = Person::players[0]->coords; + lastseentime = 12; + } + + + lastchecktime = 12; + + XYZ facing = coords; + XYZ flatfacing = Person::players[ally]->coords; + facing.y += jointPos(head).y * scale; + flatfacing.y += Person::players[ally]->jointPos(head).y * Person::players[ally]->scale; + if (-1 != Object::checkcollide(facing, flatfacing)) + lastseentime -= .1; + + //no available ally, run back to player + if (ally <= 0 || + Person::players[ally]->skeleton.free || + Person::players[ally]->aitype != passivetype || + lastseentime <= 0) { + aitype = searchtype; + lastseentime = 12; + } + + //seek out ally + if (ally > 0) { + targetyaw = roughDirectionTo(coords, Person::players[ally]->coords); + lookyaw = targetyaw; + aiupdatedelay = .05; + forwardkeydown = 1; + + if (distsqflat(&coords, &Person::players[ally]->coords) < 3) { + aitype = searchtype; + lastseentime = 12; + Person::players[ally]->aitype = searchtype; + if (Person::players[ally]->lastseentime < lastseentime) { + Person::players[ally]->lastseen = lastseen; + Person::players[ally]->lastseentime = lastseentime; + Person::players[ally]->lastchecktime = lastchecktime; + } + } + + if (avoidcollided > .8 && !jumpkeydown && collided < .8) { + if (!avoidsomething) + targetyaw += 90 * (whichdirection * 2 - 1); + else { + XYZ leftpos, rightpos; + float leftdist, rightdist; + leftpos = coords + DoRotation(facing, 0, 90, 0); + rightpos = coords - DoRotation(facing, 0, 90, 0); + leftdist = distsq(&leftpos, &avoidwhere); + rightdist = distsq(&rightpos, &avoidwhere); + if (leftdist < rightdist) + targetyaw += 90; + else + targetyaw -= 90; + } + } + } + + leftkeydown = 0; + backkeydown = 0; + rightkeydown = 0; + crouchkeydown = 0; + attackkeydown = 0; + } + if (collided < 1 || animTarget != jumpupanim) + jumpkeydown = 0; + if (collided > .8 && jumppower >= 5) + jumpkeydown = 1; + } + + //retreiving a weapon on the ground + if (aitype == getweapontype) { + aiupdatedelay -= multiplier; + lastchecktime -= multiplier; + + if (aiupdatedelay < 0) { + aiupdatedelay = .2; + + //ALLY IS WEPON + if (ally < 0) { + int closest = -1; + float closestdist = -1; + for (unsigned k = 0; k < weapons.size(); k++) + if (weapons[k].owner == -1) { + float distance = distsq(&coords, &weapons[k].position); + if (closestdist == -1 || distance < closestdist) { + closestdist = distance; + closest = k; + } + closest = k; + } + if (closest != -1) + ally = closest; + else + ally = -1; + } + + lastseentime = 12; + + if (!Person::players[0]->dead && ((!Tutorial::active || cananger) && hostile)) + if (ally < 0 || weaponactive != -1 || lastchecktime <= 0) { + aitype = attacktypecutoff; + lastseentime = 1; + } + if (!Person::players[0]->dead) + if (ally >= 0) { + if (weapons[ally].owner != -1 || + distsq(&coords, &weapons[ally].position) > 16) { + aitype = attacktypecutoff; + lastseentime = 1; + } + //TODO: factor these out as moveToward() + targetyaw = roughDirectionTo(coords, weapons[ally].position); + lookyaw = targetyaw; + aiupdatedelay = .05; + forwardkeydown = 1; + + + if (avoidcollided > .8 && !jumpkeydown && collided < .8) { + if (!avoidsomething) + targetyaw += 90 * (whichdirection * 2 - 1); + else { + XYZ leftpos, rightpos; + float leftdist, rightdist; + leftpos = coords + DoRotation(facing, 0, 90, 0); + rightpos = coords - DoRotation(facing, 0, 90, 0); + leftdist = distsq(&leftpos, &avoidwhere); + rightdist = distsq(&rightpos, &avoidwhere); + if (leftdist < rightdist) + targetyaw += 90; + else + targetyaw -= 90; + } + } + } + + leftkeydown = 0; + backkeydown = 0; + rightkeydown = 0; + attackkeydown = 0; + throwkeydown = 1; + crouchkeydown = 0; + if (animTarget != crouchremoveknifeanim && + animTarget != removeknifeanim) + throwtogglekeydown = 0; + drawkeydown = 0; + } + if (collided < 1 || animTarget != jumpupanim) + jumpkeydown = 0; + if ((collided > .8 && jumppower >= 5)) + jumpkeydown = 1; + } + + if (aitype == attacktypecutoff) { + 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 && + (aiupdatedelay < .1)) { + attackkeydown = 0; + if (isIdle()) + crouchkeydown = 1; + if (Person::players[0]->animTarget != rabbitkickanim && Person::players[0]->weaponactive != -1) { + if (weapons[Person::players[0]->weaponids[0]].getType() == knife) { + if (isIdle() || isCrouch() || isRun() || isFlip()) { + if (abs(Random() % 2) == 0) + setAnimation(backhandspringanim); + else + setAnimation(rollanim); + targetyaw += 90 * (abs(Random() % 2) * 2 - 1); + wentforweapon = 0; + } + if (animTarget == jumpupanim || animTarget == jumpdownanim) + setAnimation(flipanim); + } + } + forwardkeydown = 0; + aiupdatedelay = .02; + } + //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 ((1 - damage / damagetolerance) > .5) + stunned = 1; + } + //go for weapon on the ground + if (wentforweapon < 3) + for (unsigned k = 0; k < weapons.size(); k++) + if (creature != wolftype) + if (num_weapons == 0 && + weapons[k].owner == -1 && + weapons[k].velocity.x == 0 && + weapons[k].velocity.z == 0 && + weapons[k].velocity.y == 0) { + if (distsq(&coords, &weapons[k].position) < 16) { + wentforweapon++; + lastchecktime = 6; + aitype = getweapontype; + ally = -1; + } + } + //dodge/reverse walljump kicks + if (damage < damagetolerance / 2) + if (Animation::animations[animTarget].height != highheight) + if (damage < damagetolerance * .5 && + ((Person::players[0]->animTarget == walljumprightkickanim || + Person::players[0]->animTarget == walljumpleftkickanim) && + ((aiupdatedelay < .15 && + difficulty == 2) || + (aiupdatedelay < .08 && + difficulty != 2)))) { + crouchkeydown = 1; + } + //walked off a ledge (?) + if (isRun() && !onground) + if (coords.y > terrain.getHeight(coords.x, coords.z) + 10) { + XYZ test2 = coords + facing; + test2.y += 5; + XYZ test = coords + facing; + test.y -= 10; + j = Object::checkcollide(test2, test, laststanding); + if (j == -1) + j = Object::checkcollide(test2, test); + if (j == -1) { + velocity = 0; + setAnimation(getStop()); + targetyaw += 180; + stunned = .5; + aitype = pathfindtype; + finalfinaltarget = waypoints[waypoint]; + finalpathfindpoint = -1; + targetpathfindpoint = -1; + lastpathfindpoint = -1; + lastpathfindpoint2 = -1; + lastpathfindpoint3 = -1; + lastpathfindpoint4 = -1; + } else + laststanding = j; + } + //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) { + aitype = pathfindtype; + finalfinaltarget = waypoints[waypoint]; + finalpathfindpoint = -1; + targetpathfindpoint = -1; + lastpathfindpoint = -1; + lastpathfindpoint2 = -1; + lastpathfindpoint3 = -1; + lastpathfindpoint4 = -1; + } + //it's time to think (?) + if (aiupdatedelay < 0 && + !Animation::animations[animTarget].attack && + animTarget != staggerbackhighanim && + animTarget != staggerbackhardanim && + animTarget != backhandspringanim && + animTarget != dodgebackanim) { + //draw weapon + if (weaponactive == -1 && num_weapons > 0) + drawkeydown = Random() % 2; + else + drawkeydown = 0; + rabbitkickenabled = Random() % 2; + //chase player + XYZ rotatetarget = Person::players[0]->coords + Person::players[0]->velocity; + XYZ targetpoint = Person::players[0]->coords; + if (distsq(&Person::players[0]->coords, &coords) < + distsq(&rotatetarget, &coords)) + targetpoint += Person::players[0]->velocity * + findDistance(&Person::players[0]->coords, &coords) / findLength(&velocity); + targetyaw = roughDirectionTo(coords, targetpoint); + lookyaw = targetyaw; + aiupdatedelay = .2 + fabs((float)(Random() % 100) / 1000); + + if (distsq(&coords, &Person::players[0]->coords) > 5 && (Person::players[0]->weaponactive == -1 || weaponactive != -1)) + forwardkeydown = 1; + else if ((distsq(&coords, &Person::players[0]->coords) > 16 || + distsq(&coords, &Person::players[0]->coords) < 9) && + Person::players[0]->weaponactive != -1) + forwardkeydown = 1; + else if (Random() % 6 == 0 || (creature == wolftype && Random() % 3 == 0)) + forwardkeydown = 1; + else + forwardkeydown = 0; + //chill out around the corpse + if (Person::players[0]->dead) { + forwardkeydown = 0; + if (Random() % 10 == 0) + forwardkeydown = 1; + if (Random() % 100 == 0) { + aitype = pathfindtype; + finalfinaltarget = waypoints[waypoint]; + finalpathfindpoint = -1; + targetpathfindpoint = -1; + lastpathfindpoint = -1; + lastpathfindpoint2 = -1; + lastpathfindpoint3 = -1; + lastpathfindpoint4 = -1; + } + } + leftkeydown = 0; + backkeydown = 0; + rightkeydown = 0; + crouchkeydown = 0; + throwkeydown = 0; + + if (avoidcollided > .8 && !jumpkeydown && collided < .8) + targetyaw += 90 * (whichdirection * 2 - 1); + //attack!!! + if (Random() % 2 == 0 || weaponactive != -1 || creature == wolftype) + attackkeydown = 1; + else + attackkeydown = 0; + if (isRun() && Random() % 6 && distsq(&coords, &Person::players[0]->coords) > 7) + attackkeydown = 0; + + //TODO: wat + if (aitype != playercontrolled && + (isIdle() || + isCrouch() || + isRun())) { + int target = -2; + for (unsigned j = 0; j < Person::players.size(); j++) + if (j != id && !Person::players[j]->skeleton.free && + Person::players[j]->hasvictim && + (Tutorial::active && reversaltrain || + Random() % 2 == 0 && difficulty == 2 || + Random() % 4 == 0 && difficulty == 1 || + Random() % 8 == 0 && difficulty == 0 || + Person::players[j]->lastattack2 == Person::players[j]->animTarget && + Person::players[j]->lastattack3 == Person::players[j]->animTarget && + (Random() % 2 == 0 || difficulty == 2) || + (isIdle() || isRun()) && + Person::players[j]->weaponactive != -1 || + Person::players[j]->animTarget == swordslashanim && + weaponactive != -1 || + Person::players[j]->animTarget == staffhitanim || + Person::players[j]->animTarget == staffspinhitanim)) + if (distsq(&Person::players[j]->coords, &Person::players[j]->victim->coords) < 4 && + Person::players[j]->victim == Person::players[id] && + (Person::players[j]->animTarget == sweepanim || + Person::players[j]->animTarget == spinkickanim || + Person::players[j]->animTarget == staffhitanim || + Person::players[j]->animTarget == staffspinhitanim || + Person::players[j]->animTarget == winduppunchanim || + Person::players[j]->animTarget == upunchanim || + Person::players[j]->animTarget == wolfslapanim || + Person::players[j]->animTarget == knifeslashstartanim || + Person::players[j]->animTarget == swordslashanim && + (distsq(&Person::players[j]->coords, &coords) < 2 || + weaponactive != -1))) { + if (target >= 0) { + target = -1; + } else { + target = j; + } + } + if (target >= 0) + Person::players[target]->Reverse(); + } + + if (collided < 1) + jumpkeydown = 0; + if (collided > .8 && jumppower >= 5 || + distsq(&coords, &Person::players[0]->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 (Person::players[0]->animTarget == jumpdownanim && + distsq(&Person::players[0]->coords, &coords) < 40) + crouchkeydown = 1; + if (jumpkeydown) + attackkeydown = 0; + + if (Tutorial::active) + if (!canattack) + attackkeydown = 0; + + + XYZ facing = coords; + XYZ flatfacing = Person::players[0]->coords; + facing.y += jointPos(head).y * scale; + flatfacing.y += Person::players[0]->jointPos(head).y * Person::players[0]->scale; + if (occluded >= 2) + if (-1 != Object::checkcollide(facing, flatfacing)) { + if (!pause) + lastseentime -= .2; + if (lastseentime <= 0 && + (creature != wolftype || + weaponstuck == -1)) { + aitype = searchtype; + lastchecktime = 12; + lastseen = Person::players[0]->coords; + lastseentime = 12; + } + } else + lastseentime = 1; + } + } + if (Animation::animations[Person::players[0]->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; + test.y -= 40; + if (-1 == Object::checkcollide(Person::players[0]->coords, test)) + stunned = 1; + } + //stunned + if (aitype == passivetype && !(numwaypoints > 1) || + stunned > 0 || + pause && damage > superpermanentdamage) { + if (pause) + lastseentime = 1; + targetyaw = yaw; + forwardkeydown = 0; + leftkeydown = 0; + backkeydown = 0; + rightkeydown = 0; + jumpkeydown = 0; + attackkeydown = 0; + crouchkeydown = 0; + throwkeydown = 0; + } + + + XYZ facing; + facing = 0; + facing.z = -1; + + XYZ flatfacing = DoRotation(facing, 0, yaw + 180, 0); + facing = flatfacing; + + if (aitype == attacktypecutoff) { + targetheadyaw = 180 - roughDirectionTo(coords, Person::players[0]->coords); + targetheadpitch = pitchTo(coords, Person::players[0]->coords); + } else if (howactive >= typesleeping) { + targetheadyaw = targetyaw; + targetheadpitch = 0; + } else { + if (interestdelay <= 0) { + interestdelay = .7 + (float)(abs(Random() % 100)) / 100; + headtarget = coords; + headtarget.x += (float)(abs(Random() % 200) - 100) / 100; + headtarget.z += (float)(abs(Random() % 200) - 100) / 100; + headtarget.y += (float)(abs(Random() % 200) - 100) / 300; + headtarget += facing * 1.5; + } + targetheadyaw = 180 - roughDirectionTo(coords, headtarget); + targetheadpitch = pitchTo(coords, headtarget); + } + } +} diff --git a/Source/Objects/Person.hpp b/Source/Objects/Person.hpp index 62af3a6..5339e03 100644 --- a/Source/Objects/Person.hpp +++ b/Source/Objects/Person.hpp @@ -395,6 +395,8 @@ public: bool addClothes(const int& clothesId); void addClothes(); + + void doAI(); }; const int maxplayers = 10;