• 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 0.X elevation system bug

zabuzo

Well-Known Member
Joined
Jun 10, 2016
Messages
238
Reaction score
54
I'm using the elevation system to make the famous parcel trap:

Its just this 3 changes made by mkalo:

Game.cpp:

Code:
ReturnValue Game::internalMoveCreature(Creature* actor, Creature* creature, Cylinder* fromCylinder, Cylinder* toCylinder, uint32_t flags/* = 0*/)
{
    //check if we can move the creature to the destination
    ReturnValue ret = toCylinder->__queryAdd(0, creature, 1, flags);
    if(ret != RET_NOERROR)
        return ret;

    //height check
    Tile* toTile = toCylinder->getTile();
    Tile* fromTile = fromCylinder->getTile();
    if(toTile->getHeight() - fromTile->getHeight() >= 2) {
        return RET_NOTPOSSIBLE;
    }
  
    fromCylinder->getTile()->moveCreature(actor, creature, toCylinder);
  
    if(creature->getParent() != toCylinder)
        return RET_NOERROR;

    Item* toItem = NULL;
    Cylinder* subCylinder = NULL;
  
    int32_t n = 0, tmp = 0;
    while((subCylinder = toCylinder->__queryDestination(tmp, creature, &toItem, flags)) != toCylinder)
    {
        toCylinder->getTile()->moveCreature(actor, creature, subCylinder);
        if(creature->getParent() != subCylinder) //could happen if a script move the creature
             break;

        toCylinder = subCylinder;
        flags = 0;
        if(++n >= MAP_MAX_LAYERS) //to prevent infinite loop
            break;
    }


    return RET_NOERROR;
}


Tile.cpp:

Code:
int32_t Tile::getHeight() {
    int32_t height = 0;
    if(ground) {
        if(ground->hasProperty(HASHEIGHT)) {
            ++height;
        }
    }

    if(const TileItemVector* items = getItemList()) {
        for(ItemVector::const_iterator it = items->begin(); it != items->end(); ++it) {
            if((*it)->hasProperty(HASHEIGHT)) {
                ++height;
            }
        }
    }

    return height;
}

Tile.h:
Code:
int32_t getHeight();


But there is a bug to get down on montains

I mean, i can get up normally
as u can see on this imgs:

But i cant get down, with 3,4 parcels, nothing works

Why?
 
Solution
@zabuzo Looking in the repo you've linked - there's a method getPosition() in Cylinder class, and Position has members x, y, z.
So you can try something like this:
Code:
//height check
Tile* toTile = toCylinder->getTile();
Tile* fromTile = fromCylinder->getTile();
Position toPos = toCylinder->getPosition();
Position fromPos = fromCylinder->getPosition();
if((toTile->getHeight() - fromTile->getHeight() >= 2) && (toPos.z == fromPos.z)) {
    return RET_NOTPOSSIBLE;
}
That should do the job, but as I said, I'm not working with these sources myself, so can't tell exactly.

Because height of the square you're trying to go to is much greater than the height of your current square. You'd probably be able to go down, if you stood on atleast 2 parcels too.

Just add a second condition to that if:
Code:
if((toTile->getHeight() - fromTile->getHeight() >= 2) && (toTile->getZ() == fromTile->getZ()) {
        return RET_NOTPOSSIBLE;
    }
(getZ is an example, I don't know the actual name of a function that returns Z coordinate of a tile in tfs)
 
Because height of the square you're trying to go to is much greater than the height of your current square. You'd probably be able to go down, if you stood on atleast 2 parcels too.

Just add a second condition to that if:
Code:
if((toTile->getHeight() - fromTile->getHeight() >= 2) && (toTile->getZ() == fromTile->getZ()) {
        return RET_NOTPOSSIBLE;
    }
(getZ is an example, I don't know the actual name of a function that returns Z coordinate of a tile in tfs)

Code:
game.cpp: In member function ‘ReturnValue Game::internalMoveCreature(Creature*, Creature*, Cylinder*, Cylinder*, uint32_t, bool)’:
game.cpp:1258:71: error: ‘class Tile’ has no member named ‘getZ’; did you mean ‘getZone’?
     if((toTile->getHeight() - fromTile->getHeight() >= 2) && (toTile->getZ() == fromTile->getZ()) ) {
                                                                       ^~~~
game.cpp:1258:91: error: ‘class Tile’ has no member named ‘getZ’; did you mean ‘getZone’?
     if((toTile->getHeight() - fromTile->getHeight() >= 2) && (toTile->getZ() == fromTile->getZ()) ) {
                                                                                           ^~~~
Makefile:33: recipe for target 'game.o' failed

Is it getZ?
How can i get this function names?
 
It's not getZ(), that's only how I named it, cause I don't know the actual name of the function. It's your sources, so you should know. I wrote it as an example just to give you the idea - you need to somehow extract Z coordinate of these two tiles ("from" and "to") and check if they are equal, so stack of parcels will then only block walking on the same floor.
 
It's not getZ(), that's only how I named it, cause I don't know the actual name of the function. It's your sources, so you should know. I wrote it as an example just to give you the idea - you need to somehow extract Z coordinate of these two tiles ("from" and "to") and check if they are equal, so stack of parcels will then only block walking on the same floor.

Hmmm now i gottcha, thank you so much at last now i know what is the problem...

But i never did such a thing like this, this system i take from this forum

How can i get functions like that on C++?

I mean, when i need to make a script for LUA i always found functions to LUA here:

Where should i get functions like that on C++ to get player pos Z?
 
@zabuzo Looking in the repo you've linked - there's a method getPosition() in Cylinder class, and Position has members x, y, z.
So you can try something like this:
Code:
//height check
Tile* toTile = toCylinder->getTile();
Tile* fromTile = fromCylinder->getTile();
Position toPos = toCylinder->getPosition();
Position fromPos = fromCylinder->getPosition();
if((toTile->getHeight() - fromTile->getHeight() >= 2) && (toPos.z == fromPos.z)) {
    return RET_NOTPOSSIBLE;
}
That should do the job, but as I said, I'm not working with these sources myself, so can't tell exactly.
 
Last edited:
Solution
@zabuzo Looking in the repo you've linked - there's a method getPosition() in Cylinder class, and Position has members x, y, z.
So you can try something like this:
Code:
//height check
Tile* toTile = toCylinder->getTile();
Tile* fromTile = fromCylinder->getTile();
Position toPos = toCylinder->getPosition();
Position fromPos = fromCylinder->getPosition();
if((toTile->getHeight() - fromTile->getHeight() >= 2) && (toPos.z == fromPos.z)) {
    return RET_NOTPOSSIBLE;
}
That should do the job, but as I said, I'm not working with these sources myself, so can't tell exactly.

that was it, u fix the problem
thank you so much!
 
Back
Top