00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019 #include "pent_include.h"
00020
00021 #include "AvatarMoverProcess.h"
00022 #include "Animation.h"
00023
00024 #include "GUIApp.h"
00025 #include "MainActor.h"
00026 #include "GameMapGump.h"
00027 #include "Kernel.h"
00028 #include "ActorAnimProcess.h"
00029 #include "TargetedAnimProcess.h"
00030 #include "AvatarGravityProcess.h"
00031 #include "ShapeInfo.h"
00032 #include "SettingManager.h"
00033 #include "MusicProcess.h"
00034 #include "getObject.h"
00035
00036 #include "IDataSource.h"
00037 #include "ODataSource.h"
00038
00039 #include "SDL.h"
00040
00041
00042 DEFINE_RUNTIME_CLASSTYPE_CODE(AvatarMoverProcess,Process);
00043
00044 AvatarMoverProcess::AvatarMoverProcess() : Process()
00045 {
00046 lastframe = 0;
00047 lastAttack = 0;
00048 idleTime = 0;
00049 lastHeadShakeAnim = Animation::lookLeft;
00050 mouseButton[0].state = MBS_HANDLED | MBS_RELHANDLED;
00051 mouseButton[1].state = MBS_HANDLED | MBS_RELHANDLED;
00052 mouseButton[0].curDown = 0;
00053 mouseButton[1].curDown = 0;
00054 mouseButton[0].lastDown = 0;
00055 mouseButton[1].lastDown = 0;
00056 type = 1;
00057 }
00058
00059
00060 AvatarMoverProcess::~AvatarMoverProcess()
00061 {
00062
00063 }
00064
00065 bool AvatarMoverProcess::run(const uint32 framenum)
00066 {
00067
00068 if (framenum == lastframe) return false;
00069 lastframe = framenum;
00070
00071
00072 MainActor* avatar = getMainActor();
00073
00074
00075 if (Kernel::get_instance()->getNumProcesses(1, 0x00F0) > 0) {
00076 idleTime = 0;
00077 return false;
00078 }
00079
00080
00081 if (avatar->getLastAnim() == Animation::hang) {
00082 return handleHangingMode(framenum);
00083 }
00084
00085
00086 if (avatar->getGravityPID() != 0) {
00087 idleTime = 0;
00088 return false;
00089 }
00090
00091 bool combatRun = (avatar->getActorFlags() & Actor::ACT_COMBATRUN);
00092 if (avatar->isInCombat() && !combatRun)
00093 return handleCombatMode(framenum);
00094 else
00095 return handleNormalMode(framenum);
00096 }
00097
00098 bool AvatarMoverProcess::handleHangingMode(const uint32 )
00099 {
00100 GUIApp* guiapp = GUIApp::get_instance();
00101 MainActor* avatar = getMainActor();
00102 uint32 now = SDL_GetTicks();
00103 bool stasis = guiapp->isAvatarInStasis();
00104
00105 idleTime = 0;
00106
00107 if (stasis) return false;
00108
00109 bool m0clicked = false;
00110 bool m1clicked = false;
00111 if (!(mouseButton[0].state & MBS_HANDLED) &&
00112 now - mouseButton[0].curDown > DOUBLE_CLICK_TIMEOUT)
00113 {
00114 m0clicked = true;
00115 mouseButton[0].state |= MBS_HANDLED;
00116 }
00117 if (!(mouseButton[1].state & MBS_HANDLED) &&
00118 now - mouseButton[1].curDown > DOUBLE_CLICK_TIMEOUT)
00119 {
00120 m1clicked = true;
00121 mouseButton[1].state |= MBS_HANDLED;
00122 }
00123 if (!(mouseButton[0].state & MBS_RELHANDLED))
00124 mouseButton[0].state |= MBS_RELHANDLED;
00125 if (!(mouseButton[1].state & MBS_RELHANDLED))
00126 mouseButton[1].state |= MBS_RELHANDLED;
00127
00128
00129
00130
00131 if ((mouseButton[0].state & MBS_DOWN) &&
00132 (!(mouseButton[0].state & MBS_HANDLED) || m0clicked))
00133 {
00134 mouseButton[0].state |= MBS_HANDLED;
00135 mouseButton[0].lastDown = 0;
00136
00137 if (avatar->tryAnim(Animation::climb40, 8) == Animation::SUCCESS) {
00138 avatar->ensureGravityProcess()->terminate();
00139 waitFor(avatar->doAnim(Animation::climb40, 8));
00140 }
00141 }
00142
00143 return false;
00144 }
00145
00146 bool AvatarMoverProcess::handleCombatMode(const uint32 framenum)
00147 {
00148 GUIApp* guiapp = GUIApp::get_instance();
00149 MainActor* avatar = getMainActor();
00150 Animation::Sequence lastanim = avatar->getLastAnim();
00151 Animation::Sequence nextanim = Animation::walk;
00152 sint32 direction = avatar->getDir();
00153 uint32 now = SDL_GetTicks();
00154 bool stasis = guiapp->isAvatarInStasis();
00155
00156 int mx, my;
00157 guiapp->getMouseCoords(mx, my);
00158 unsigned int mouselength = guiapp->getMouseLength(mx,my);
00159
00160
00161 sint32 mousedir = (guiapp->getMouseDirection(mx,my)+7)%8;
00162
00163
00164 idleTime = 0;
00165
00166
00167 if (lastanim == Animation::die || lastanim == Animation::fallBackwards) {
00168 if (!stasis)
00169 waitFor(avatar->doAnim(Animation::standUp, mousedir));
00170 return false;
00171 }
00172
00173
00174 if (lastanim == Animation::startBlock &&
00175 !(mouseButton[0].state & MBS_DOWN))
00176 {
00177
00178 waitFor(avatar->doAnim(Animation::stopBlock, direction));
00179 return false;
00180 }
00181
00182
00183 if (stasis)
00184 return false;
00185
00186 bool m0clicked = false;
00187 bool m1clicked = false;
00188
00189 if (!(mouseButton[0].state & MBS_HANDLED) &&
00190 now - mouseButton[0].curDown > DOUBLE_CLICK_TIMEOUT)
00191 {
00192 m0clicked = true;
00193 mouseButton[0].state |= MBS_HANDLED;
00194 }
00195
00196 if (!(mouseButton[1].state & MBS_HANDLED) &&
00197 now - mouseButton[1].curDown > DOUBLE_CLICK_TIMEOUT)
00198 {
00199 m1clicked = true;
00200 mouseButton[1].state |= MBS_HANDLED;
00201 }
00202
00203 if (!(mouseButton[0].state & MBS_RELHANDLED))
00204 mouseButton[0].state |= MBS_RELHANDLED;
00205
00206 if (!(mouseButton[1].state & MBS_RELHANDLED))
00207 mouseButton[1].state |= MBS_RELHANDLED;
00208
00209 if ((mouseButton[0].state & MBS_DOWN) &&
00210 (mouseButton[0].state & MBS_HANDLED) && mouseButton[0].lastDown > 0)
00211 {
00212
00213 if (lastanim == Animation::startBlock)
00214 return false;
00215
00216
00217
00218 if (checkTurn(mousedir, false)) return false;
00219
00220 waitFor(avatar->doAnim(Animation::startBlock, mousedir));
00221 return false;
00222 }
00223
00224 if ((mouseButton[0].state & MBS_DOWN) &&
00225 !(mouseButton[0].state & MBS_HANDLED) &&
00226 mouseButton[0].curDown-mouseButton[0].lastDown <= DOUBLE_CLICK_TIMEOUT)
00227 {
00228 mouseButton[0].state |= MBS_HANDLED;
00229 mouseButton[0].lastDown = 0;
00230
00231 if (canAttack()) {
00232
00233
00234
00235 if (checkTurn(mousedir, true)) return false;
00236
00237 waitFor(avatar->doAnim(Animation::attack, mousedir));
00238 lastAttack = framenum;
00239
00240
00241 avatar->accumulateStr(1+(std::rand()%2));
00242 avatar->accumulateDex(2+(std::rand()%2));
00243 }
00244
00245 return false;
00246 }
00247
00248 if ((mouseButton[1].state & MBS_DOWN) &&
00249 !(mouseButton[1].state & MBS_HANDLED) &&
00250 mouseButton[1].curDown-mouseButton[1].lastDown <= DOUBLE_CLICK_TIMEOUT)
00251 {
00252 mouseButton[1].state |= MBS_HANDLED;
00253 mouseButton[1].lastDown = 0;
00254
00255 Gump* desktopgump = GUIApp::get_instance()->getDesktopGump();
00256 if (desktopgump->TraceObjId(mx,my) == 1) {
00257
00258 avatar->toggleInCombat();
00259 waitFor(avatar->doAnim(Animation::unreadyWeapon, direction));
00260 return false;
00261 }
00262
00263 if (canAttack()) {
00264
00265
00266
00267 if (checkTurn(mousedir, false)) return false;
00268
00269 waitFor(avatar->doAnim(Animation::kick, mousedir));
00270 lastAttack = framenum;
00271
00272
00273 avatar->accumulateStr(1+(std::rand()%2));
00274 avatar->accumulateDex(2+(std::rand()%2));
00275 }
00276
00277 return false;
00278 }
00279
00280 if ((mouseButton[1].state & MBS_DOWN) &&
00281 (mouseButton[1].state & MBS_HANDLED) && mouseButton[1].lastDown > 0)
00282 {
00283
00284
00286
00287 if (checkTurn(mousedir, true)) return false;
00288
00289 sint32 nextdir = mousedir;
00290
00291 if (lastanim == Animation::run) {
00292
00293
00294 nextanim = Animation::readyWeapon;
00295 } else if (abs(direction - mousedir) == 4) {
00296 nextanim = Animation::retreat;
00297 nextdir = direction;
00298 } else
00299 nextanim = Animation::advance;
00300
00301 if (mouselength == 2)
00302 {
00303
00304 nextanim = Animation::walk;
00305 avatar->setActorFlag(Actor::ACT_COMBATRUN);
00306 avatar->toggleInCombat();
00307 MusicProcess::get_instance()->playCombatMusic(110);
00308 }
00309
00310 nextanim = Animation::checkWeapon(nextanim, lastanim);
00311 waitFor(avatar->doAnim(nextanim, nextdir));
00312 return false;
00313 }
00314
00315
00316 if (m0clicked || m1clicked)
00317 if (checkTurn(mousedir, false)) return false;
00318
00319
00320
00321 if (lastanim != Animation::combatStand) {
00322 nextanim = Animation::combatStand;
00323 nextanim = Animation::checkWeapon(nextanim, lastanim);
00324 waitFor(avatar->doAnim(nextanim, direction));
00325 }
00326
00327 return false;
00328 }
00329
00330 bool AvatarMoverProcess::handleNormalMode(const uint32 )
00331 {
00332 GUIApp* guiapp = GUIApp::get_instance();
00333 MainActor* avatar = getMainActor();
00334 Animation::Sequence lastanim = avatar->getLastAnim();
00335 Animation::Sequence nextanim = Animation::walk;
00336 sint32 direction = avatar->getDir();
00337 uint32 now = SDL_GetTicks();
00338 bool stasis = guiapp->isAvatarInStasis();
00339 bool combatRun = (avatar->getActorFlags() & Actor::ACT_COMBATRUN);
00340
00341 int mx, my;
00342 guiapp->getMouseCoords(mx, my);
00343 unsigned int mouselength = guiapp->getMouseLength(mx,my);
00344
00345
00346 sint32 mousedir = (guiapp->getMouseDirection(mx,my)+7)%8;
00347
00348
00349 sint32 currentIdleTime = idleTime;
00350 idleTime = 0;
00351
00352
00353 if (avatar->isInCombat())
00354 {
00355 avatar->clearActorFlag(Actor::ACT_COMBATRUN);
00356 avatar->toggleInCombat();
00357 }
00358
00359
00360 if (lastanim == Animation::die || lastanim == Animation::fallBackwards) {
00361 if (!stasis) {
00362
00363 waitFor(avatar->doAnim(Animation::standUp, direction));
00364 }
00365 return false;
00366 }
00367
00368
00369 if (!stasis && Animation::isCombatAnim(lastanim)) {
00370
00371
00372 ProcId anim1 = avatar->doAnim(Animation::unreadyWeapon, direction);
00373 ProcId anim2 = avatar->doAnim(Animation::stand, direction);
00374 Process* anim2p = Kernel::get_instance()->getProcess(anim2);
00375 anim2p->waitFor(anim1);
00376 waitFor(anim2);
00377
00378 return false;
00379 }
00380
00381 bool m0clicked = false;
00382 bool m1clicked = false;
00383
00384
00385 if (!(mouseButton[0].state & MBS_HANDLED) &&
00386 now - mouseButton[0].curDown > DOUBLE_CLICK_TIMEOUT)
00387 {
00388 m0clicked = true;
00389 mouseButton[0].state |= MBS_HANDLED;
00390 }
00391
00392 if (!(mouseButton[1].state & MBS_HANDLED) &&
00393 now - mouseButton[1].curDown > DOUBLE_CLICK_TIMEOUT)
00394 {
00395 m1clicked = true;
00396 mouseButton[1].state |= MBS_HANDLED;
00397 }
00398
00399
00400 if (!(mouseButton[0].state & MBS_RELHANDLED))
00401 mouseButton[0].state |= MBS_RELHANDLED;
00402
00403 if (!(mouseButton[1].state & MBS_RELHANDLED)) {
00404 mouseButton[1].state |= MBS_RELHANDLED;
00405
00406
00407
00408 if (combatRun)
00409 {
00410 MainActor* avatar = getMainActor();
00411 avatar->clearActorFlag(Actor::ACT_COMBATRUN);
00412 avatar->toggleInCombat();
00413 ProcId walkpid = avatar->doAnim(Animation::walk, direction);
00414 ProcId drawpid = avatar->doAnim(Animation::readyWeapon, direction);
00415 Process* drawproc = Kernel::get_instance()->getProcess(drawpid);
00416 drawproc->waitFor(walkpid);
00417 waitFor(drawpid);
00418 return false;
00419 }
00420
00421
00422
00423 if (lastanim == Animation::run) {
00424 ProcId walkpid = avatar->doAnim(Animation::walk, direction);
00425 ProcId standpid = avatar->doAnim(Animation::stand, direction);
00426 Process* standproc = Kernel::get_instance()->getProcess(standpid);
00427 standproc->waitFor(walkpid);
00428 waitFor(standpid);
00429 return false;
00430 }
00431
00432
00433
00434
00435 if (!stasis)
00436 waitFor(avatar->doAnim(Animation::stand, direction));
00437 return false;
00438 }
00439
00440
00441 if (stasis)
00442 return false;
00443
00444
00445 if (!(mouseButton[0].state & MBS_HANDLED) &&
00446 !(mouseButton[1].state & MBS_HANDLED))
00447 {
00448
00449 uint32 down = mouseButton[1].curDown;
00450 if (mouseButton[0].curDown < down)
00451 {
00452 down = down - mouseButton[0].curDown;
00453 }
00454 else
00455 {
00456 down = mouseButton[0].curDown - down;
00457 }
00458
00459 if (down < DOUBLE_CLICK_TIMEOUT)
00460 {
00461 mouseButton[0].state |= MBS_HANDLED;
00462 mouseButton[1].state |= MBS_HANDLED;
00463
00464
00465
00466 if (checkTurn(mousedir, false)) return false;
00467
00468 nextanim = Animation::jumpUp;
00469 if (mouselength > 0) {
00470 nextanim = Animation::jump;
00471 }
00472
00473
00474 Animation::Sequence climbanim = Animation::climb72;
00475 while (climbanim >= Animation::climb16)
00476 {
00477 if (avatar->tryAnim(climbanim, direction) ==
00478 Animation::SUCCESS)
00479 {
00480 nextanim = climbanim;
00481 }
00482 climbanim = static_cast<Animation::Sequence>(climbanim-1);
00483 }
00484
00485 if (nextanim == Animation::jump || nextanim == Animation::jumpUp)
00486 {
00487 jump(nextanim, direction);
00488 return false;
00489 }
00490
00491
00492 avatar->accumulateStr(2+nextanim-Animation::climb16);
00493 avatar->accumulateDex(2*(2+nextanim-Animation::climb16));
00494
00495 nextanim = Animation::checkWeapon(nextanim, lastanim);
00496 waitFor(avatar->doAnim(nextanim, direction));
00497 return false;
00498 }
00499 }
00500
00501 if ((!(mouseButton[0].state & MBS_HANDLED) || m0clicked) &&
00502 (mouseButton[1].state & MBS_DOWN))
00503 {
00504 mouseButton[0].state |= MBS_HANDLED;
00505
00506
00507
00508 if (checkTurn(mousedir, false)) return false;
00509
00510 nextanim = Animation::jumpUp;
00511
00512
00513 if (lastanim == Animation::run ||
00514 lastanim == Animation::runningJump) {
00515 pout << "AvatarMover: running jump" << std::endl;
00516 jump(Animation::runningJump, direction);
00517 return false;
00518 } else if (mouselength > 0) {
00519 pout << "AvatarMover: jump" << std::endl;
00520 jump(Animation::jump, direction);
00521 return false;
00522 }
00523 nextanim = Animation::checkWeapon(nextanim, lastanim);
00524 waitFor(avatar->doAnim(nextanim, direction));
00525 return false;
00526
00527
00528 }
00529
00530 if ((mouseButton[1].state & MBS_DOWN) &&
00531 !(mouseButton[1].state & MBS_HANDLED) &&
00532 mouseButton[1].curDown-mouseButton[1].lastDown <= DOUBLE_CLICK_TIMEOUT)
00533 {
00534 Gump* desktopgump = GUIApp::get_instance()->getDesktopGump();
00535 if (desktopgump->TraceObjId(mx,my) == 1) {
00536
00537 mouseButton[1].state |= MBS_HANDLED;
00538 mouseButton[1].lastDown = 0;
00539
00540 avatar->toggleInCombat();
00541 waitFor(avatar->doAnim(Animation::readyWeapon, direction));
00542 return false;
00543 }
00544 }
00545
00546 if ((mouseButton[1].state & MBS_DOWN) &&
00547 (mouseButton[1].state & MBS_HANDLED))
00548 {
00549
00550
00551
00552 nextanim = Animation::step;
00553
00554 if (mouselength == 1)
00555 nextanim = Animation::walk;
00556
00557 if (mouselength == 2)
00558 {
00559 if (lastanim == Animation::run
00560 || lastanim == Animation::runningJump
00561 || lastanim == Animation::walk)
00562 nextanim = Animation::run;
00563 else
00564 nextanim = Animation::walk;
00565 }
00566
00567 step(nextanim, mousedir);
00568 return false;
00569 }
00570
00571 if (m1clicked)
00572 if (checkTurn(mousedir, false)) return true;
00573
00574
00575 if (Kernel::get_instance()->getNumProcesses(1, 0x00F0))
00576 return false;
00577
00578
00579 idleTime = currentIdleTime + 1;
00580
00581
00582 if (lastanim == Animation::lookLeft || lastanim == Animation::lookRight) {
00583 if ((std::rand() % 1500) + 30 < idleTime) {
00584 lastHeadShakeAnim = lastanim;
00585 waitFor(avatar->doAnim(Animation::stand, direction));
00586 idleTime = 0;
00587 return false;
00588 }
00589 } else {
00590 if ((std::rand() % 3000) + 150 < idleTime) {
00591 if (std::rand() % 5 == 0)
00592 nextanim = lastHeadShakeAnim;
00593 else
00594 if (lastHeadShakeAnim == Animation::lookLeft)
00595 nextanim = Animation::lookRight;
00596 else
00597 nextanim = Animation::lookLeft;
00598 waitFor(avatar->doAnim(nextanim, direction));
00599 idleTime = 0;
00600 }
00601 }
00602
00603 return false;
00604 }
00605
00606 void AvatarMoverProcess::step(Animation::Sequence action, int direction,
00607 bool adjusted)
00608 {
00609 assert(action == Animation::step || action == Animation::walk ||
00610 action == Animation::run);
00611
00612 MainActor* avatar = getMainActor();
00613 Animation::Sequence lastanim = avatar->getLastAnim();
00614
00615 Animation::Result res = avatar->tryAnim(action, direction);
00616
00617 int stepdir = direction;
00618
00619 if (res == Animation::FAILURE ||
00620 (action == Animation::step && res == Animation::END_OFF_LAND))
00621 {
00622 int altdir1 = (stepdir + 1)%8;
00623 int altdir2 = (stepdir + 7)%8;
00624
00625 res = avatar->tryAnim(action, altdir1);
00626 if (res == Animation::FAILURE ||
00627 (action == Animation::step && res == Animation::END_OFF_LAND))
00628 {
00629 res = avatar->tryAnim(action, altdir2);
00630 if (res == Animation::FAILURE ||
00631 (action == Animation::step && res == Animation::END_OFF_LAND))
00632 {
00633
00634
00635
00636 if (action == Animation::walk) {
00637 step(Animation::step, direction, true);
00638 return;
00639 } else if (action == Animation::run) {
00640 step(Animation::walk, direction, true);
00641 return;
00642 }
00643
00644 } else {
00645 stepdir = altdir2;
00646 }
00647 } else {
00648 stepdir = altdir1;
00649 }
00650
00651
00652 }
00653
00654 if (action == Animation::step && res == Animation::END_OFF_LAND &&
00655 lastanim != Animation::keepBalance && !adjusted)
00656 {
00657 if (checkTurn(stepdir, false)) return;
00658 waitFor(avatar->doAnim(Animation::keepBalance, stepdir));
00659 return;
00660 }
00661
00662 if (action == Animation::step && res == Animation::FAILURE)
00663 {
00664 action = Animation::stand;
00665 }
00666
00667
00668 bool moving = (action == Animation::run || action == Animation::walk);
00669
00670 if (checkTurn(stepdir, moving)) return;
00671
00672 action = Animation::checkWeapon(action, lastanim);
00673 waitFor(avatar->doAnim(action, stepdir));
00674 }
00675
00676 void AvatarMoverProcess::jump(Animation::Sequence action, int direction)
00677 {
00678 GUIApp* guiapp = GUIApp::get_instance();
00679 MainActor* avatar = getMainActor();
00680 int mx, my;
00681 guiapp->getMouseCoords(mx, my);
00682
00683
00684 if (action == Animation::runningJump)
00685 {
00686 waitFor(avatar->doAnim(action, direction));
00687 return;
00688 }
00689
00690
00691 if ((avatar->getActorFlags() & Actor::ACT_AIRWALK) &&
00692 action == Animation::jump)
00693 {
00694 waitFor(avatar->doAnim(Animation::airwalkJump, direction));
00695 return;
00696 }
00697
00698 bool targeting;
00699 SettingManager::get_instance()->get("targetedjump", targeting);
00700
00701 if (targeting) {
00702 sint32 coords[3];
00703 GameMapGump * gameMap = guiapp->getGameMapGump();
00704
00705 gameMap->ScreenSpaceToGump(mx,my);
00706 ObjId targetId = gameMap->TraceCoordinates(mx,my,coords);
00707 Item * target = getItem(targetId);
00708
00709 sint32 ax,ay,az;
00710 avatar->getCentre(ax,ay,az);
00711
00712 sint32 xrange = ax-coords[0];
00713 if (xrange < 0) xrange = -xrange;
00714 sint32 yrange = ay-coords[1];
00715 if (yrange < 0) yrange = -yrange;
00716 int maxrange = avatar->getStr() * 32;
00717
00718 if (target && target->getShapeInfo()->is_land() &&
00719 xrange < maxrange && yrange < maxrange)
00720 {
00721 Process *p = new TargetedAnimProcess(avatar, Animation::jumpUp,
00722 direction, coords);
00723 waitFor(Kernel::get_instance()->addProcess(p));
00724 return;
00725 }
00726
00727 waitFor(avatar->doAnim(Animation::shakeHead, direction));
00728 } else {
00729 waitFor(avatar->doAnim(Animation::jump, direction));
00730 }
00731 }
00732
00733 void AvatarMoverProcess::turnToDirection(int direction)
00734 {
00735 MainActor* avatar = getMainActor();
00736 bool combatRun = (avatar->getActorFlags() & Actor::ACT_COMBATRUN);
00737 int curdir = avatar->getDir();
00738 int step;
00739 bool combat = avatar->isInCombat() && !combatRun;
00740 Animation::Sequence turnanim;
00741 Animation::Sequence standanim = Animation::stand;
00742
00743 if ((curdir - direction + 8) % 8 < 4) {
00744 step = -1;
00745 turnanim = Animation::lookLeft;
00746 } else {
00747 step = 1;
00748 turnanim = Animation::lookRight;
00749 }
00750
00751 if (combat) {
00752 turnanim = Animation::combatStand;
00753 standanim = Animation::combatStand;
00754 }
00755
00756 ProcId prevpid = 0;
00757
00758 for (int dir = curdir; dir != direction; ) {
00759 ProcId animpid = avatar->doAnim(turnanim, dir);
00760
00761 if (prevpid) {
00762 Process* proc = Kernel::get_instance()->getProcess(animpid);
00763 assert(proc);
00764 proc->waitFor(prevpid);
00765 }
00766
00767 prevpid = animpid;
00768
00769 dir = (dir + step + 8) % 8;
00770 }
00771
00772 ProcId animpid = avatar->doAnim(standanim, direction);
00773
00774 if (prevpid) {
00775 Process* proc = Kernel::get_instance()->getProcess(animpid);
00776 assert(proc);
00777 proc->waitFor(prevpid);
00778 }
00779
00780 waitFor(animpid);
00781 }
00782
00783 bool AvatarMoverProcess::checkTurn(int direction, bool moving)
00784 {
00785 MainActor* avatar = getMainActor();
00786 bool combatRun = (avatar->getActorFlags() & Actor::ACT_COMBATRUN);
00787 int curdir = avatar->getDir();
00788 bool combat = avatar->isInCombat() && !combatRun;
00789 Animation::Sequence lastanim = avatar->getLastAnim();
00790
00791
00792
00793 if (direction != curdir && !(
00794 combat && abs(direction - curdir) == 4))
00795 {
00796 if (moving &&
00797 (lastanim == Animation::walk || lastanim == Animation::run ||
00798 lastanim == Animation::combatStand) &&
00799 (abs(direction - curdir) + 1 % 8 <= 2))
00800 {
00801
00802 return false;
00803 }
00804
00805 if (moving && lastanim == Animation::run) {
00806
00807 waitFor(avatar->doAnim(Animation::walk, curdir));
00808 return true;
00809 }
00810
00811 turnToDirection(direction);
00812 return true;
00813 }
00814
00815 return false;
00816 }
00817
00818 bool AvatarMoverProcess::canAttack()
00819 {
00820 MainActor* avatar = getMainActor();
00821 return (lastframe > lastAttack + (25 - avatar->getDex()));
00822 }
00823
00824 void AvatarMoverProcess::OnMouseDown(int button, int mx, int my)
00825 {
00826 int bid = 0;
00827
00828 switch (button) {
00829 case BUTTON_LEFT:
00830 {
00831 bid = 0;
00832 break;
00833 }
00834 case BUTTON_RIGHT:
00835 {
00836 bid = 1;
00837 break;
00838 }
00839 default:
00840 CANT_HAPPEN_MSG("invalid MouseDown passed to AvatarMoverProcess");
00841 break;
00842 };
00843
00844 mouseButton[bid].lastDown = mouseButton[bid].curDown;
00845 mouseButton[bid].curDown = SDL_GetTicks();
00846 mouseButton[bid].state |= MBS_DOWN;
00847 mouseButton[bid].state &= ~MBS_HANDLED;
00848 }
00849
00850 void AvatarMoverProcess::OnMouseUp(int button)
00851 {
00852 int bid = 0;
00853
00854 if (button == BUTTON_LEFT) {
00855 bid = 0;
00856 } else if (button == BUTTON_RIGHT) {
00857 bid = 1;
00858 } else {
00859 CANT_HAPPEN_MSG("invalid MouseUp passed to AvatarMoverProcess");
00860 }
00861
00862 mouseButton[bid].state &= ~MBS_DOWN;
00863 mouseButton[bid].state &= ~MBS_RELHANDLED;
00864 }
00865
00866
00867 void AvatarMoverProcess::saveData(ODataSource* ods)
00868 {
00869 Process::saveData(ods);
00870
00871 ods->write4(lastAttack);
00872 ods->write4(idleTime);
00873 ods->write2(static_cast<uint8>(lastHeadShakeAnim));
00874 }
00875
00876 bool AvatarMoverProcess::loadData(IDataSource* ids, uint32 version)
00877 {
00878 if (!Process::loadData(ids, version)) return false;
00879
00880 lastAttack = ids->read4();
00881 idleTime = ids->read4();
00882 lastHeadShakeAnim = static_cast<Animation::Sequence>(ids->read2());
00883
00884 return true;
00885 }