• 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!

C++ [src] Angles of the block missiles

kaincer

Member
Joined
Jun 28, 2010
Messages
44
Reaction score
5
Hello, good afternoon.
Nekiro 1.5 downgrade 8.0
I think I have a problem in c++
with respect to the angles of the block missiles
I rule out that it is the .dat because the "block Missiles" is selected.
How can I make the angles of attack more restricted?

1681673622116.png

1681673657581.png

1681673602125.png
At some angles it should return
RETURNVALUE_CREATUREISNOTREACHABLE
 
Last edited:
You can see in your source:
isTileClear
blockprojectile
return !tile->hasProperty(CONST_PROP_BLOCKPROJECTILE);
isSightClear
checkSightLine
blockprojectile

This code is the default from tfs 1.4:

C++:
bool Map::canThrowObjectTo(const Position& fromPos, const Position& toPos, bool checkLineOfSight /*= true*/, bool sameFloor /*= false*/,
                           int32_t rangex /*= Map::maxClientViewportX*/, int32_t rangey /*= Map::maxClientViewportY*/) const
{
    if (Position::getDistanceX(fromPos, toPos) > rangex || Position::getDistanceY(fromPos, toPos) > rangey) {
        return false;
    }

    return !checkLineOfSight || isSightClear(fromPos, toPos, sameFloor);
}

bool Map::isTileClear(uint16_t x, uint16_t y, uint8_t z, bool blockFloor /*= false*/) const
{
    const Tile* tile = getTile(x, y, z);
    if (!tile) {
        return true;
    }

    if (blockFloor && tile->getGround()) {
        return false;
    }

    return !tile->hasProperty(CONST_PROP_BLOCKPROJECTILE);
}

namespace {

bool checkSteepLine(uint16_t x0, uint16_t y0, uint16_t x1, uint16_t y1, uint8_t z)
{
    float dx = x1 - x0;
    float slope = (dx == 0) ? 1 : (y1 - y0) / dx;
    float yi = y0 + slope;

    for (uint16_t x = x0 + 1; x < x1; ++x) {
        //0.1 is necessary to avoid loss of precision during calculation
        if (!g_game.map.isTileClear(std::floor(yi + 0.1), x, z)) {
            return false;
        }
        yi += slope;
    }

    return true;
}

bool checkSlightLine(uint16_t x0, uint16_t y0, uint16_t x1, uint16_t y1, uint8_t z)
{
    float dx = x1 - x0;
    float slope = (dx == 0) ? 1 : (y1 - y0) / dx;
    float yi = y0 + slope;

    for (uint16_t x = x0 + 1; x < x1; ++x) {
        //0.1 is necessary to avoid loss of precision during calculation
        if (!g_game.map.isTileClear(x, std::floor(yi + 0.1), z)) {
            return false;
        }
        yi += slope;
    }

    return true;
}

}

bool Map::checkSightLine(uint16_t x0, uint16_t y0, uint16_t x1, uint16_t y1, uint8_t z) const
{
    if (x0 == x1 && y0 == y1) {
        return true;
    }

    if (std::abs(y1 - y0) > std::abs(x1 - x0)) {
        if (y1 > y0) {
            return checkSteepLine(y0, x0, y1, x1, z);
        }
        return checkSteepLine(y1, x1, y0, x0, z);
    }

    if (x0 > x1) {
        return checkSlightLine(x1, y1, x0, y0, z);
    }

    return checkSlightLine(x0, y0, x1, y1, z);
}

bool Map::isSightClear(const Position& fromPos, const Position& toPos, bool sameFloor /*= false*/) const
{
    //target is on the same floor
    if (fromPos.z == toPos.z) {
        //skip checks if toPos is next to us
        if (Position::getDistanceX(fromPos, toPos) < 2 && Position::getDistanceY(fromPos, toPos) < 2) {
            return true;
        }

        //sight is clear or sameFloor is enabled
        bool sightClear = checkSightLine(fromPos.x, fromPos.y, toPos.x, toPos.y, fromPos.z);
        if (sightClear || sameFloor) {
            return sightClear;
        }

        //no obstacles above floor 0 so we can throw above the obstacle
        if (fromPos.z == 0) {
            return true;
        }

        //check if tiles above us and the target are clear and check for a clear sight between them
        uint8_t newZ = fromPos.z - 1;
        return isTileClear(fromPos.x, fromPos.y, newZ, true) && isTileClear(toPos.x, toPos.y, newZ, true) && checkSightLine(fromPos.x, fromPos.y, toPos.x, toPos.y, newZ);
    }

    //target is on a different floor
    if (sameFloor) {
        return false;
    }

    //skip checks for sight line in case fromPos and toPos cross the ground floor
    if (fromPos.z < 8 && toPos.z > 7 || fromPos.z > 7 && toPos.z < 8) {
        return false;
    }

    //target is above us
    if (fromPos.z > toPos.z) {
        if (Position::getDistanceZ(fromPos, toPos) > 1) {
            return false;
        }

        //check a tile above us and the path to the target
        uint8_t newZ = fromPos.z - 1;
        return isTileClear(fromPos.x, fromPos.y, newZ, true) && checkSightLine(fromPos.x, fromPos.y, toPos.x, toPos.y, newZ);
    }

    //target is below us
    //check if tiles above the target are clear
    for (uint8_t z = fromPos.z; z < toPos.z; ++z) {
        if (!isTileClear(toPos.x, toPos.y, z, true)) {
            return false;
        }
    }

    //check if we can throw to the tile above the target
    return checkSightLine(fromPos.x, fromPos.y, toPos.x, toPos.y, fromPos.z);
}
 
Back
Top