• 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 WalkTrough player in pz

Snavy

Bakasta
Senator
Joined
Apr 1, 2012
Messages
1,249
Solutions
71
Reaction score
621
Location
Hell
TFS : 0.4 — 3777
VER: 8.6

#[UPDATED]

I was trying to fix player walktrough in pz, and it did work for a moment but i noticed a "bug".
First when two players are on screen, in pz, they can walk trough eachother just fine, except if one is standing on a depot-tile. However. When players go off screen (can't see eachother) and come back. They can't walk trough eachother. I asked cykotitan he mentioned that "sendCreatureImpassable" isn't called whenever necessary, and because of that the client is not able to determine if creature is walkable or not.

player.cpp ( canwalkTrough)
C++:
bool Player::canWalkthrough(const Creature* creature) const
{
    if(creature == this || creature->isWalkable() ||
        (creature->getMaster() && creature->getMaster() != this && canWalkthrough(creature->getMaster())))
        return true;

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

    if(
        (
            (
                (
                    (
                        player->getVocation()->isAttackable() &&
                        player->getLevel() < (uint32_t)g_config.getNumber(ConfigManager::PROTECTION_LEVEL)
                    )
                    || (
                        player->getTile()->hasFlag(TILESTATE_PROTECTIONZONE) &&
                        !player->getTile()->hasFlag(TILESTATE_HOUSE)
                    )
                )
            ) && player->getTile()->ground &&
                player->getTile()->ground->getID() != 11062
        ) && (
            !player->hasCustomFlag(PlayerCustomFlag_GamemasterPrivileges)
            || player->getAccess() <= getAccess()
        )
    ) return true;

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

protocolgame.cpp ( sendCreatureImpassable() )
C++:
void ProtocolGame::sendCreatureImpassable(const Creature* creature)
{
   // TODO: how this actually work...
   if(!canSee(creature))
       return;

   NetworkMessage_ptr msg = getOutputBuffer();
   if(msg)
   {
       TRACK_MESSAGE(msg);
       msg->put<char>(0x92);
       msg->put<uint32_t>(creature->getID());
       msg->put<char>(!player->canWalkthrough(creature));
       
   }
}
 
Last edited:
try this
C++:
bool Player::canWalkthrough(const Creature* creature) const
{
    if(!creature)
        return true;
    if(creature == this)
        return false;
    if(hasCustomFlag(PlayerCustomFlag_CanWalkthrough) || creature->isWalkable())
        return true;
    const Player* player = creature->getPlayer();
    if(!player)
        return false;
    if(((g_game.getWorldType() == WORLDTYPE_OPTIONAL &&
#ifdef __WAR_SYSTEM__
        !player->isEnemy(this, true) &&
#endif
        player->getVocation()->isAttackable() && player->getTile()->hasFlag(TILESTATE_PROTECTIONZONE)) && player->getTile()->ground &&
        Item::items[player->getTile()->ground->getID()].walkStack) && (!player->hasCustomFlag(PlayerCustomFlag_GamemasterPrivileges)
        || player->getAccess() <= getAccess()))
        return true;
    return (player->isGhost() && getGhostAccess() < player->getGhostAccess())
        || (isGhost() && getGhostAccess() > player->getGhostAccess());
}
 
try this
C++:
bool Player::canWalkthrough(const Creature* creature) const
{
    if(!creature)
        return true;
    if(creature == this)
        return false;
    if(hasCustomFlag(PlayerCustomFlag_CanWalkthrough) || creature->isWalkable())
        return true;
    const Player* player = creature->getPlayer();
    if(!player)
        return false;
    if(((g_game.getWorldType() == WORLDTYPE_OPTIONAL &&
#ifdef __WAR_SYSTEM__
        !player->isEnemy(this, true) &&
#endif
        player->getVocation()->isAttackable() && player->getTile()->hasFlag(TILESTATE_PROTECTIONZONE)) && player->getTile()->ground &&
        Item::items[player->getTile()->ground->getID()].walkStack) && (!player->hasCustomFlag(PlayerCustomFlag_GamemasterPrivileges)
        || player->getAccess() <= getAccess()))
        return true;
    return (player->isGhost() && getGhostAccess() < player->getGhostAccess())
        || (isGhost() && getGhostAccess() > player->getGhostAccess());
}

no luck :/
 
Solution
The problem is that in tfs 0.3.6 there is no CreatureImpassable in protocolgame so I cant call it :/
Is it 0.3.6 with 8.6 protocol? You can add that function to your protocolgame.cpp.
Can you link from where you did take sources of your 0.3.6? There are maaaany version of 0.3.6.
 
It’s tfs 0.3.6 pl1 actually I’ve modified creatureimpassable from 0.4 to my source and compiled without any problems. But when I called creatureimpassable later in player.cpp I had errors while compiling. When I’ll get home I will post my protocolgame.cpp
 
It’s tfs 0.3.6 pl1 actually I’ve modified creatureimpassable from 0.4 to my source and compiled without any problems. But when I called creatureimpassable later in player.cpp I had errors while compiling. When I’ll get home I will post my protocolgame.cpp
If u have not done any big chance to Source yet
Change to 1.x
Dont waste ur time with 0.3.6
 
If u have not done any big chance to Source yet
Change to 1.x
Dont waste ur time with 0.3.6
I know ur right but I've done a lot of changes in source :/ Problem solved, I added CreatureImpassable function to tfs 0.3.6 pl1, then I did exactly what @Snavy told me to do and its working perfectly. Thanks everybody!
 
Back
Top