Exemplo n.º 1
0
void PlayerHandler::handleMessage(MessageIn *msg)
{
    const int numOfAttr = LocalPlayer::LUK - LocalPlayer::STR;

    switch (msg->getId())
    {
        case SMSG_WALK_RESPONSE:
            /*
             * This client assumes that all walk messages succeed,
             * and that the server will send a correction notice
             * otherwise.
             */
            break;

        case SMSG_PLAYER_WARP:
            {
                std::string mapPath = msg->readString(16);
                bool nearby;
                Uint16 x = msg->readInt16();
                Uint16 y = msg->readInt16();

                logger->log("Warping to %s (%d, %d)", mapPath.c_str(), x, y);

                /*
                 * We must clear the local player's target *before* the call
                 * to changeMap, as it deletes all beings.
                 */
                player_node->stopAttack();

                nearby = (viewport->getMapName() == mapPath);

                // Switch the actual map, deleting the previous one if necessary
                viewport->changeMap(mapPath);

                current_npc = 0;

                int scrollOffsetX = 0;
                int scrollOffsetY = 0;

                /* Scroll if neccessary */
                if (!nearby
                    || (abs(x - player_node->mX) > MAP_TELEPORT_SCROLL_DISTANCE)
                    || (abs(y - player_node->mY) > MAP_TELEPORT_SCROLL_DISTANCE))
                {
                    scrollOffsetX = x - player_node->mX;
                    scrollOffsetY = y - player_node->mY;
                }

                player_node->setAction(Being::STAND);
                player_node->mFrame = 0;
                player_node->mX = x;
                player_node->mY = y;

                logger->log("Adjust scrolling by (%d, %d) tiles", scrollOffsetX,
                            scrollOffsetY);

                viewport->scrollBy(scrollOffsetX, scrollOffsetY);
            }
            break;

        case SMSG_PLAYER_STAT_UPDATE_1:
            {
                int type = msg->readInt16();
                int value = msg->readInt32();

                switch (type)
                {
                    case 0x0000: player_node->setWalkSpeed(value); break;
                    case 0x0005: player_node->mHp = value; break;
                    case 0x0006: player_node->mMaxHp = value; break;
                    case 0x0007: player_node->mMp = value; break;
                    case 0x0008: player_node->mMaxMp = value; break;
                    case 0x0009:
                                 player_node->mStatsPointsToAttribute = value;
                                 break;
                    case 0x000b: player_node->mLevel = value; break;
                    case 0x000c:
                                 player_node->mSkillPoint = value;
                                 skillDialog->update();
                                 break;
                    case 0x0018:
                                 if (value >= player_node->mMaxWeight / 2 &&
                                     player_node->mTotalWeight <
                                     player_node->mMaxWeight / 2)
                                 {
                                     weightNotice = new OkDialog(_("Message"),
                                             _("You are carrying more than "
                                               "half your weight. You are "
                                               "unable to regain health."));
                                     weightNotice->addActionListener(
                                             &weightListener);
                                 }
                                 player_node->mTotalWeight = value;
                                 break;
                    case 0x0019: player_node->mMaxWeight = value; break;
                    case 0x0029: player_node->ATK = value; break;
                    case 0x002b: player_node->MATK = value; break;
                    case 0x002d: player_node->DEF = value; break;
                    case 0x002e: player_node->DEF_BONUS = value; break;
                    case 0x002f: player_node->MDEF = value; break;
                    case 0x0031: player_node->HIT = value; break;
                    case 0x0032: player_node->FLEE = value; break;
                    case 0x0035: player_node->mAttackSpeed = value; break;
                    case 0x0037: player_node->mJobLevel = value; break;
                }

                if (player_node->mHp == 0 && !deathNotice)
                {
                    deathNotice = new OkDialog(_("Message"),
                                               randomDeathMessage());
                    deathNotice->addActionListener(&deathListener);
                    player_node->setAction(Being::DEAD);
                }
            }
            break;

        case SMSG_PLAYER_STAT_UPDATE_2:
            switch (msg->readInt16())
            {
                case 0x0001:
                    player_node->setXp(msg->readInt32());
                    break;
                case 0x0002:
                    player_node->mJobXp = msg->readInt32();
                    break;
                case 0x0014:
                    {
                        Uint32 curGp = player_node->mGp;
                        player_node->mGp = msg->readInt32();
                        if (player_node->mGp > curGp)
                            chatWindow->chatLog(strprintf(
                                _("You picked up %d GP"),
                                player_node->mGp - curGp), BY_SERVER);
                    }
                    break;
                case 0x0016:
                    player_node->mXpForNextLevel = msg->readInt32();
                    break;
                case 0x0017:
                    player_node->mJobXpForNextLevel = msg->readInt32();
                    break;
            }
            break;

        case SMSG_PLAYER_STAT_UPDATE_3:
            {
                const int type = msg->readInt32();
                const int base = msg->readInt32();
                const int bonus = msg->readInt32();
                const int total = base + bonus;
                const int index = type - LocalPlayer::STR;

                if (index >=0 && index <= numOfAttr)
                    player_node->mAttr[index] = total;
            }
            break;

        case SMSG_PLAYER_STAT_UPDATE_4:
            {
                const int type = msg->readInt16();
                const int fail = msg->readInt8();
                const int value = msg->readInt8();
                const int index = type - LocalPlayer::STR;

                if (fail != 1)
                    break;

                if (index >=0 && index <= numOfAttr)
                    player_node->mAttr[index] = value;
            }
            break;

        // Updates stats and status points
        case SMSG_PLAYER_STAT_UPDATE_5:
            player_node->mStatsPointsToAttribute = msg->readInt16();

            for (int i = LocalPlayer::STR; i <= LocalPlayer::LUK; i++)
            {
                const int index = i - LocalPlayer::STR;

                player_node->mAttr[index] = msg->readInt8();
                player_node->mAttrUp[index] = msg->readInt8();
            }

            player_node->ATK       = msg->readInt16();  // ATK
            player_node->ATK_BONUS  = msg->readInt16();  // ATK bonus
            player_node->MATK      = msg->readInt16();  // MATK max
            player_node->MATK_BONUS = msg->readInt16();  // MATK min
            player_node->DEF       = msg->readInt16();  // DEF
            player_node->DEF_BONUS  = msg->readInt16();  // DEF bonus
            player_node->MDEF      = msg->readInt16();  // MDEF
            player_node->MDEF_BONUS = msg->readInt16();  // MDEF bonus
            player_node->HIT       = msg->readInt16();  // HIT
            player_node->FLEE      = msg->readInt16();  // FLEE
            player_node->FLEE_BONUS = msg->readInt16();  // FLEE bonus
            msg->readInt16();  // critical
            msg->readInt16();  // unknown
            break;

        case SMSG_PLAYER_STAT_UPDATE_6:
            {
                const int index = msg->readInt16() - 0x0020;
                const int attr = msg->readInt8();

                if (index >=0 && index <= numOfAttr)
                    player_node->mAttrUp[index] = attr;
            }

            break;

        case SMSG_PLAYER_ARROW_MESSAGE:
            {
                const int type = msg->readInt16();

                switch (type)
                {
                    case 0:
                        chatWindow->chatLog(_("Equip arrows first."),
                                             BY_SERVER);
                        break;
                    default:
                        logger->log("0x013b: Unhandled message %i", type);
                        break;
                }
            }
            break;
    }
}
Exemplo n.º 2
0
void PlayerHandler::handleMessage(MessageIn &msg)
{
    switch (msg.getId())
    {
    case SMSG_WALK_RESPONSE:
        /*
         * This client assumes that all walk messages succeed,
         * and that the server will send a correction notice
         * otherwise.
         */
        break;

    case SMSG_PLAYER_WARP:
    {
        std::string mapPath = msg.readString(16);
        bool nearby;
        Uint16 x = msg.readInt16();
        Uint16 y = msg.readInt16();

        logger->log("Warping to %s (%d, %d)", mapPath.c_str(), x, y);

        /*
         * We must clear the local player's target *before* the call
         * to changeMap, as it deletes all beings.
         */
        player_node->stopAttack();

        nearby = (engine->getCurrentMapName() == mapPath);

        // Switch the actual map, deleting the previous one if necessary
        mapPath = mapPath.substr(0, mapPath.rfind("."));
        engine->changeMap(mapPath);

        float scrollOffsetX = 0.0f;
        float scrollOffsetY = 0.0f;

        /* Scroll if neccessary */
        if (!nearby
                || (abs(x - player_node->getTileX()) > MAP_TELEPORT_SCROLL_DISTANCE)
                || (abs(y - player_node->getTileY()) > MAP_TELEPORT_SCROLL_DISTANCE))
        {
            scrollOffsetX = (x - player_node->getTileX()) * 32;
            scrollOffsetY = (y - player_node->getTileY()) * 32;
        }

        player_node->setAction(Being::STAND);
        player_node->mFrame = 0;
        player_node->setTileCoords(x, y);

        logger->log("Adjust scrolling by %d:%d", (int) scrollOffsetX,
                    (int) scrollOffsetY);

        viewport->scrollBy(scrollOffsetX, scrollOffsetY);
    }
    break;

    case SMSG_PLAYER_STAT_UPDATE_1:
    {
        int type = msg.readInt16();
        int value = msg.readInt32();

        switch (type)
        {
        case 0x0000:
            player_node->setWalkSpeed(value);
            break;
        case 0x0004:
            break; // manner
        case 0x0005:
            player_node->setHp(value);
            break;
        case 0x0006:
            player_node->setMaxHp(value);
            break;
        case 0x0007:
            player_node->setMP(value);
            break;
        case 0x0008:
            player_node->setMaxMP(value);
            break;
        case 0x0009:
            player_node->setCharacterPoints(value);
            break;
        case 0x000b:
            player_node->setLevel(value);
            break;
        case 0x000c:
            player_node->setSkillPoints(value);
            break;
        case 0x0018:
            if (value >= player_node->getMaxWeight() / 2 &&
                    player_node->getTotalWeight() <
                    player_node->getMaxWeight() / 2)
            {
                weightNotice = new OkDialog(_("Message"),
                                            _("You are carrying more than "
                                              "half your weight. You are "
                                              "unable to regain health."));
                weightNotice->addActionListener(
                    &weightListener);
            }
            player_node->setTotalWeight(value);
            break;
        case 0x0019:
            player_node->setMaxWeight(value);
            break;

        case 0x0029:
            player_node->setAttributeEffective(ATK, value
                                               + ATTR_BONUS(ATK));
            player_node->setAttributeBase(ATK, value);
            break;
        case 0x002a:
            value += player_node->getAttributeBase(ATK);
            player_node->setAttributeEffective(ATK, value);
            break;

        case 0x002b:
            player_node->setAttributeEffective(MATK, value
                                               + ATTR_BONUS(MATK));
            player_node->setAttributeBase(MATK, value);
            statusWindow->update(StatusWindow::MP);
            break;
        case 0x002c:
            value += player_node->getAttributeBase(MATK);
            player_node->setAttributeEffective(MATK, value);
            statusWindow->update(StatusWindow::MP);
            break;
        case 0x002d:
            player_node->setAttributeEffective(DEF, value
                                               + ATTR_BONUS(DEF));
            player_node->setAttributeBase(DEF, value);
            break;
        case 0x002e:
            value += player_node->getAttributeBase(DEF);
            player_node->setAttributeEffective(DEF, value);
            break;

        case 0x002f:
            player_node->setAttributeEffective(MDEF, value
                                               + ATTR_BONUS(MDEF));
            player_node->setAttributeBase(MDEF, value);
            break;
        case 0x0030:
            value += player_node->getAttributeBase(MDEF);
            player_node->setAttributeEffective(MDEF, value);
            break;

        case 0x0031:
            player_node->setAttributeBase(HIT, value);
            player_node->setAttributeEffective(HIT, value);
            break;

        case 0x0032:
            player_node->setAttributeEffective(FLEE, value
                                               + ATTR_BONUS(FLEE));
            player_node->setAttributeBase(FLEE, value);
            break;
        case 0x0033:
            value += player_node->getAttributeBase(FLEE);
            player_node->setAttributeEffective(FLEE, value);
            break;

        case 0x0034:
            player_node->setAttributeBase(CRIT, value);
            player_node->setAttributeEffective(CRIT, value);
            break;

        case 0x0035:
            player_node->mAttackSpeed = value;
            break;
        case 0x0037:
            player_node->setAttributeBase(JOB, value);
            player_node->setAttributeEffective(JOB, value);
            break;
        case 500:
            player_node->setGMLevel(value);
            break;
        }

        if (player_node->getHp() == 0 && !deathNotice)
        {
            deathNotice = new OkDialog(_("Message"),
                                       randomDeathMessage());
            deathNotice->addActionListener(&deathListener);
            player_node->setAction(Being::DEAD);
        }
    }
    break;

    case SMSG_PLAYER_STAT_UPDATE_2:
        switch (msg.readInt16()) {
        case 0x0001:
            player_node->setExp(msg.readInt32());
            break;
        case 0x0002:
            player_node->setExperience(JOB, msg.readInt32(),
                                       player_node->getExperience(JOB).second);
            break;
        case 0x0014: {
            int curGp = player_node->getMoney();
            player_node->setMoney(msg.readInt32());
            if (player_node->getMoney() > curGp)
                localChatTab->chatLog(strprintf(_("You picked up "
                                                  "%s."),
                                                Units::formatCurrency(player_node->getMoney()
                                                        - curGp).c_str()), BY_SERVER);
        }
        break;
        case 0x0016:
            player_node->setExpNeeded(msg.readInt32());
            break;
        case 0x0017:
            player_node->setExperience(JOB,
                                       player_node->getExperience(JOB).first,
                                       msg.readInt32());
            break;
        }
        break;

    case SMSG_PLAYER_STAT_UPDATE_3: // Update a base attribute
    {
        int type = msg.readInt32();
        int base = msg.readInt32();
        int bonus = msg.readInt32();

        player_node->setAttributeBase(type, base);
        player_node->setAttributeEffective(type, base + bonus);
    }
    break;

    case SMSG_PLAYER_STAT_UPDATE_4: // Attribute increase ack
    {
        int type = msg.readInt16();
        int fail = msg.readInt8();
        int value = msg.readInt8();

        if (fail != 1)
            break;

        int bonus = ATTR_BONUS(type);

        player_node->setAttributeBase(type, value);
        player_node->setAttributeEffective(type, value + bonus);
    }
    break;

    // Updates stats and status points
    case SMSG_PLAYER_STAT_UPDATE_5:
        player_node->setCharacterPoints(msg.readInt16());

        {
            int val = msg.readInt8();
            player_node->setAttributeEffective(STR, val + ATTR_BONUS(STR));
            player_node->setAttributeBase(STR, val);
            statusWindow->setPointsNeeded(STR, msg.readInt8());

            val = msg.readInt8();
            player_node->setAttributeEffective(AGI, val + ATTR_BONUS(AGI));
            player_node->setAttributeBase(AGI, val);
            statusWindow->setPointsNeeded(AGI, msg.readInt8());

            val = msg.readInt8();
            player_node->setAttributeEffective(VIT, val + ATTR_BONUS(VIT));
            player_node->setAttributeBase(VIT, val);
            statusWindow->setPointsNeeded(VIT, msg.readInt8());

            val = msg.readInt8();
            player_node->setAttributeEffective(INTT, val + ATTR_BONUS(INTT));
            player_node->setAttributeBase(INTT, val);
            statusWindow->setPointsNeeded(INTT, msg.readInt8());

            val = msg.readInt8();
            player_node->setAttributeEffective(DEX, val + ATTR_BONUS(DEX));
            player_node->setAttributeBase(DEX, val);
            statusWindow->setPointsNeeded(DEX, msg.readInt8());

            val = msg.readInt8();
            player_node->setAttributeEffective(LUK, val + ATTR_BONUS(LUK));
            player_node->setAttributeBase(LUK, val);
            statusWindow->setPointsNeeded(LUK, msg.readInt8());

            val = msg.readInt16(); // ATK
            player_node->setAttributeBase(ATK, val);
            val += msg.readInt16();  // ATK bonus
            player_node->setAttributeEffective(ATK, val);

            val = msg.readInt16(); // MATK
            player_node->setAttributeBase(MATK, val);
            val += msg.readInt16();  // MATK bonus
            player_node->setAttributeEffective(MATK, val);
            statusWindow->update(StatusWindow::MP);

            val = msg.readInt16(); // DEF
            player_node->setAttributeBase(DEF, val);
            val += msg.readInt16();  // DEF bonus
            player_node->setAttributeEffective(DEF, val);

            val = msg.readInt16(); // MDEF
            player_node->setAttributeBase(MDEF, val);
            val += msg.readInt16();  // MDEF bonus
            player_node->setAttributeEffective(MDEF, val);

            val = msg.readInt16(); // HIT
            player_node->setAttributeBase(ATK, val);
            player_node->setAttributeEffective(ATK, val);

            val = msg.readInt16(); // FLEE
            player_node->setAttributeBase(FLEE, val);
            val += msg.readInt16();  // FLEE bonus
            player_node->setAttributeEffective(FLEE, val);

            val = msg.readInt16();
            player_node->setAttributeBase(CRIT, val);
            player_node->setAttributeEffective(CRIT, val);
        }

        msg.readInt16();  // manner
        break;

    case SMSG_PLAYER_STAT_UPDATE_6:
        switch (msg.readInt16()) {
        case 0x0020:
            statusWindow->setPointsNeeded(STR, msg.readInt8());
            break;
        case 0x0021:
            statusWindow->setPointsNeeded(AGI, msg.readInt8());
            break;
        case 0x0022:
            statusWindow->setPointsNeeded(VIT, msg.readInt8());
            break;
        case 0x0023:
            statusWindow->setPointsNeeded(INTT, msg.readInt8());
            break;
        case 0x0024:
            statusWindow->setPointsNeeded(DEX, msg.readInt8());
            break;
        case 0x0025:
            statusWindow->setPointsNeeded(LUK, msg.readInt8());
            break;
        }
        break;

    case SMSG_PLAYER_ARROW_MESSAGE:
    {
        int type = msg.readInt16();

        switch (type) {
        case 0:
            localChatTab->chatLog(_("Equip arrows first."),
                                  BY_SERVER);
            break;
        default:
            logger->log("0x013b: Unhandled message %i", type);
            break;
        }
    }
    break;
    }
}
Exemplo n.º 3
0
void PlayerHandler::processPlayerStatUpdate1(Net::MessageIn &msg)
{
    int type = msg.readInt16();
    int value = msg.readInt32();
    if (!player_node)
        return;

    switch (type)
    {
        case 0x0000:
            player_node->setWalkSpeed(Vector(static_cast<float>(
                value), static_cast<float>(value), 0));
            PlayerInfo::setStatBase(WALK_SPEED, value);
            PlayerInfo::setStatMod(WALK_SPEED, 0);
        break;
        case 0x0004: break; // manner
        case 0x0005:
            PlayerInfo::setAttribute(HP, value);
            if (player_node->isInParty() && Party::getParty(1))
            {
                PartyMember *m = Party::getParty(1)
                    ->getMember(player_node->getId());
                if (m)
                {
                    m->setHp(value);
                    m->setMaxHp(PlayerInfo::getAttribute(MAX_HP));
                }
            }
            break;
        case 0x0006:
            PlayerInfo::setAttribute(MAX_HP, value);

            if (player_node->isInParty() && Party::getParty(1))
            {
                PartyMember *m = Party::getParty(1)->getMember(
                    player_node->getId());
                if (m)
                {
                    m->setHp(PlayerInfo::getAttribute(HP));
                    m->setMaxHp(value);
                }
            }
            break;
        case 0x0007:
            PlayerInfo::setAttribute(MP, value);
            break;
        case 0x0008:
            PlayerInfo::setAttribute(MAX_MP, value);
            break;
        case 0x0009:
            PlayerInfo::setAttribute(CHAR_POINTS, value);
            break;
        case 0x000b:
            PlayerInfo::setAttribute(LEVEL, value);
            if (player_node)
            {
                player_node->setLevel(value);
                player_node->updateName();
            }
            break;
        case 0x000c:
            PlayerInfo::setAttribute(SKILL_POINTS, value);
            if (skillDialog)
                skillDialog->update();
            break;
        case 0x0018:
            if (!weightNotice)
            {
                const int max = PlayerInfo::getAttribute(MAX_WEIGHT) / 2;
                const int total = PlayerInfo::getAttribute(TOTAL_WEIGHT);
                if (value >= max && total < max)
                {
                    weightNoticeTime = cur_time + 5;
                    weightNotice = new OkDialog(_("Message"),
                        _("You are carrying more than "
                        "half your weight. You are "
                        "unable to regain health."), DIALOG_OK, false);
                    weightNotice->addActionListener(
                        &weightListener);
                }
                else if (value < max && total >= max)
                {
                    weightNoticeTime = cur_time + 5;
                    weightNotice = new OkDialog(_("Message"),
                        _("You are carrying less than "
                        "half your weight. You "
                        "can regain health."), DIALOG_OK, false);
                    weightNotice->addActionListener(
                        &weightListener);
                }
            }
            PlayerInfo::setAttribute(TOTAL_WEIGHT, value);
            break;
        case 0x0019:
            PlayerInfo::setAttribute(MAX_WEIGHT, value);
            break;

        case 0x0029:
            PlayerInfo::setStatBase(EA_ATK, value);
            PlayerInfo::updateAttrs();
            break;
        case 0x002a:
            PlayerInfo::setStatMod(EA_ATK, value);
            PlayerInfo::updateAttrs();
            break;

        case 0x002b:
            PlayerInfo::setStatBase(EA_MATK, value);
            break;
        case 0x002c:
            PlayerInfo::setStatMod(EA_MATK, value);
            break;

        case 0x002d:
            PlayerInfo::setStatBase(EA_DEF, value);
            break;
        case 0x002e:
            PlayerInfo::setStatMod(EA_DEF, value);
            break;

        case 0x002f:
            PlayerInfo::setStatBase(EA_MDEF, value);
            break;
        case 0x0030:
            PlayerInfo::setStatMod(EA_MDEF, value);
            break;

        case 0x0031:
            PlayerInfo::setStatBase(EA_HIT, value);
            break;

        case 0x0032:
            PlayerInfo::setStatBase(EA_FLEE, value);
            break;
        case 0x0033:
            PlayerInfo::setStatMod(EA_FLEE, value);
            break;

        case 0x0034:
            PlayerInfo::setStatBase(EA_CRIT, value);
            break;

        case 0x0035:
            player_node->setAttackSpeed(value);
            PlayerInfo::setStatBase(ATTACK_DELAY, value);
            PlayerInfo::setStatMod(ATTACK_DELAY, 0);
            PlayerInfo::updateAttrs();
            break;

        case 0x0037:
            PlayerInfo::setStatBase(EA_JOB, value);
            break;

        case 500:
            player_node->setGMLevel(value);
            break;

        default:
            logger->log("QQQQ PLAYER_STAT_UPDATE_1 "
                        + toString(type) + "," + toString(value));
            break;
    }

    if (PlayerInfo::getAttribute(HP) == 0 && !deathNotice)
    {
        deathNotice = new OkDialog(_("Message"),
            randomDeathMessage(), DIALOG_OK, false);
        deathNotice->addActionListener(&deathListener);
        player_node->setAction(Being::DEAD);
    }
}
Exemplo n.º 4
0
void PlayerHandler::handleMessage(Net::MessageIn &msg)
{
    if (!player_node)
        return;

    switch (msg.getId())
    {
        case SMSG_WALK_RESPONSE:
            /*
             * This client assumes that all walk messages succeed,
             * and that the server will send a correction notice
             * otherwise.
             */
            break;

        case SMSG_PLAYER_WARP:
            {
                std::string mapPath = msg.readString(16);
                int x = msg.readInt16();
                int y = msg.readInt16();

                logger->log("Warping to %s (%d, %d)", mapPath.c_str(), x, y);

                /*
                 * We must clear the local player's target *before* the call
                 * to changeMap, as it deletes all beings.
                 */
                player_node->stopAttack();

                Game *game = Game::instance();

                const std::string &currentMapName = game->getCurrentMapName();
                bool sameMap = (currentMapName == mapPath);

                // Switch the actual map, deleting the previous one if necessary
                mapPath = mapPath.substr(0, mapPath.rfind("."));
                game->changeMap(mapPath);

                float scrollOffsetX = 0.0f;
                float scrollOffsetY = 0.0f;

                /* Scroll if necessary */
                Map *map = game->getCurrentMap();
                int tileX = player_node->getTileX();
                int tileY = player_node->getTileY();
                if (!sameMap
                    || (abs(x - tileX) > MAP_TELEPORT_SCROLL_DISTANCE)
                    || (abs(y - tileY) > MAP_TELEPORT_SCROLL_DISTANCE))
                {
                    scrollOffsetX = (x - tileX) * map->getTileWidth();
                    scrollOffsetY = (y - tileY) * map->getTileHeight();
                }

                player_node->setAction(Being::STAND);
                Vector pos = map->getTileCenter(x, y);
                player_node->setPosition(pos);
                // Stop movement
                player_node->setDestination(pos.x, pos.y);

                logger->log("Adjust scrolling by %d:%d", (int) scrollOffsetX,
                           (int) scrollOffsetY);

                viewport->scrollBy(scrollOffsetX, scrollOffsetY);
            }
            break;

        case SMSG_PLAYER_STAT_UPDATE_1:
            {
                if (!player_node)
                    break;
                int type = msg.readInt16();
                int value = msg.readInt32();

                switch (type)
                {
                    case 0x0000:
                      player_node->setMoveSpeed(Vector(value / 10,
                                                       value / 10, 0));
                    break;
                    case 0x0004: break; // manner
                    case 0x0005: PlayerInfo::setAttribute(HP, value); break;
                    case 0x0006: PlayerInfo::setAttribute(MAX_HP, value); break;
                    case 0x0007: PlayerInfo::setAttribute(MP, value); break;
                    case 0x0008: PlayerInfo::setAttribute(MAX_MP, value); break;
                    case 0x0009: PlayerInfo::setAttribute(CHAR_POINTS, value); break;
                    case 0x000b: PlayerInfo::setAttribute(LEVEL, value); break;
                    case 0x000c: PlayerInfo::setAttribute(SKILL_POINTS, value); break;
                    case 0x0018:
                                 if (value >= PlayerInfo::getAttribute(MAX_WEIGHT) / 2 &&
                                         PlayerInfo::getAttribute(TOTAL_WEIGHT) <
                                         PlayerInfo::getAttribute(MAX_WEIGHT) / 2)
                                 {
                                     weightNotice = new OkDialog(_("Message"),
                                             _("You are carrying more than "
                                               "half your weight. You are "
                                               "unable to regain health."));
                                     weightNotice->addActionListener(
                                             &weightListener);
                                 }
                                 PlayerInfo::setAttribute(TOTAL_WEIGHT, value);
                                 break;
                    case 0x0019: PlayerInfo::setAttribute(MAX_WEIGHT, value); break;

                    case 0x0029: PlayerInfo::setStatBase(ATK, value); break;
                    case 0x002a: PlayerInfo::setStatMod(ATK, value); break;

                    case 0x002b: PlayerInfo::setStatBase(MATK, value); break;
                    case 0x002c: PlayerInfo::setStatMod(MATK, value); break;

                    case 0x002d: PlayerInfo::setStatBase(DEF, value); break;
                    case 0x002e: PlayerInfo::setStatMod(DEF, value); break;

                    case 0x002f: PlayerInfo::setStatBase(MDEF, value); break;
                    case 0x0030: PlayerInfo::setStatMod(MDEF, value); break;

                    case 0x0031: PlayerInfo::setStatBase(HIT, value); break;

                    case 0x0032: PlayerInfo::setStatBase(FLEE, value); break;
                    case 0x0033: PlayerInfo::setStatMod(FLEE, value); break;

                    case 0x0034: PlayerInfo::setStatBase(CRIT, value); break;

                    case 0x0035: player_node->setAttackSpeed(value); break;

                    case 0x0037: PlayerInfo::setStatBase(JOB, value); break;

                    case 500: player_node->setGMLevel(value); break;
                }

                if (PlayerInfo::getAttribute(HP) == 0 && !deathNotice)
                {
                    viewport->shakeScreen(100);
                    deathNotice = new OkDialog(_("Message"),
                                               randomDeathMessage(),
                                               false);
                    deathNotice->addActionListener(&deathListener);
                    player_node->setAction(Being::DEAD);
                }
            }

            if (statusWindow)
                statusWindow->updateAttrs();

            break;

        case SMSG_PLAYER_STAT_UPDATE_2:
            switch (msg.readInt16())
            {
                case 0x0001:
                    PlayerInfo::setAttribute(EXP, msg.readInt32());
                    break;
                case 0x0002:
                    PlayerInfo::setStatExperience(JOB, msg.readInt32(),
                                                  PlayerInfo::getStatExperience(JOB).second);
                    break;

                case 0x0014:
                    {
                        int oldMoney = PlayerInfo::getAttribute(MONEY);
                        int newMoney = msg.readInt32();
                        std::string money = Units::formatCurrency(
                                            newMoney - oldMoney);
                        PlayerInfo::setAttribute(MONEY, newMoney);
                        if (newMoney > oldMoney)
                        {
                            if (config.getBoolValue("showpickupchat"))
                                SERVER_NOTICE(strprintf(_("You picked up %s."),
                                            Units::formatCurrency(newMoney -
                                            oldMoney).c_str()))
                            if (config.getBoolValue("showpickupparticle"))
                                player_node->addMessageToQueue(money,
                                                      UserPalette::PICKUP_INFO);
                        }
                    }
                    break;
                case 0x0016:
                    PlayerInfo::setAttribute(EXP_NEEDED, msg.readInt32());
                    break;
                case 0x0017:
                    PlayerInfo::setStatExperience(JOB,
                                                  PlayerInfo::getStatExperience(JOB).first,
                                                  msg.readInt32());
                    break;
            }
            break;

        case SMSG_PLAYER_STAT_UPDATE_3: // Update a base attribute
            {
                int type = msg.readInt32();
                int base = msg.readInt32();
                int bonus = msg.readInt32();

                PlayerInfo::setStatBase(type, base, false);
                PlayerInfo::setStatMod(type, bonus);
            }
            break;

        case SMSG_PLAYER_STAT_UPDATE_4: // Attribute increase ack
            {
                int type = msg.readInt16();
                int ok = msg.readInt8();
                int value = msg.readInt8();

                if (ok != 1)
                {
                    SERVER_NOTICE(_("Cannot raise skill!"))
                }

                PlayerInfo::setStatBase(type, value);
            }
            break;

        // Updates stats and status points
        case SMSG_PLAYER_STAT_UPDATE_5:
            PlayerInfo::setAttribute(CHAR_POINTS, msg.readInt16());

            {
                int val = msg.readInt8();
                PlayerInfo::setStatBase(STR, val);
                if (val >= 99)
                {
                    statusWindow->setPointsNeeded(STR, 0);
                    msg.readInt8();
                }
                else
                {
                    statusWindow->setPointsNeeded(STR, msg.readInt8());
                }

                val = msg.readInt8();
                PlayerInfo::setStatBase(AGI, val);
                if (val >= 99)
                {
                    statusWindow->setPointsNeeded(AGI, 0);
                    msg.readInt8();
                }
                else
                {
                    statusWindow->setPointsNeeded(AGI, msg.readInt8());
                }

                val = msg.readInt8();
                PlayerInfo::setStatBase(VIT, val);
                if (val >= 99)
                {
                    statusWindow->setPointsNeeded(VIT, 0);
                    msg.readInt8();
                }
                else
                {
                    statusWindow->setPointsNeeded(VIT, msg.readInt8());
                }

                val = msg.readInt8();
                PlayerInfo::setStatBase(INT, val);
                if (val >= 99)
                {
                    statusWindow->setPointsNeeded(INT, 0);
                    msg.readInt8();
                }
                else
                {
                    statusWindow->setPointsNeeded(INT, msg.readInt8());
                }

                val = msg.readInt8();
                PlayerInfo::setStatBase(DEX, val);
                if (val >= 99)
                {
                    statusWindow->setPointsNeeded(DEX, 0);
                    msg.readInt8();
                }
                else
                {
                    statusWindow->setPointsNeeded(DEX, msg.readInt8());
                }

                val = msg.readInt8();
                PlayerInfo::setStatBase(LUK, val);
                if (val >= 99)
                {
                    statusWindow->setPointsNeeded(LUK, 0);
                    msg.readInt8();
                }
                else
                {
                    statusWindow->setPointsNeeded(LUK, msg.readInt8());
                }

                PlayerInfo::setStatBase(ATK, msg.readInt16(), false);
                PlayerInfo::setStatMod(ATK, msg.readInt16());

                PlayerInfo::setStatBase(MATK, msg.readInt16(), false);
                PlayerInfo::setStatMod(MATK, msg.readInt16());


                PlayerInfo::setStatBase(DEF, msg.readInt16(), false);
                PlayerInfo::setStatMod(DEF, msg.readInt16());

                PlayerInfo::setStatBase(MDEF, msg.readInt16(), false);
                PlayerInfo::setStatMod(MDEF, msg.readInt16());

                PlayerInfo::setStatBase(HIT, msg.readInt16());

                PlayerInfo::setStatBase(FLEE, msg.readInt16(), false);
                PlayerInfo::setStatMod(FLEE, msg.readInt16());

                PlayerInfo::setStatBase(CRIT, msg.readInt16());
            }

            msg.readInt16();  // manner
            break;

        case SMSG_PLAYER_STAT_UPDATE_6:
            switch (msg.readInt16())
            {
                case 0x0020:
                    statusWindow->setPointsNeeded(STR, msg.readInt8());
                    break;
                case 0x0021:
                    statusWindow->setPointsNeeded(AGI, msg.readInt8());
                    break;
                case 0x0022:
                    statusWindow->setPointsNeeded(VIT, msg.readInt8());
                    break;
                case 0x0023:
                    statusWindow->setPointsNeeded(INT, msg.readInt8());
                    break;
                case 0x0024:
                    statusWindow->setPointsNeeded(DEX, msg.readInt8());
                    break;
                case 0x0025:
                    statusWindow->setPointsNeeded(LUK, msg.readInt8());
                    break;
            }
            break;

        case SMSG_PLAYER_ARROW_MESSAGE:
            {
                int type = msg.readInt16();

                switch (type)
                {
                    case 0:
                        {
                            SERVER_NOTICE(_("Equip arrows first."))
                        }
                        break;
                    default:
                        logger->log("0x013b: Unhandled message %i", type);
                        break;
                }
            }
            break;
    }
}
Exemplo n.º 5
0
void PlayerHandler::handleMessage(MessageIn &msg)
{
	switch (msg.getId())
	{
	case SMSG_WALK_RESPONSE:
		/*
		 * This client assumes that all walk messages succeed,
		 * and that the server will send a correction notice
		 * otherwise.
		 */
		break;

	case SMSG_PLAYER_WARP:
	{
		std::string mapPath = msg.readString(16);
		bool nearby;
		Uint16 x = msg.readInt16();
		Uint16 y = msg.readInt16();

		logger->log("Warping to %s (%d, %d)", mapPath.c_str(), x, y);

		/*
		 * We must clear the local player's target *before* the call
		 * to changeMap, as it deletes all beings.
		 */
		player_node->stopAttack();

		nearby = (engine->getCurrentMapName() == mapPath);

		// Switch the actual map, deleting the previous one if necessary
		mapPath = mapPath.substr(0, mapPath.rfind("."));
		engine->changeMap(mapPath);

		float scrollOffsetX = 0.0f;
		float scrollOffsetY = 0.0f;

		/* Scroll if neccessary */
		if (!nearby
				|| (abs(x - player_node->mX) > MAP_TELEPORT_SCROLL_DISTANCE)
				|| (abs(y - player_node->mY) > MAP_TELEPORT_SCROLL_DISTANCE))
		{
			scrollOffsetX = (x - player_node->mX) * 32;
			scrollOffsetY = (y - player_node->mY) * 32;
		}

		player_node->setAction(Being::STAND);
		player_node->mFrame = 0;
		player_node->mX = x;
		player_node->mY = y;

		logger->log("Adjust scrolling by %d:%d", (int) scrollOffsetX,
				(int) scrollOffsetY);

		viewport->scrollBy(scrollOffsetX, scrollOffsetY);
	}
		break;

	case SMSG_PLAYER_STAT_UPDATE_1:
	{
		int type = msg.readInt16();
		int value = msg.readInt32();

		switch (type)
		{
		//case 0x0000:
		//    player_node->setWalkSpeed(msg.readInt32());
		//    break;
		case 0x0005:
			player_node->setHp(value);
			break;
		case 0x0006:
			player_node->setMaxHp(value);
			break;
		case 0x0007:
			player_node->mMp = value;
			break;
		case 0x0008:
			player_node->mMaxMp = value;
			break;
		case 0x0009:
			player_node->mStatsPointsToAttribute = value;
			break;
		case 0x000b:
			player_node->setLevel(value);
			break;
		case 0x000c:
			player_node->mSkillPoint = value;
			skillDialog->update();
			break;
		case 0x0018:
			if (value >= player_node->getMaxWeight() / 2
					&& player_node->getTotalWeight()
							< player_node->getMaxWeight() / 2)
			{
				weightNotice = new OkDialog(_("Message"),
						_("You are carrying more than "
								"half your weight. You are "
								"unable to regain health."));
				weightNotice->addActionListener(&weightListener);
			}
			player_node->setTotalWeight(value);
			break;
		case 0x0019:
			player_node->setMaxWeight(value);
			break;
		case 0x0029:
			player_node->ATK = value;
			break;
		case 0x002b:
			player_node->MATK = value;
			break;
		case 0x002d:
			player_node->DEF = value;
			break;
		case 0x002e:
			player_node->DEF_BONUS = value;
			break;
		case 0x002f:
			player_node->MDEF = value;
			break;
		case 0x0031:
			player_node->HIT = value;
			break;
		case 0x0032:
			player_node->FLEE = value;
			break;
		case 0x0035:
			player_node->mAttackSpeed = value;
			break;
		case 0x0037:
			player_node->mJobLevel = value;
			break;
		case 500:
			player_node->setGMLevel(value);
			break;
		}

		if (player_node->getHp() == 0 && !deathNotice)
		{
			if (true)
			{
				game.wasKilled = true;
				Net::getPlayerHandler()->respawn();
			}
			else
			{
				deathNotice = new OkDialog(_("Message"), randomDeathMessage());
				deathNotice->addActionListener(&deathListener);
				player_node->setAction(Being::DEAD);
			}
		}
	}
		break;

	case SMSG_PLAYER_STAT_UPDATE_2:
		switch (msg.readInt16())
		{
		case 0x0001:
			player_node->setXp(msg.readInt32());
			break;
		case 0x0002:
			player_node->mJobXp = msg.readInt32();
			break;
		case 0x0014:
		{
			int curGp = player_node->getMoney();
			player_node->setMoney(msg.readInt32());
			if (player_node->getMoney() > curGp)
				localChatTab->chatLog(
						_("You picked up ") + Units::formatCurrency(
								player_node->getMoney() - curGp), BY_SERVER);
		}
			break;
		case 0x0016:
			player_node->mXpForNextLevel = msg.readInt32();
			break;
		case 0x0017:
			player_node->mJobXpForNextLevel = msg.readInt32();
			break;
		}
		break;

	case SMSG_PLAYER_STAT_UPDATE_3:
	{
		int type = msg.readInt32();
		int base = msg.readInt32();
		int bonus = msg.readInt32();
		int total = base + bonus;

		switch (type)
		{
		case 0x000d:
			player_node->mAttr[LocalPlayer::STR] = total;
			break;
		case 0x000e:
			player_node->mAttr[LocalPlayer::AGI] = total;
			break;
		case 0x000f:
			player_node->mAttr[LocalPlayer::VIT] = total;
			break;
		case 0x0010:
			player_node->mAttr[LocalPlayer::INT] = total;
			break;
		case 0x0011:
			player_node->mAttr[LocalPlayer::DEX] = total;
			break;
		case 0x0012:
			player_node->mAttr[LocalPlayer::LUK] = total;
			break;
		}
	}
		break;

	case SMSG_PLAYER_STAT_UPDATE_4:
	{
		int type = msg.readInt16();
		int fail = msg.readInt8();
		int value = msg.readInt8();

		if (fail != 1)
			break;

		switch (type)
		{
		case 0x000d:
			player_node->mAttr[LocalPlayer::STR] = value;
			break;
		case 0x000e:
			player_node->mAttr[LocalPlayer::AGI] = value;
			break;
		case 0x000f:
			player_node->mAttr[LocalPlayer::VIT] = value;
			break;
		case 0x0010:
			player_node->mAttr[LocalPlayer::INT] = value;
			break;
		case 0x0011:
			player_node->mAttr[LocalPlayer::DEX] = value;
			break;
		case 0x0012:
			player_node->mAttr[LocalPlayer::LUK] = value;
			break;
		}
	}
		break;

		// Updates stats and status points
	case SMSG_PLAYER_STAT_UPDATE_5:
		player_node->mStatsPointsToAttribute = msg.readInt16();
		player_node->mAttr[LocalPlayer::STR] = msg.readInt8();
		player_node->mAttrUp[LocalPlayer::STR] = msg.readInt8();
		player_node->mAttr[LocalPlayer::AGI] = msg.readInt8();
		player_node->mAttrUp[LocalPlayer::AGI] = msg.readInt8();
		player_node->mAttr[LocalPlayer::VIT] = msg.readInt8();
		player_node->mAttrUp[LocalPlayer::VIT] = msg.readInt8();
		player_node->mAttr[LocalPlayer::INT] = msg.readInt8();
		player_node->mAttrUp[LocalPlayer::INT] = msg.readInt8();
		player_node->mAttr[LocalPlayer::DEX] = msg.readInt8();
		player_node->mAttrUp[LocalPlayer::DEX] = msg.readInt8();
		player_node->mAttr[LocalPlayer::LUK] = msg.readInt8();
		player_node->mAttrUp[LocalPlayer::LUK] = msg.readInt8();
		player_node->ATK = msg.readInt16(); // ATK
		player_node->ATK_BONUS = msg.readInt16(); // ATK bonus
		player_node->MATK = msg.readInt16(); // MATK max
		player_node->MATK_BONUS = msg.readInt16(); // MATK min
		player_node->DEF = msg.readInt16(); // DEF
		player_node->DEF_BONUS = msg.readInt16(); // DEF bonus
		player_node->MDEF = msg.readInt16(); // MDEF
		player_node->MDEF_BONUS = msg.readInt16(); // MDEF bonus
		player_node->HIT = msg.readInt16(); // HIT
		player_node->FLEE = msg.readInt16(); // FLEE
		player_node->FLEE_BONUS = msg.readInt16(); // FLEE bonus
		msg.readInt16(); // critical
		msg.readInt16(); // unknown
		break;

	case SMSG_PLAYER_STAT_UPDATE_6:
		switch (msg.readInt16())
		{
		case 0x0020:
			player_node->mAttrUp[LocalPlayer::STR] = msg.readInt8();
			break;
		case 0x0021:
			player_node->mAttrUp[LocalPlayer::AGI] = msg.readInt8();
			break;
		case 0x0022:
			player_node->mAttrUp[LocalPlayer::VIT] = msg.readInt8();
			break;
		case 0x0023:
			player_node->mAttrUp[LocalPlayer::INT] = msg.readInt8();
			break;
		case 0x0024:
			player_node->mAttrUp[LocalPlayer::DEX] = msg.readInt8();
			break;
		case 0x0025:
			player_node->mAttrUp[LocalPlayer::LUK] = msg.readInt8();
			break;
		}
		break;

	case SMSG_PLAYER_ARROW_MESSAGE:
	{
		int type = msg.readInt16();

		switch (type)
		{
		case 0:
			localChatTab->chatLog(_("Equip arrows first."), BY_SERVER);
			break;
		default:
			logger->log("0x013b: Unhandled message %i", type);
			break;
		}
	}
		break;
	}
}