• There is NO official Otland's Discord server and NO official Otland's server list. The Otland's Staff does not manage any Discord server or server list. Moderators or administrator of any Discord server or server lists have NO connection to the Otland's Staff. Do not get scammed!

Drawing bottomright of outfit cropped out

ZowN

Well-Known Member
Joined
Mar 19, 2015
Messages
130
Solutions
1
Reaction score
66
Hi guys, was wondering if anyone know where in the the sourcecode this can get fixed?

If unclear the issue is:
I want to draw aura effects but the sprite gets cropped out towards bottomright but it's perfectly visible from my position and topleft.

I believe it actually gets drawn over, I've tried to change the rect that gets passed into drawself but with no luck.
I've actually tested and fooled around quite a long time and I just can't find the solution.
When walking sideways i can see my entire aura effect flickering but then when i stand still it gets cropped out again.

Thanks in advance, appreciate any help!
 
If you take a look at MapView::draw you will understand why this happens, map is drawn from top left corner till bottom right corner, so your aura is being drawn correctly but tiles drawn after the creature with "aura" are being drawn on top of it, you will need to play with map drawing flags (note that it also calls Tile::draw), do not ask me for assistance and good luck
 
Thanks for the thorough explanation, exactly what I needed. Sat for hours trying to fix.
You've saved me lots of time, much appreciated sir:eek:!
 
Ok guys, I need some help. I'll try guiding through my process, after hearing someone point out the problem I'm probably gonna facepalm myself for my stupidity for missing it but I really can't find the issue after many hours of testing.
halpme.png
=====================================
Code:
    //Find creature with aura
    const TilePtr& tile = g_map.getTile(m_position.translated(-2, -2));
    if (tile)
    {
        for (const CreaturePtr& creature : tile->m_walkingCreatures) {
            if (creature->getOutfit().getAura())
            {
                redrawPreviousTopH = 2;
                redrawPreviousTopW = 2;
            }
        }
    }

    // redraw aura(Same code as lying corpses use to redraw creatures above the corpses, minus the loop and specific position inserted)
    if(redrawPreviousTopH > 0 || redrawPreviousTopW > 0) {
        int topRedrawFlags = drawFlags & (Otc::DrawCreatures | Otc::DrawEffects | Otc::DrawOnTop | Otc::DrawAnimations);
        if(topRedrawFlags) {
            const TilePtr& tile = g_map.getTile(m_position.translated(-2,-2));
            if (tile)
            {
                tile->draw(dest + Point((-2)*Otc::TILE_PIXELS, (-2)*Otc::TILE_PIXELS)*scaleFactor, scaleFactor, topRedrawFlags);
            }
        }
    }

Here is the full function, note that the aura drawing actually works exactly as I want if I stand on a corpse.
Code:
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_REFRESH,
        TILESTATE_NOLOGOUT,
        TILESTATE_LAST
    };

    // 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(m_selected)
                g_painter->setColor(Color::teal);

            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();
                }
            }
            if(m_selected)
                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<int>(thing->getWidth(), redrawPreviousTopW);
                redrawPreviousTopH = std::max<int>(thing->getHeight(), redrawPreviousTopH);
            }

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

    const TilePtr& tile = g_map.getTile(m_position.translated(-2, -2));
    if (tile)
    {
        for (const CreaturePtr& creature : tile->m_walkingCreatures) {
            if (creature->getOutfit().getaura())
            {
                redrawPreviousTopH = 2;
                redrawPreviousTopW = 2;
            }
        }
    }

    // after we render 2x2 lying corpses, we must redraw previous creatures/ontop above them
    // this is also what I use to redraw my aura(which isn't working and the problem im trying to solve)
    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, m_position.x - g_map.getCentralPosition().x, m_position.y - g_map.getCentralPosition().y, 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);
    }
}
 
I think you are struggling with a problem that I had a few years ago:

Solution of Hrsantiago is the correct one:
 
4drik man, you're a goddamn lifesaver! Had to put this task on hold cause I wasn't getting anywhere. Btw anyone know why I can't see "Best Answer" option?
 
Back
Top