示例#1
0
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();
            }
        }
    }
}
示例#2
0
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();
    }
}
示例#3
0
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
    }
}
示例#4
0
void LocalPlayer::setMap(Map *map)
{
    Being::setMap(map);
    stopAttack();
}
示例#5
0
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();
}
示例#6
0
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();
}
示例#7
0
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
}
示例#8
0
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();
}
示例#9
0
void AutoAttackComponent::didTargetDie()
{
    stopAttack();
}