void ProtocolGame::parseCreatureHealth(InputMessage& msg)
{
    uint id = msg.getU32();
    int healthPercent = msg.getU8();

    CreaturePtr creature = g_map.getCreatureById(id);
    if(creature)
        creature->setHealthPercent(healthPercent);
}
void ProtocolGame::parseCreatureSquare(InputMessage& msg)
{
    uint id = msg.getU32();
    int color = msg.getU8();

    CreaturePtr creature = g_map.getCreatureById(id);
    if(creature)
        creature->addVolatileSquare(color);
}
void ProtocolGame::parseCreatureShields(InputMessage& msg)
{
    uint id = msg.getU32();
    int shield = msg.getU8();

    CreaturePtr creature = g_map.getCreatureById(id);
    if(creature)
        creature->setShield(shield);
}
void ProtocolGame::parseCreatureTurn(InputMessage& msg)
{
    uint id = msg.getU32();
    Otc::Direction direction = (Otc::Direction)msg.getU8();

    CreaturePtr creature = g_map.getCreatureById(id);
    if(creature)
        creature->turn(direction);
}
void ProtocolGame::parseCreatureSkulls(InputMessage& msg)
{
    uint id = msg.getU32();
    int skull = msg.getU8();

    CreaturePtr creature = g_map.getCreatureById(id);
    if(creature)
        creature->setSkull(skull);
}
void ProtocolGame::parseCreatureSpeed(InputMessage& msg)
{
    uint id = msg.getU32();
    int speed = msg.getU16();

    CreaturePtr creature = g_map.getCreatureById(id);
    if(creature)
        creature->setSpeed(speed);
}
void ProtocolGame::parseCreatureOutfit(InputMessage& msg)
{
    uint id = msg.getU32();
    Outfit outfit = internalGetOutfit(msg);

    CreaturePtr creature = g_map.getCreatureById(id);
    if(creature)
        creature->setOutfit(outfit);
}
void ProtocolGame::parseCreatureLight(InputMessage& msg)
{
    uint id = msg.getU32();

    Light light;
    light.intensity = msg.getU8();
    light.color = msg.getU8();

    CreaturePtr creature = g_map.getCreatureById(id);
    if(creature)
        creature->setLight(light);
}
Example #9
0
bool Tile::isWalkable(bool ignoreCreatures)
{
    if(!getGround())
        return false;

    for(const ThingPtr& thing : m_things) {
        if(thing->isNotWalkable())
            return false;

        if(!ignoreCreatures) {
            if(thing->isCreature()) {
                CreaturePtr creature = thing->static_self_cast<Creature>();
                if(!creature->isPassable() && creature->canBeSeen())
                    return false;
            }
        }
    }
    return true;
}
Example #10
0
void Game::follow(const CreaturePtr& creature)
{
    if(!canPerformGameAction() || creature == m_localPlayer || creature == m_followingCreature)
        return;

    if(creature && isAttacking())
        cancelAttack();

    setFollowingCreature(creature);
    m_protocolGame->sendFollow(creature ? creature->getId() : 0, ++m_seq);
}
Example #11
0
void Game::processOpenOutfitWindow(const Outfit& currentOufit, const std::vector<std::tuple<int, std::string, int> >& outfitList,
                                   const std::vector<std::tuple<int, std::string> >& mountList)
{
    // create virtual creature outfit
    CreaturePtr virtualOutfitCreature = CreaturePtr(new Creature);
    virtualOutfitCreature->setDirection(Otc::South);

    Outfit outfit = currentOufit;
    outfit.setMount(0);
    virtualOutfitCreature->setOutfit(outfit);

    // creature virtual mount outfit
    CreaturePtr virtualMountCreature = nullptr;
    if(getFeature(Otc::GamePlayerMounts))
    {
        virtualMountCreature = CreaturePtr(new Creature);
        virtualMountCreature->setDirection(Otc::South);
        if(currentOufit.getMount() > 0) {
            Outfit mountOutfit;
            mountOutfit.setId(currentOufit.getMount());
            virtualMountCreature->setOutfit(mountOutfit);
        }
    }

    g_lua.callGlobalField("g_game", "onOpenOutfitWindow", virtualOutfitCreature, outfitList, virtualMountCreature, mountList);
}
void ProtocolGame::parseOutfitWindow(InputMessage& msg)
{
    Outfit outfit = internalGetOutfit(msg);

    typedef std::tuple<int, std::string, int> OutfitInfo;
    std::vector<OutfitInfo> outfitList;

    uint8 outfitCount = msg.getU8();
    for(int i = 0; i < outfitCount; i++) {
        uint16 outfitId = msg.getU16();
        std::string outfitName = msg.getString();
        uint8 outfitAddons = msg.getU8();

        outfitList.push_back(OutfitInfo(outfitId, outfitName, outfitAddons));
    }

    CreaturePtr creature = CreaturePtr(new Creature);
    creature->setXPattern(2);
    creature->setOutfit(outfit);

    g_lua.callGlobalField("Game", "onOpenOutfitWindow", creature, outfitList);
}
Example #13
0
void Game::follow(CreaturePtr creature)
{
    if(!canPerformGameAction() || creature == m_localPlayer)
        return;

    // cancel when following again
    if(creature && creature == m_followingCreature)
        creature = nullptr;

    if(creature && isAttacking())
        cancelAttack();

    setFollowingCreature(creature);
    m_localPlayer->stopAutoWalk();

    if(m_protocolVersion >= 963) {
        if(creature)
            m_seq = creature->getId();
    } else
        m_seq++;

    m_protocolGame->sendFollow(creature ? creature->getId() : 0, m_seq);
}
Example #14
0
void LocalPlayer::setFollowingCreature(const CreaturePtr& creature)
{
    // clear current following creature
    if(m_followingCreature) {
        m_followingCreature->hideStaticSquare();
        m_followingCreature = nullptr;
    }

    // set the new attacking creature
    if(creature) {
        creature->showStaticSquare(Fw::green);
        m_followingCreature = creature;
    }
}
Example #15
0
void Map::addCreature(const CreaturePtr& creature)
{
    m_knownCreatures[creature->getId()] = creature;
}
Example #16
0
void Tile::draw(const Point& dest, float scaleFactor, int drawFlags, LightView *lightView)
{
    bool animate = drawFlags & Otc::DrawAnimations;

    /* Flags to be checked for.  */
    static const tileflags_t flags[] = {
        TILESTATE_HOUSE,
        TILESTATE_PROTECTIONZONE,
        TILESTATE_OPTIONALZONE,
        TILESTATE_HARDCOREZONE,
        TILESTATE_NOLOGOUT
    };

    // first bottom items
    if(drawFlags & (Otc::DrawGround | Otc::DrawGroundBorders | Otc::DrawOnBottom)) {
        m_drawElevation = 0;
        for(const ThingPtr& thing : m_things) {
            if(!thing->isGround() && !thing->isGroundBorder() && !thing->isOnBottom())
                break;

            bool restore = false;
            if(g_map.showZones() && thing->isGround()) {
                for(unsigned int i = 0; i < sizeof(flags) / sizeof(tileflags_t); ++i) {
                    tileflags_t flag = flags[i];
                    if(hasFlag(flag) && g_map.showZone(flag)) {
                        g_painter->setOpacity(g_map.getZoneOpacity());
                        g_painter->setColor(g_map.getZoneColor(flag));
                        restore = true;
                        break;
                    }
                }
            }

            if((thing->isGround() && drawFlags & Otc::DrawGround) ||
               (thing->isGroundBorder() && drawFlags & Otc::DrawGroundBorders) ||
               (thing->isOnBottom() && drawFlags & Otc::DrawOnBottom)) {
                thing->draw(dest - m_drawElevation*scaleFactor, scaleFactor, animate, lightView);

                if(restore) {
                    g_painter->resetOpacity();
                    g_painter->resetColor();
                }
            }

            m_drawElevation += thing->getElevation();
            if(m_drawElevation > Otc::MAX_ELEVATION)
                m_drawElevation = Otc::MAX_ELEVATION;
        }
    }

    int redrawPreviousTopW = 0;
    int redrawPreviousTopH = 0;

    if(drawFlags & Otc::DrawItems) {
        // now common items in reverse order
        for(auto it = m_things.rbegin(); it != m_things.rend(); ++it) {
            const ThingPtr& thing = *it;
            if(thing->isOnTop() || thing->isOnBottom() || thing->isGroundBorder() || thing->isGround() || thing->isCreature())
                break;
            thing->draw(dest - m_drawElevation*scaleFactor, scaleFactor, animate, lightView);

            if(thing->isLyingCorpse()) {
                redrawPreviousTopW = std::max(thing->getWidth(), redrawPreviousTopW);
                redrawPreviousTopH = std::max(thing->getHeight(), redrawPreviousTopH);
            }

            m_drawElevation += thing->getElevation();
            if(m_drawElevation > Otc::MAX_ELEVATION)
                m_drawElevation = Otc::MAX_ELEVATION;
        }
    }

    // after we render 2x2 lying corpses, we must redraw previous creatures/ontop above them
    if(redrawPreviousTopH > 0 || redrawPreviousTopW > 0) {
        int topRedrawFlags = drawFlags & (Otc::DrawCreatures | Otc::DrawEffects | Otc::DrawOnTop | Otc::DrawAnimations);
        if(topRedrawFlags) {
            for(int x=-redrawPreviousTopW;x<=0;++x) {
                for(int y=-redrawPreviousTopH;y<=0;++y) {
                    if(x == 0 && y == 0)
                        continue;
                    const TilePtr& tile = g_map.getTile(m_position.translated(x,y));
                    if(tile)
                        tile->draw(dest + Point(x*Otc::TILE_PIXELS, y*Otc::TILE_PIXELS)*scaleFactor, scaleFactor, topRedrawFlags);
                }
            }
        }
    }

    // creatures
    if(drawFlags & Otc::DrawCreatures) {
        if(animate) {
            for(const CreaturePtr& creature : m_walkingCreatures) {
                creature->draw(Point(dest.x + ((creature->getPosition().x - m_position.x)*Otc::TILE_PIXELS - m_drawElevation)*scaleFactor,
                                     dest.y + ((creature->getPosition().y - m_position.y)*Otc::TILE_PIXELS - m_drawElevation)*scaleFactor), scaleFactor, animate, lightView);
            }
        }

        for(auto it = m_things.rbegin(); it != m_things.rend(); ++it) {
            const ThingPtr& thing = *it;
            if(!thing->isCreature())
                continue;
            CreaturePtr creature = thing->static_self_cast<Creature>();
            if(creature && (!creature->isWalking() || !animate))
                creature->draw(dest - m_drawElevation*scaleFactor, scaleFactor, animate, lightView);
        }
    }

    // effects
    if(drawFlags & Otc::DrawEffects)
        for(const EffectPtr& effect : m_effects)
            effect->draw(dest - m_drawElevation*scaleFactor, scaleFactor, animate, lightView);

    // top items
    if(drawFlags & Otc::DrawOnTop)
        for(const ThingPtr& thing : m_things)
            if(thing->isOnTop())
                thing->draw(dest, scaleFactor, animate, lightView); 

    // draw translucent light (for tiles beneath holes)
    if(hasTranslucentLight() && lightView) {
        Light light;
        light.intensity = 1;
        lightView->addLightSource(dest + Point(16,16) * scaleFactor, scaleFactor, light);
    }
}
ThingPtr ProtocolGame::internalGetThing(InputMessage& msg)
{
    ThingPtr thing;

    int thingId = msg.getU16();
    assert(thingId != 0);
    if(thingId == 0x0061 || thingId == 0x0062) { // add new creature
        CreaturePtr creature;

        if(thingId == 0x0062) { //creature is known
            uint id = msg.getU32();

            CreaturePtr knownCreature = g_map.getCreatureById(id);
            if(knownCreature)
                creature = knownCreature;
            else
                logTraceError("server says creature is known, but its not on creatures list");
        } else if(thingId == 0x0061) { //creature is not known
            uint removeId = msg.getU32();
            uint id = msg.getU32();
            std::string name = msg.getString();

            if(name.length() > 0) // every creature name must start with a capital letter
                name[0] = toupper(name[0]);

            g_map.removeCreatureById(removeId);

            if(id == m_localPlayer->getId())
                creature = m_localPlayer;
            else if(id >= Proto::PlayerStartId && id < Proto::PlayerEndId)
                creature = PlayerPtr(new Player);
            else if(id >= Proto::MonsterStartId && id < Proto::MonsterEndId)
                creature = MonsterPtr(new Monster);
            else if(id >= Proto::NpcStartId && id < Proto::NpcEndId)
                creature = NpcPtr(new Npc);
            else
                logTraceError("creature id is invalid");

            creature->setId(id);
            creature->setName(name);
        }

        uint8 healthPercent = msg.getU8();
        Otc::Direction direction = (Otc::Direction)msg.getU8();
        Outfit outfit = internalGetOutfit(msg);

        Light light;
        light.intensity = msg.getU8();
        light.color = msg.getU8();

        int speed = msg.getU16();
        int skull = msg.getU8();
        int shield = msg.getU8();

        int emblem = -1;
        if(thingId == 0x0061) // emblem is sent only in packet type 0x61
            emblem = msg.getU8();

        bool passable = (msg.getU8() == 0);

        if(creature) {
            creature->setHealthPercent(healthPercent);
            creature->setDirection(direction);
            creature->setOutfit(outfit);
            creature->setLight(light);
            creature->setSpeed(speed);
            creature->setSkull(skull);
            creature->setShield(shield);
            if(emblem != -1)
                creature->setEmblem(emblem);
            creature->setPassable(passable);
            creature->setDirection(direction);

            if(creature == m_localPlayer) {
                m_localPlayer->setKnown(true);
            }
        }

        thing = creature;
    } else if(thingId == 0x0063) { // creature turn
        parseCreatureTurn(msg);
    } else // item
        thing = internalGetItem(msg, thingId);

    return thing;
}
Example #18
0
void Game::requestTrade(const ItemPtr& item, const CreaturePtr& creature)
{
    if(!canPerformGameAction() || !item || !creature)
        return;
    m_protocolGame->sendRequestTrade(item->getPosition(), item->getId(), item->getStackpos(), creature->getId());
}
Example #19
0
void Tile::draw(const Point& dest, float scaleFactor, int drawFlags, LightView *lightView)
{
    bool animate = drawFlags & Otc::DrawAnimations;

    // Added for MapEditor purposes.
    // This check will and must evaluate to false if using
    // normal client, unless some flag error.
    // Save last color
    Color lastColor = g_painter->getColor();
    if((m_flags & TILESTATE_HOUSE) == TILESTATE_HOUSE)
        g_painter->setColor(Color::blue);
    else if((m_flags & TILESTATE_PROTECTIONZONE) == TILESTATE_PROTECTIONZONE)
        g_painter->setColor(Color::green);
    // first bottom items
    if(drawFlags & (Otc::DrawGround | Otc::DrawGroundBorders | Otc::DrawOnBottom)) {
        m_drawElevation = 0;
        for(const ThingPtr& thing : m_things) {
            if(!thing->isGround() && !thing->isGroundBorder() && !thing->isOnBottom())
                break;

            if((thing->isGround() && drawFlags & Otc::DrawGround) ||
               (thing->isGroundBorder() && drawFlags & Otc::DrawGroundBorders) ||
               (thing->isOnBottom() && drawFlags & Otc::DrawOnBottom)) {
                thing->draw(dest - m_drawElevation*scaleFactor, scaleFactor, animate, lightView);
            }

            m_drawElevation += thing->getElevation();
            if(m_drawElevation > Otc::MAX_ELEVATION)
                m_drawElevation = Otc::MAX_ELEVATION;
        }
    }

    int redrawPreviousTopW = 0;
    int redrawPreviousTopH = 0;

    if(drawFlags & Otc::DrawItems) {
        // now common items in reverse order
        for(auto it = m_things.rbegin(); it != m_things.rend(); ++it) {
            const ThingPtr& thing = *it;
            if(thing->isOnTop() || thing->isOnBottom() || thing->isGroundBorder() || thing->isGround() || thing->isCreature())
                break;
            thing->draw(dest - m_drawElevation*scaleFactor, scaleFactor, animate, lightView);

            if(thing->isLyingCorpse()) {
                redrawPreviousTopW = std::max(thing->getWidth(), redrawPreviousTopW);
                redrawPreviousTopH = std::max(thing->getHeight(), redrawPreviousTopH);
            }

            m_drawElevation += thing->getElevation();
            if(m_drawElevation > Otc::MAX_ELEVATION)
                m_drawElevation = Otc::MAX_ELEVATION;
        }
    }

    // after we render 2x2 lying corpses, we must redraw previous creatures/ontop above them
    if(redrawPreviousTopH > 0 || redrawPreviousTopW > 0) {
        int topRedrawFlags = drawFlags & (Otc::DrawCreatures | Otc::DrawEffects | Otc::DrawOnTop | Otc::DrawAnimations);
        if(topRedrawFlags) {
            for(int x=-redrawPreviousTopW;x<=0;++x) {
                for(int y=-redrawPreviousTopH;y<=0;++y) {
                    if(x == 0 && y == 0)
                        continue;
                    const TilePtr& tile = g_map.getTile(m_position.translated(x,y));
                    if(tile)
                        tile->draw(dest + Point(x*Otc::TILE_PIXELS, y*Otc::TILE_PIXELS)*scaleFactor, scaleFactor, topRedrawFlags);
                }
            }
        }
    }

    // creatures
    if(drawFlags & Otc::DrawCreatures) {
        if(animate) {
            for(const CreaturePtr& creature : m_walkingCreatures) {
                creature->draw(Point(dest.x + ((creature->getPosition().x - m_position.x)*Otc::TILE_PIXELS - m_drawElevation)*scaleFactor,
                                     dest.y + ((creature->getPosition().y - m_position.y)*Otc::TILE_PIXELS - m_drawElevation)*scaleFactor), scaleFactor, animate, lightView);
            }
        }

        for(auto it = m_things.rbegin(); it != m_things.rend(); ++it) {
            const ThingPtr& thing = *it;
            if(!thing->isCreature())
                continue;
            CreaturePtr creature = thing->static_self_cast<Creature>();
            if(creature && (!creature->isWalking() || !animate))
                creature->draw(dest - m_drawElevation*scaleFactor, scaleFactor, animate, lightView);

        }
    }

    // effects
    if(drawFlags & Otc::DrawEffects) {
        for(const EffectPtr& effect : m_effects){
            effect->draw(dest - m_drawElevation*scaleFactor, scaleFactor, animate, lightView);
        }
    }

    // top items
    if(drawFlags & Otc::DrawOnTop) {
        for(const ThingPtr& thing : m_things) {
            if(thing->isOnTop()){
                thing->draw(dest, scaleFactor, animate, lightView);
            }
        }
    }

    // draw translucent light (for tiles beneath holes)
    if(hasTranslucentLight() && lightView) {
        Light light;
        light.intensity = 1;
        lightView->addLightSource(dest + Point(16,16) * scaleFactor, scaleFactor, light);
    }

    // Restore color
    g_painter->setColor(lastColor);
}