• 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++ Player::canWalkthrough() TFS 1.2

Itutorial

Legendary OT User
Joined
Dec 23, 2014
Messages
2,339
Solutions
68
Reaction score
1,023
I am trying to make it so players can walk through other players summons.

Code:
bool Player::canWalkthrough(const Creature* creature) const
{
    if (group->access || creature->isInGhostMode()) {
        return true;
    }
    const Player* player = creature->getPlayer();
    const Tile* playerTile = player->getTile();
    // const Item* playerTileGround = playerTile->getGround(); //
   
    if (player && playerTile && !playerTile->hasFlag(TILESTATE_PROTECTIONZONE)) {
        return false;
    }
    Player* thisPlayer = const_cast<Player*>(this);
    if ((OTSYS_TIME() - lastWalkthroughAttempt) > 2000) {
        thisPlayer->setLastWalkthroughAttempt(OTSYS_TIME());
        return false;
    }
    if (creature->getPosition() != lastWalkthroughPosition) {
        thisPlayer->setLastWalkthroughPosition(creature->getPosition());
        return false;
    }
   
    const Player* owner = creature->getMaster()->getPlayer();
    if (owner) {
        thisPlayer->setLastWalkthroughPosition(creature->getPosition());
        return true;
    }
    thisPlayer->setLastWalkthroughPosition(creature->getPosition());
    return true;
}

This is what I have added with no luck.

Code:
const Player* owner = creature->getMaster()->getPlayer();
    if (owner) {
        thisPlayer->setLastWalkthroughPosition(creature->getPosition());
        return true;
    }
 
Solution
Have you tried to relog (or walk out of its sight) before attempting to walk through the summon?

Tested this snippet a minute ago, and it worked just fine.
C++:
bool Player::canWalkthrough(const Creature* creature) const
{
    if (group->access || creature->isInGhostMode()) {
        return true;
    }
   
    if (creature->isSummon() && creature->getMaster()->getPlayer()) {
        return true;
    }

    const Player* player = creature->getPlayer();
    if (!player) {
        return false;
    }

    const Tile* playerTile = player->getTile();
    if (!playerTile || (!playerTile->hasFlag(TILESTATE_PROTECTIONZONE) && player->getLevel() > static_cast<uint32_t>(g_config.getNumber(ConfigManager::PROTECTION_LEVEL)))) {
        return...
Have you tried to relog (or walk out of its sight) before attempting to walk through the summon?

Tested this snippet a minute ago, and it worked just fine.
C++:
bool Player::canWalkthrough(const Creature* creature) const
{
    if (group->access || creature->isInGhostMode()) {
        return true;
    }
   
    if (creature->isSummon() && creature->getMaster()->getPlayer()) {
        return true;
    }

    const Player* player = creature->getPlayer();
    if (!player) {
        return false;
    }

    const Tile* playerTile = player->getTile();
    if (!playerTile || (!playerTile->hasFlag(TILESTATE_PROTECTIONZONE) && player->getLevel() > static_cast<uint32_t>(g_config.getNumber(ConfigManager::PROTECTION_LEVEL)))) {
        return false;
    }

    const Item* playerTileGround = playerTile->getGround();
    if (!playerTileGround || !playerTileGround->hasWalkStack()) {
        return false;
    }

    Player* thisPlayer = const_cast<Player*>(this);
    if ((OTSYS_TIME() - lastWalkthroughAttempt) > 2000) {
        thisPlayer->setLastWalkthroughAttempt(OTSYS_TIME());
        return false;
    }

    if (creature->getPosition() != lastWalkthroughPosition) {
        thisPlayer->setLastWalkthroughPosition(creature->getPosition());
        return false;
    }

    thisPlayer->setLastWalkthroughPosition(creature->getPosition());
    return true;
}

bool Player::canWalkthroughEx(const Creature* creature) const
{
    if (group->access) {
        return true;
    }
   
    if (creature->isSummon() && creature->getMaster()->getPlayer()) {
        return true;
    }

    const Player* player = creature->getPlayer();
    if (!player) {
        return false;
    }

    const Tile* playerTile = player->getTile();
    return playerTile && (playerTile->hasFlag(TILESTATE_PROTECTIONZONE) || player->getLevel() <= static_cast<uint32_t>(g_config.getNumber(ConfigManager::PROTECTION_LEVEL)));
}

-- Edit --

If you wish to avoid doing the things I mentioned above, simply add the following to Creature.setMaster;
C++:
g_game.updateCreatureWalkthrough(creature);
 
Last edited:
Solution
Okay, that did allow me to walk through summons but I can also walk through players outside of pz.
 
Can you at least show me the code you're using? I'm unable to reproduce the issue with the snippet from my previous post.
 
I am using the exact code you posted.

So this is what I noticed:

If the player is higher than protection level - I can walk through summon and player
If the player isn't higher than protection level - I cant walk through either one.

Edit: I can move my own player into the monster but not walk into it.
 
Have you tried to relog (or walk out of its sight) before attempting to walk through the summon?

Tested this snippet a minute ago, and it worked just fine.
C++:
bool Player::canWalkthrough(const Creature* creature) const
{
    if (group->access || creature->isInGhostMode()) {
        return true;
    }
   
    if (creature->isSummon() && creature->getMaster()->getPlayer()) {
        return true;
    }

    const Player* player = creature->getPlayer();
    if (!player) {
        return false;
    }

    const Tile* playerTile = player->getTile();
    if (!playerTile || (!playerTile->hasFlag(TILESTATE_PROTECTIONZONE) && player->getLevel() > static_cast<uint32_t>(g_config.getNumber(ConfigManager::PROTECTION_LEVEL)))) {
        return false;
    }

    const Item* playerTileGround = playerTile->getGround();
    if (!playerTileGround || !playerTileGround->hasWalkStack()) {
        return false;
    }

    Player* thisPlayer = const_cast<Player*>(this);
    if ((OTSYS_TIME() - lastWalkthroughAttempt) > 2000) {
        thisPlayer->setLastWalkthroughAttempt(OTSYS_TIME());
        return false;
    }

    if (creature->getPosition() != lastWalkthroughPosition) {
        thisPlayer->setLastWalkthroughPosition(creature->getPosition());
        return false;
    }

    thisPlayer->setLastWalkthroughPosition(creature->getPosition());
    return true;
}

bool Player::canWalkthroughEx(const Creature* creature) const
{
    if (group->access) {
        return true;
    }
   
    if (creature->isSummon() && creature->getMaster()->getPlayer()) {
        return true;
    }

    const Player* player = creature->getPlayer();
    if (!player) {
        return false;
    }

    const Tile* playerTile = player->getTile();
    return playerTile && (playerTile->hasFlag(TILESTATE_PROTECTIONZONE) || player->getLevel() <= static_cast<uint32_t>(g_config.getNumber(ConfigManager::PROTECTION_LEVEL)));
}

-- Edit --

If you wish to avoid doing the things I mentioned above, simply add the following to Creature.setMaster;
C++:
g_game.updateCreatureWalkthrough(creature);

Thank's. You know how you get the monsters to go through the summons, too?

EDIT 2: When I summon, he dont through, only when I leave his screen and the same is teleported to me, which allows to pass through it. You know why?

EDIT 3: Missing put: g_game.updateCreatureWalkthrough(creature); :confused:

But I still need to know how the summon through the monsters on the map. Please! :D
 
Last edited:
C++:
bool Player::canWalkthrough(const Creature* creature) const
{
    if(!creature)
        return true;

    if(creature == this)
        return true;

    const Player* player = creature->getPlayer();
    if(!player)
        return false;

    if(g_game.getWorldType() == WORLD_TYPE_NO_PVP && player->getTile()->ground
        && player->getTile()->ground->getID() != ITEM_GLOWING_SWITCH)
        return true;

    return player->isGhost() && getGhostAccess() < player->getGhostAccess();
}

How i make this in 0.3.6. change just true/false and player can walktrough other players, summon and monsters.
 
C++:
bool Player::canWalkthrough(const Creature* creature) const
{
    if(!creature)
        return true;

    if(creature == this)
        return true;

    const Player* player = creature->getPlayer();
    if(!player)
        return false;

    if(g_game.getWorldType() == WORLD_TYPE_NO_PVP && player->getTile()->ground
        && player->getTile()->ground->getID() != ITEM_GLOWING_SWITCH)
        return true;

    return player->isGhost() && getGhostAccess() < player->getGhostAccess();
}

How i make this in 0.3.6. change just true/false and player can walktrough other players, summon and monsters.

Hi, yours "if" no opening or closing { } ?
Or is this just an example you've done to demonstrate?

Well, as I'm in version 1.2~1.3 I believe it's not useful, although having true and false, the structure is different.
The change I made was based on what @Ninja posted.

Anyway thank you, bro.
 
Have you tried to relog (or walk out of its sight) before attempting to walk through the summon?

Tested this snippet a minute ago, and it worked just fine.
C++:
bool Player::canWalkthrough(const Creature* creature) const
{
    if (group->access || creature->isInGhostMode()) {
        return true;
    }
   
    if (creature->isSummon() && creature->getMaster()->getPlayer()) {
        return true;
    }

    const Player* player = creature->getPlayer();
    if (!player) {
        return false;
    }

    const Tile* playerTile = player->getTile();
    if (!playerTile || (!playerTile->hasFlag(TILESTATE_PROTECTIONZONE) && player->getLevel() > static_cast<uint32_t>(g_config.getNumber(ConfigManager::PROTECTION_LEVEL)))) {
        return false;
    }

    const Item* playerTileGround = playerTile->getGround();
    if (!playerTileGround || !playerTileGround->hasWalkStack()) {
        return false;
    }

    Player* thisPlayer = const_cast<Player*>(this);
    if ((OTSYS_TIME() - lastWalkthroughAttempt) > 2000) {
        thisPlayer->setLastWalkthroughAttempt(OTSYS_TIME());
        return false;
    }

    if (creature->getPosition() != lastWalkthroughPosition) {
        thisPlayer->setLastWalkthroughPosition(creature->getPosition());
        return false;
    }

    thisPlayer->setLastWalkthroughPosition(creature->getPosition());
    return true;
}

bool Player::canWalkthroughEx(const Creature* creature) const
{
    if (group->access) {
        return true;
    }
   
    if (creature->isSummon() && creature->getMaster()->getPlayer()) {
        return true;
    }

    const Player* player = creature->getPlayer();
    if (!player) {
        return false;
    }

    const Tile* playerTile = player->getTile();
    return playerTile && (playerTile->hasFlag(TILESTATE_PROTECTIONZONE) || player->getLevel() <= static_cast<uint32_t>(g_config.getNumber(ConfigManager::PROTECTION_LEVEL)));
}

-- Edit --

If you wish to avoid doing the things I mentioned above, simply add the following to Creature.setMaster;
C++:
g_game.updateCreatureWalkthrough(creature);
Can you teach me how to apply this to my server? Using an OTX that is based on TFS 1.2 (OTX 3.7 . 807), but I'm very noob when it comes to editing things, but making players being able to walk through other players and summons is something I've been looking to learn how to do. I don't know what file I'd have to edit or create to add these codes.
 
Back
Top