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

TFS 1.X+ Block push

aqubjukr

Well-Known Member
Joined
Mar 13, 2013
Messages
200
Solutions
17
Reaction score
79
Location
Paraná, Brazil
I want to block push if player if player has a storage, on sources.

I tried many times, but still, i didn't get.

Storage: 9362905 == 1


GAME.CPP (playerMoveCreature):
C++:
void Game::playerMoveCreature(Player* player, Creature* movingCreature, const Position& movingCreatureOrigPos, Tile* toTile)
{
    if (!player->canDoAction()) {
        uint32_t delay = player->getNextActionTime();
        SchedulerTask* task = createSchedulerTask(delay, std::bind(&Game::playerMoveCreatureByID,
            this, player->getID(), movingCreature->getID(), movingCreatureOrigPos, toTile->getPosition()));
        player->setNextActionTask(task);
        return;
    }

    player->setNextActionTask(nullptr);

    if (!Position::areInRange<1, 1, 0>(movingCreatureOrigPos, player->getPosition())) {
        //need to walk to the creature first before moving it
        std::forward_list<Direction> listDir;
        if (player->getPathTo(movingCreatureOrigPos, listDir, 0, 1, true, true)) {
            g_dispatcher.addTask(createTask(std::bind(&Game::playerAutoWalk,
                                            this, player->getID(), listDir)));
            SchedulerTask* task = createSchedulerTask(1500, std::bind(&Game::playerMoveCreatureByID, this,
                player->getID(), movingCreature->getID(), movingCreatureOrigPos, toTile->getPosition()));
            player->setNextWalkActionTask(task);
        } else {
            player->sendCancelMessage(RETURNVALUE_THEREISNOWAY);
        }
        return;
    }

    if ((!movingCreature->isPushable() && !player->hasFlag(PlayerFlag_CanPushAllCreatures)) ||
            (movingCreature->isInGhostMode() && !player->isAccessPlayer())) {
        player->sendCancelMessage(RETURNVALUE_NOTMOVEABLE);
        return;
    }
    
    //check throw distance
    const Position& movingCreaturePos = movingCreature->getPosition();
    const Position& toPos = toTile->getPosition();
    if ((Position::getDistanceX(movingCreaturePos, toPos) > movingCreature->getThrowRange()) || (Position::getDistanceY(movingCreaturePos, toPos) > movingCreature->getThrowRange()) || (Position::getDistanceZ(movingCreaturePos, toPos) * 4 > movingCreature->getThrowRange())) {
        player->sendCancelMessage(RETURNVALUE_DESTINATIONOUTOFREACH);
        return;
    }

    if (player != movingCreature) {
        if (toTile->hasFlag(TILESTATE_BLOCKPATH)) {
            player->sendCancelMessage(RETURNVALUE_NOTENOUGHROOM);
            return;
        } else if ((movingCreature->getZone() == ZONE_PROTECTION && !toTile->hasFlag(TILESTATE_PROTECTIONZONE)) || (movingCreature->getZone() == ZONE_NOPVP && !toTile->hasFlag(TILESTATE_NOPVPZONE))) {
            player->sendCancelMessage(RETURNVALUE_NOTPOSSIBLE);
            return;
        } else {
            if (CreatureVector* tileCreatures = toTile->getCreatures()) {
                for (Creature* tileCreature : *tileCreatures) {
                    if (!tileCreature->isInGhostMode()) {
                        player->sendCancelMessage(RETURNVALUE_NOTENOUGHROOM);
                        return;
                    }
                }
            }

            Npc* movingNpc = movingCreature->getNpc();
            if (movingNpc && !Spawns::isInZone(movingNpc->getMasterPos(), movingNpc->getMasterRadius(), toPos)) {
                player->sendCancelMessage(RETURNVALUE_NOTENOUGHROOM);
                return;
            }
        }
    }

    if (!g_events->eventPlayerOnMoveCreature(player, movingCreature, movingCreaturePos, toPos)) {
        return;
    }

    ReturnValue ret = internalMoveCreature(*movingCreature, *toTile);
    if (ret != RETURNVALUE_NOERROR) {
        player->sendCancelMessage(ret);
    }
}

ReturnValue Game::internalMoveCreature(Creature* creature, Direction direction, uint32_t flags /*= 0*/)
{
    creature->setLastPosition(creature->getPosition());
    const Position& currentPos = creature->getPosition();
    Position destPos = getNextPosition(direction, currentPos);
    Player* player = creature->getPlayer();

    bool diagonalMovement = (direction & DIRECTION_DIAGONAL_MASK) != 0;
    if (player && !diagonalMovement) {
        //try go up
        if (currentPos.z != 8 && creature->getTile()->hasHeight(3)) {
            Tile* tmpTile = map.getTile(currentPos.x, currentPos.y, currentPos.getZ() - 1);
            if (tmpTile == nullptr || (tmpTile->getGround() == nullptr && !tmpTile->hasFlag(TILESTATE_BLOCKSOLID))) {
                tmpTile = map.getTile(destPos.x, destPos.y, destPos.getZ() - 1);
                if (tmpTile && tmpTile->getGround() && !tmpTile->hasFlag(TILESTATE_BLOCKSOLID)) {
                    flags |= FLAG_IGNOREBLOCKITEM | FLAG_IGNOREBLOCKCREATURE;

                    if (!tmpTile->hasFlag(TILESTATE_FLOORCHANGE)) {
                        player->setDirection(direction);
                        destPos.z--;
                    }
                }
            }
        }

        //try go down
        if (currentPos.z != 7 && currentPos.z == destPos.z) {
            Tile* tmpTile = map.getTile(destPos.x, destPos.y, destPos.z);
            if (tmpTile == nullptr || (tmpTile->getGround() == nullptr && !tmpTile->hasFlag(TILESTATE_BLOCKSOLID))) {
                tmpTile = map.getTile(destPos.x, destPos.y, destPos.z + 1);
                if (tmpTile && tmpTile->hasHeight(3)) {
                    flags |= FLAG_IGNOREBLOCKITEM | FLAG_IGNOREBLOCKCREATURE;
                    player->setDirection(direction);
                    destPos.z++;
                }
            }
        }
    }

    Tile* toTile = map.getTile(destPos);
    if (!toTile) {
        return RETURNVALUE_NOTPOSSIBLE;
    }
    return internalMoveCreature(*creature, *toTile, flags);
}

ReturnValue Game::internalMoveCreature(Creature& creature, Tile& toTile, uint32_t flags /*= 0*/)
{
    //check if we can move the creature to the destination
    ReturnValue ret = toTile.queryAdd(0, creature, 1, flags);
    if (ret != RETURNVALUE_NOERROR) {
        return ret;
    }

    map.moveCreature(creature, toTile);
    if (creature.getParent() != &toTile) {
        return RETURNVALUE_NOERROR;
    }

    int32_t index = 0;
    Item* toItem = nullptr;
    Tile* subCylinder = nullptr;
    Tile* toCylinder = &toTile;
    Tile* fromCylinder = nullptr;
    uint32_t n = 0;

    while ((subCylinder = toCylinder->queryDestination(index, creature, &toItem, flags)) != toCylinder) {
        map.moveCreature(creature, *subCylinder);

        if (creature.getParent() != subCylinder) {
            //could happen if a script move the creature
            fromCylinder = nullptr;
            break;
        }

        fromCylinder = toCylinder;
        toCylinder = subCylinder;
        flags = 0;

        //to prevent infinite loop
        if (++n >= MAP_MAX_LAYERS) {
            break;
        }
    }

    if (fromCylinder) {
        const Position& fromPosition = fromCylinder->getPosition();
        const Position& toPosition = toCylinder->getPosition();
        if (fromPosition.z != toPosition.z && (fromPosition.x != toPosition.x || fromPosition.y != toPosition.y)) {
            Direction dir = getDirectionTo(fromPosition, toPosition);
            if ((dir & DIRECTION_DIAGONAL_MASK) == 0) {
                internalCreatureTurn(&creature, dir);
            }
        }
    }

    return RETURNVALUE_NOERROR;
}
 
Solution
in data/events/scripts/player.lua replace Player:onMoveCreature function with this one
Lua:
function Player:onMoveCreature(creature, fromPosition, toPosition)
    if player:getStorageValue(xxxxx) == 1 then
        return false
    end
    return true
end
replace xxxxxwith any storage you want.
and also enable this in data/events/events.xml
XML:
<event class="Player" method="onMoveCreature" enabled="1" />
in data/events/scripts/player.lua replace Player:onMoveCreature function with this one
Lua:
function Player:onMoveCreature(creature, fromPosition, toPosition)
    if player:getStorageValue(xxxxx) == 1 then
        return false
    end
    return true
end
replace xxxxxwith any storage you want.
and also enable this in data/events/events.xml
XML:
<event class="Player" method="onMoveCreature" enabled="1" />
 
Solution
in data/events/scripts/player.lua replace Player:onMoveCreature function with this one
Lua:
function Player:onMoveCreature(creature, fromPosition, toPosition)
    if player:getStorageValue(xxxxx) == 1 then
        return false
    end
    return true
end
replace xxxxxwith any storage you want.
and also enable this in data/events/events.xml
XML:
<event class="Player" method="onMoveCreature" enabled="1" />

Thx man, i'm trying to use TFS 1.3 and her functions ...
I've tried early to use (player.lua) but i didn't know how need enable the function before.

It works perfectly.

Ps: I've changed if player to if creature, to work.
 
Back
Top