void ReactorAI::UpdateAI(const uint32 time_diff) { // update i_victimGuid if i_creature.getVictim() !=0 and changed if(i_creature.getVictim()) i_victimGuid = i_creature.getVictim()->GetGUID(); // i_creature.getVictim() can't be used for check in case stop fighting, i_creature.getVictim() cleared at Unit death etc. if( i_victimGuid ) { if( needToStop() ) { DEBUG_LOG("Creature %u stopped attacking.", i_creature.GetGUIDLow()); stopAttack(); // i_victimGuid == 0 && i_creature.getVictim() == NULL now } else if( i_creature.IsStopped() ) { if( i_creature.isAttackReady() ) { Unit* newtarget = i_creature.SelectHostilTarget(); if(newtarget) AttackStart(newtarget); if(!i_creature.canReachWithAttack(i_creature.getVictim())) return; i_creature.AttackerStateUpdate(i_creature.getVictim()); i_creature.resetAttackTimer(); if ( !i_creature.getVictim() ) return; if( needToStop() ) stopAttack(); } } } }
void LocalPlayer::pickUp(FloorItem *item) { int dx = item->getX() - mX; int dy = item->getY() - mY; if (dx * dx + dy * dy < 4) { MessageOut outMsg(CMSG_ITEM_PICKUP); outMsg.writeInt32(item->getId()); mPickUpTarget = NULL; } else { setDestination(item->getX(), item->getY()); mPickUpTarget = item; stopAttack(); } }
void LocalPlayer::pickUp(FloorItem *item) { int dx = item->getX() - (int) getPosition().x / 32; int dy = item->getY() - (int) getPosition().y / 32; if (dx * dx + dy * dy < 4) { Net::getPlayerHandler()->pickUp(item); mPickUpTarget = NULL; } else { #ifdef TMWSERV_SUPPORT setDestination(item->getX() * 32 + 16, item->getY() * 32 + 16); #else setDestination(item->getX(), item->getY()); #endif mPickUpTarget = item; #ifdef EATHENA_SUPPORT stopAttack(); #endif } }
void LocalPlayer::setMap(Map *map) { Being::setMap(map); stopAttack(); }
void LocalPlayer::attack(Being *target, const bool keep) { mKeepAttacking = keep; if (!target) return; if ((mTarget != target) || !mTarget) setTarget(target); const int dist_x = target->mX - mX; const int dist_y = target->mY - mY; // Must be standing and be within attack range to continue if (target->getType() != Being::NPC && (mAction != STAND || mAttackRange < abs(dist_x) || mAttackRange < abs(dist_y))) return; if (abs(dist_y) >= abs(dist_x)) { if (dist_y > 0) setDirection(DOWN); else setDirection(UP); } else { if (dist_x > 0) setDirection(RIGHT); else setDirection(LEFT); } mWalkTime = tick_time; mTargetTime = tick_time; if (target->getType() != Being::NPC) setAction(ATTACK); if (mEquippedWeapon) { std::string soundFile = mEquippedWeapon->getSound(EQUIP_EVENT_STRIKE); if (!soundFile.empty()) sound.playSfx(soundFile); } else sound.playSfx("sfx/fist-swish.ogg"); MessageOut outMsg(0x0089); outMsg.writeInt32(target->getId()); outMsg.writeInt8(0); if (target->getType() == Being::NPC) { NPC::mTalking = true; mKeepAttacking = false; } if (!mKeepAttacking) stopAttack(); }
void LocalPlayer::logic() { switch (mAction) { case STAND: break; case SIT: break; case DEAD: break; case HURT: break; case WALK: mFrame = (get_elapsed_time(mWalkTime) * 6) / mWalkSpeed; if (mFrame >= 6) nextStep(); break; case ATTACK: int rotation = 0; std::string particleEffect = ""; int frames = 4; if (mEquippedWeapon && mEquippedWeapon->getAttackType() == ACTION_ATTACK_BOW) frames = 5; mFrame = (get_elapsed_time(mWalkTime) * frames) / mAttackSpeed; //attack particle effect if (mEquippedWeapon) particleEffect = mEquippedWeapon->getParticleEffect(); if (!particleEffect.empty() && mParticleEffects && mFrame == 1) { switch (mDirection) { case DOWN: rotation = 0; break; case LEFT: rotation = 90; break; case UP: rotation = 180; break; case RIGHT: rotation = 270; break; default: break; } Particle *p; p = particleEngine->addEffect("graphics/particles/" + particleEffect, 0, 0, rotation); controlParticle(p); } if (mFrame >= frames) nextStep(); break; } // Actions are allowed once per second if (get_elapsed_time(mLastAction) >= 1000) mLastAction = -1; // Remove target if its been on a being for more than a minute if (get_elapsed_time(mTargetTime) >= 60000) { mTargetTime = -1; setTarget(NULL); } if (mTarget) { // Find whether target is in range const int rangeX = abs(mTarget->mX - mX); const int rangeY = abs(mTarget->mY - mY); const int attackRange = getAttackRange(); const int inRange = rangeX > attackRange || rangeY > attackRange ? 1 : 0; mTarget->setTargetAnimation( mTargetCursor[inRange][mTarget->getTargetCursorSize()]); if (mTarget->mAction == DEAD) stopAttack(); if (mKeepAttacking && mTarget) attack(mTarget, true); } Being::logic(); }
void LocalPlayer::attack(Being *target, bool keep) { #ifdef TMWSERV_SUPPORT if (mLastAction != -1) return; // Can only attack when standing still if (mAction != STAND && mAction != ATTACK) return; #endif mKeepAttacking = keep; if (!target || target->getType() == Being::NPC) return; if (mTarget != target || !mTarget) { mLastTarget = -1; setTarget(target); } #ifdef TMWSERV_SUPPORT Vector plaPos = this->getPosition(); Vector tarPos = mTarget->getPosition(); int dist_x = plaPos.x - tarPos.x; int dist_y = plaPos.y - tarPos.y; #else int dist_x = target->getTileX() - getTileX(); int dist_y = target->getTileY() - getTileY(); // Must be standing to attack if (mAction != STAND) return; #endif #ifdef TMWSERV_SUPPORT if (abs(dist_y) >= abs(dist_x)) { if (dist_y < 0) setDirection(DOWN); else setDirection(UP); } else { if (dist_x < 0) setDirection(RIGHT); else setDirection(LEFT); } #else if (abs(dist_y) >= abs(dist_x)) { if (dist_y > 0) setDirection(DOWN); else setDirection(UP); } else { if (dist_x > 0) setDirection(RIGHT); else setDirection(LEFT); } #endif #ifdef TMWSERV_SUPPORT mLastAction = tick_time; #else mWalkTime = tick_time; mTargetTime = tick_time; #endif setAction(ATTACK); if (mEquippedWeapon) { std::string soundFile = mEquippedWeapon->getSound(EQUIP_EVENT_STRIKE); if (!soundFile.empty()) sound.playSfx(soundFile); } else { sound.playSfx("sfx/fist-swish.ogg"); } Net::getPlayerHandler()->attack(target->getId()); #ifdef EATHENA_SUPPORT if (!keep) stopAttack(); #endif }
void LocalPlayer::logic() { // Actions are allowed once per second if (get_elapsed_time(mLastAction) >= 1000) mLastAction = -1; // Show XP messages if (!mMessages.empty()) { if (mMessageTime == 0) { //const Vector &pos = getPosition(); MessagePair info = mMessages.front(); particleEngine->addTextRiseFadeOutEffect( info.first, /*(int) pos.x, (int) pos.y - 48,*/ getPixelX(), getPixelY() - 48, &guiPalette->getColor(info.second), gui->getInfoParticleFont(), true); mMessages.pop_front(); mMessageTime = 30; } mMessageTime--; } if ((mSpecialRechargeUpdateNeeded%11) == 0) { mSpecialRechargeUpdateNeeded = 0; for (std::map<int, Special>::iterator i = mSpecials.begin(); i != mSpecials.end(); i++) { i->second.currentMana += i->second.recharge; if (i->second.currentMana > i->second.neededMana) { i->second.currentMana = i->second.neededMana; } } } mSpecialRechargeUpdateNeeded++; #ifdef EATHENA_SUPPORT // Targeting allowed 4 times a second if (get_elapsed_time(mLastTarget) >= 250) mLastTarget = -1; // Remove target if its been on a being for more than a minute if (get_elapsed_time(mTargetTime) >= 60000) { mTargetTime = -1; setTarget(NULL); mLastTarget = -1; } #endif if (mTarget) { if (mTarget->getType() == Being::NPC) { // NPCs are always in range mTarget->setTargetAnimation( mTargetCursor[0][mTarget->getTargetCursorSize()]); } else { #ifdef TMWSERV_SUPPORT // Find whether target is in range const int rangeX = abs(mTarget->getPosition().x - getPosition().x); const int rangeY = abs(mTarget->getPosition().y - getPosition().y); #else // Find whether target is in range const int rangeX = abs(mTarget->getTileX() - getTileX()); const int rangeY = abs(mTarget->getTileY() - getTileY()); #endif const int attackRange = getAttackRange(); const int inRange = rangeX > attackRange || rangeY > attackRange ? 1 : 0; mTarget->setTargetAnimation( mTargetCursor[inRange][mTarget->getTargetCursorSize()]); if (mTarget->mAction == DEAD) stopAttack(); if (mKeepAttacking && mTarget) attack(mTarget, true); } } Player::logic(); }
void AutoAttackComponent::didTargetDie() { stopAttack(); }