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

Parcel trap 8.6 - 0.4

zabuzo

Well-Known Member
Joined
Jun 10, 2016
Messages
238
Reaction score
54
What i need to search/change in my sources to make parcel traps like was on old tibia

Should be amazing play anothers 8.60 having it :D

Example like was on 7.4 (what i want put in my 8.60)
 
Solution
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...
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();
 
Solution
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();


My mistake?
Code:
game.cpp:1247:13: error: prototype for ‘ReturnValue Game::internalMoveCreature(Creature*, Creature*, Cylinder*, Cylinder*, uint32_t)’ does not match any in class ‘Game’
 ReturnValue Game::internalMoveCreature(Creature* actor, Creature* creature, Cylinder* fromCylinder, Cylinder* toCylinder, uint32_t flags/* = 0*/)
  ^
In file included from game.cpp:18:0:
game.h:346:15: error: candidates are: ReturnValue Game::internalMoveCreature(Creature*, Creature*, Cylinder*, Cylinder*, uint32_t, bool)
  ReturnValue internalMoveCreature(Creature* actor, Creature* creature, Cylinder* fromCylinder,
  ^
game.cpp:1199:13: error:  ReturnValue Game::internalMoveCreature(Creature*, Direction, uint32_t)
 ReturnValue Game::internalMoveCreature(Creature* creature, Direction direction, uint32_t flags/* = 0*/)
  ^
 
My mistake?
Code:
game.cpp:1247:13: error: prototype for ‘ReturnValue Game::internalMoveCreature(Creature*, Creature*, Cylinder*, Cylinder*, uint32_t)’ does not match any in class ‘Game’
ReturnValue Game::internalMoveCreature(Creature* actor, Creature* creature, Cylinder* fromCylinder, Cylinder* toCylinder, uint32_t flags/* = 0*/)
  ^
In file included from game.cpp:18:0:
game.h:346:15: error: candidates are: ReturnValue Game::internalMoveCreature(Creature*, Creature*, Cylinder*, Cylinder*, uint32_t, bool)
  ReturnValue internalMoveCreature(Creature* actor, Creature* creature, Cylinder* fromCylinder,
  ^
game.cpp:1199:13: error:  ReturnValue Game::internalMoveCreature(Creature*, Direction, uint32_t)
ReturnValue Game::internalMoveCreature(Creature* creature, Direction direction, uint32_t flags/* = 0*/)
  ^
Because your Game::internalMoveCreature was not the same and you shouldn't just copy paste but see the changes and do it in yours.
 
Because your Game::internalMoveCreature was not the same and you shouldn't just copy paste but see the changes and do it in yours.

There is 2: ReturnValue Game::internalMoveCreature

What is it? What i edit?

1199:
Code:
ReturnValue Game::internalMoveCreature(Creature* creature, Direction direction, uint32_t flags/* = 0*/)
{
   const Position& currentPos = creature->getPosition();
   Cylinder* fromTile = creature->getTile();
   Cylinder* toTile = NULL;

   Position destPos = getNextPosition(direction, currentPos);
   if(direction < SOUTHWEST && creature->getPlayer())
   {
     Tile* tmpTile = NULL;
     if(currentPos.z != 8 && creature->getTile()->hasHeight(3)) //try go up
     {
       if((!(tmpTile = map->getTile(Position(currentPos.x, currentPos.y, currentPos.z - 1)))
         || (!tmpTile->ground && !tmpTile->hasProperty(BLOCKSOLID))) &&
         (tmpTile = map->getTile(Position(destPos.x, destPos.y, destPos.z - 1)))
         && tmpTile->ground && !tmpTile->hasProperty(BLOCKSOLID))
       {
         flags = flags | FLAG_IGNOREBLOCKITEM | FLAG_IGNOREBLOCKCREATURE;
         if(!tmpTile->floorChange())
           destPos.z--;
       }
     }
     else if(currentPos.z != 7 && (!(tmpTile = map->getTile(destPos)) || (!tmpTile->ground &&
       !tmpTile->hasProperty(BLOCKSOLID))) && (tmpTile = map->getTile(Position(
       destPos.x, destPos.y, destPos.z + 1))) && tmpTile->hasHeight(3)) //try go down
     {
       flags = flags | FLAG_IGNOREBLOCKITEM | FLAG_IGNOREBLOCKCREATURE;
       destPos.z++;
     }
   }

   ReturnValue ret = RET_NOTPOSSIBLE;
   if((toTile = map->getTile(destPos)))
     ret = internalMoveCreature(NULL, creature, fromTile, toTile, flags);

   if(ret == RET_NOERROR)
     return RET_NOERROR;

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

   player->sendCancelMessage(ret);
   player->sendCancelWalk();
   return ret;
}

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

   fromCylinder->getTile()->moveCreature(actor, creature, toCylinder, forceTeleport);
   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;
}
 
There is 2: ReturnValue Game::internalMoveCreature

What is it? What i edit?

1199:
Code:
ReturnValue Game::internalMoveCreature(Creature* creature, Direction direction, uint32_t flags/* = 0*/)
{
   const Position& currentPos = creature->getPosition();
   Cylinder* fromTile = creature->getTile();
   Cylinder* toTile = NULL;

   Position destPos = getNextPosition(direction, currentPos);
   if(direction < SOUTHWEST && creature->getPlayer())
   {
     Tile* tmpTile = NULL;
     if(currentPos.z != 8 && creature->getTile()->hasHeight(3)) //try go up
     {
       if((!(tmpTile = map->getTile(Position(currentPos.x, currentPos.y, currentPos.z - 1)))
         || (!tmpTile->ground && !tmpTile->hasProperty(BLOCKSOLID))) &&
         (tmpTile = map->getTile(Position(destPos.x, destPos.y, destPos.z - 1)))
         && tmpTile->ground && !tmpTile->hasProperty(BLOCKSOLID))
       {
         flags = flags | FLAG_IGNOREBLOCKITEM | FLAG_IGNOREBLOCKCREATURE;
         if(!tmpTile->floorChange())
           destPos.z--;
       }
     }
     else if(currentPos.z != 7 && (!(tmpTile = map->getTile(destPos)) || (!tmpTile->ground &&
       !tmpTile->hasProperty(BLOCKSOLID))) && (tmpTile = map->getTile(Position(
       destPos.x, destPos.y, destPos.z + 1))) && tmpTile->hasHeight(3)) //try go down
     {
       flags = flags | FLAG_IGNOREBLOCKITEM | FLAG_IGNOREBLOCKCREATURE;
       destPos.z++;
     }
   }

   ReturnValue ret = RET_NOTPOSSIBLE;
   if((toTile = map->getTile(destPos)))
     ret = internalMoveCreature(NULL, creature, fromTile, toTile, flags);

   if(ret == RET_NOERROR)
     return RET_NOERROR;

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

   player->sendCancelMessage(ret);
   player->sendCancelWalk();
   return ret;
}

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

   fromCylinder->getTile()->moveCreature(actor, creature, toCylinder, forceTeleport);
   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;
}
Well the second one, if it doesnt work you probably have to edit both.
 
Well the second one, if it doesnt work you probably have to edit both.

Ty...
You mean this?
Code:
ReturnValue Game::internalMoveCreature(Creature* creature, Direction direction, uint32_t flags/* = 0*/)
{
   const Position& currentPos = creature->getPosition();
   Cylinder* fromTile = creature->getTile();
   Cylinder* toTile = NULL;

   Position destPos = getNextPosition(direction, currentPos);
   if(direction < SOUTHWEST && creature->getPlayer())
   {
     Tile* tmpTile = NULL;
     if(currentPos.z != 8 && creature->getTile()->hasHeight(3)) //try go up
     {
       if((!(tmpTile = map->getTile(Position(currentPos.x, currentPos.y, currentPos.z - 1)))
         || (!tmpTile->ground && !tmpTile->hasProperty(BLOCKSOLID))) &&
         (tmpTile = map->getTile(Position(destPos.x, destPos.y, destPos.z - 1)))
         && tmpTile->ground && !tmpTile->hasProperty(BLOCKSOLID))
       {
         flags = flags | FLAG_IGNOREBLOCKITEM | FLAG_IGNOREBLOCKCREATURE;
         if(!tmpTile->floorChange())
           destPos.z--;
       }
     }
     else if(currentPos.z != 7 && (!(tmpTile = map->getTile(destPos)) || (!tmpTile->ground &&
       !tmpTile->hasProperty(BLOCKSOLID))) && (tmpTile = map->getTile(Position(
       destPos.x, destPos.y, destPos.z + 1))) && tmpTile->hasHeight(3)) //try go down
     {
       flags = flags | FLAG_IGNOREBLOCKITEM | FLAG_IGNOREBLOCKCREATURE;
       destPos.z++;
     }
   }

   ReturnValue ret = RET_NOTPOSSIBLE;
   if((toTile = map->getTile(destPos)))
     ret = internalMoveCreature(NULL, creature, fromTile, toTile, flags);

   if(ret == RET_NOERROR)
     return RET_NOERROR;

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

   player->sendCancelMessage(ret);
   player->sendCancelWalk();
   return ret;
}

ReturnValue Game::internalMoveCreature(Creature* actor, Creature* creature, Cylinder* fromCylinder,
   Cylinder* toCylinder, uint32_t flags/* = 0*/, bool forceTeleport/* = false*/)
{
   //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, forceTeleport);
   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;
}

Code:
game.cpp: In member function ‘ReturnValue Game::internalMoveCreature(Creature*, Creature*, Cylinder*, Cylinder*, uint32_t, bool)’:
game.cpp:1257:16: error: ‘class Tile’ has no member named ‘getHeight’
  if(toTile->getHeight() - fromTile->getHeight() >= 2) {
  ^
game.cpp:1257:40: error: ‘class Tile’ has no member named ‘getHeight’
  if(toTile->getHeight() - fromTile->getHeight() >= 2) {
  ^
Makefile:546: recipe for target 'game.o' failed
make[1]: *** [game.o] Error 1


====================================================================
or this?
====================================================================

Code:
ReturnValue Game::internalMoveCreature(Creature* creature, Direction direction, uint32_t flags/* = 0*/)
{
   const Position& currentPos = creature->getPosition();
   Cylinder* fromTile = creature->getTile();
   Cylinder* toTile = NULL;

  //height check
  Tile* toTile = toCylinder->getTile();
  Tile* fromTile = fromCylinder->getTile();
  if(toTile->getHeight() - fromTile->getHeight() >= 2) {
  return RET_NOTPOSSIBLE;
  }

   Position destPos = getNextPosition(direction, currentPos);
   if(direction < SOUTHWEST && creature->getPlayer())
   {
     Tile* tmpTile = NULL;
     if(currentPos.z != 8 && creature->getTile()->hasHeight(3)) //try go up
     {
       if((!(tmpTile = map->getTile(Position(currentPos.x, currentPos.y, currentPos.z - 1)))
         || (!tmpTile->ground && !tmpTile->hasProperty(BLOCKSOLID))) &&
         (tmpTile = map->getTile(Position(destPos.x, destPos.y, destPos.z - 1)))
         && tmpTile->ground && !tmpTile->hasProperty(BLOCKSOLID))
       {
         flags = flags | FLAG_IGNOREBLOCKITEM | FLAG_IGNOREBLOCKCREATURE;
         if(!tmpTile->floorChange())
           destPos.z--;
       }
     }
     else if(currentPos.z != 7 && (!(tmpTile = map->getTile(destPos)) || (!tmpTile->ground &&
       !tmpTile->hasProperty(BLOCKSOLID))) && (tmpTile = map->getTile(Position(
       destPos.x, destPos.y, destPos.z + 1))) && tmpTile->hasHeight(3)) //try go down
     {
       flags = flags | FLAG_IGNOREBLOCKITEM | FLAG_IGNOREBLOCKCREATURE;
       destPos.z++;
     }
   }

   ReturnValue ret = RET_NOTPOSSIBLE;
   if((toTile = map->getTile(destPos)))
     ret = internalMoveCreature(NULL, creature, fromTile, toTile, flags);

   if(ret == RET_NOERROR)
     return RET_NOERROR;

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

   player->sendCancelMessage(ret);
   player->sendCancelWalk();
   return ret;
}

ReturnValue Game::internalMoveCreature(Creature* actor, Creature* creature, Cylinder* fromCylinder,
   Cylinder* toCylinder, uint32_t flags/* = 0*/, bool forceTeleport/* = false*/)
{
   //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, forceTeleport);
   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;
}


Code:
game.cpp: In member function ‘ReturnValue Game::internalMoveCreature(Creature*, Direction, uint32_t)’:
game.cpp:1206:11: error: conflicting declaration ‘Tile* toTile’
  Tile* toTile = toCylinder->getTile();
  ^
game.cpp:1203:12: note: previous declaration as ‘Cylinder* toTile’
  Cylinder* toTile = NULL;
  ^
game.cpp:1206:20: error: ‘toCylinder’ was not declared in this scope
  Tile* toTile = toCylinder->getTile();
  ^
game.cpp:1207:11: error: conflicting declaration ‘Tile* fromTile’
  Tile* fromTile = fromCylinder->getTile();
  ^
game.cpp:1202:12: note: previous declaration as ‘Cylinder* fromTile’
  Cylinder* fromTile = creature->getTile();
  ^
game.cpp:1207:22: error: ‘fromCylinder’ was not declared in this scope
  Tile* fromTile = fromCylinder->getTile();
  ^
game.cpp:1208:16: error: ‘class Cylinder’ has no member named ‘getHeight’
  if(toTile->getHeight() - fromTile->getHeight() >= 2) {
  ^
game.cpp:1208:40: error: ‘class Cylinder’ has no member named ‘getHeight’
  if(toTile->getHeight() - fromTile->getHeight() >= 2) {
  ^
game.cpp: In member function ‘ReturnValue Game::internalMoveCreature(Creature*, Creature*, Cylinder*, Cylinder*, uint32_t, bool)’:
game.cpp:1264:16: error: ‘class Tile’ has no member named ‘getHeight’
  if(toTile->getHeight() - fromTile->getHeight() >= 2) {
  ^
game.cpp:1264:40: error: ‘class Tile’ has no member named ‘getHeight’
  if(toTile->getHeight() - fromTile->getHeight() >= 2) {
  ^
Makefile:546: recipe for target 'game.o' failed
make[1]: *** [game.o] Error 1
 
Last edited:
U mean it?
Code:
class Tile : public Cylinder
{
   public:
     static Tile& nullTile;
     Tile(uint16_t x, uint16_t y, uint16_t z);
     virtual ~Tile();

     TileItemVector* getItemList();
     const TileItemVector* getItemList() const;
     TileItemVector* makeItemList();

     CreatureVector* getCreatures();
     const CreatureVector* getCreatures() const;
     CreatureVector* makeCreatures();

     HouseTile* getHouseTile();
     const HouseTile* getHouseTile() const;
     bool isHouseTile() const {return hasFlag(TILESTATE_HOUSE);}

     MagicField* getFieldItem() const;
     Teleport* getTeleportItem() const;
     TrashHolder* getTrashHolder() const;
     Mailbox* getMailbox() const;
     BedItem* getBedItem() const;

     Creature* getTopCreature();
     Item* getTopTopItem();
     Item* getTopDownItem();
     bool isMoveableBlocking() const;
     Thing* getTopVisibleThing(const Creature* creature);
     Creature* getTopVisibleCreature(const Creature* creature);
     const Creature* getTopVisibleCreature(const Creature* creature) const;
     Item* getItemByTopOrder(uint32_t topOrder);

     uint32_t getThingCount() const {return thingCount;}
     uint32_t getCreatureCount() const;
     uint32_t getItemCount() const;
     uint32_t getTopItemCount() const;
     uint32_t getDownItemCount() const;

     int32_t getHeight(); // elevation system

     bool hasProperty(enum ITEMPROPERTY prop) const;
     bool hasProperty(Item* exclude, enum ITEMPROPERTY prop) const;

     bool hasFlag(tileflags_t flag) const {return ((m_flags & (uint32_t)flag) == (uint32_t)flag);}
     void setFlag(tileflags_t flag) {m_flags |= (uint32_t)flag;}
     void resetFlag(tileflags_t flag) {m_flags &= ~(uint32_t)flag;}

     bool positionChange() const {return hasFlag(TILESTATE_TELEPORT);}
     bool floorChange(FloorChange_t change = CHANGE_NONE) const
     {
       switch(change)
       {
         case CHANGE_DOWN:
           return hasFlag(TILESTATE_FLOORCHANGE_DOWN);
         case CHANGE_NORTH:
           return hasFlag(TILESTATE_FLOORCHANGE_NORTH);
         case CHANGE_SOUTH:
           return hasFlag(TILESTATE_FLOORCHANGE_SOUTH);
         case CHANGE_EAST:
           return hasFlag(TILESTATE_FLOORCHANGE_EAST);
         case CHANGE_WEST:
           return hasFlag(TILESTATE_FLOORCHANGE_WEST);
         case CHANGE_NORTH_EX:
           return hasFlag(TILESTATE_FLOORCHANGE_NORTH_EX);
         case CHANGE_SOUTH_EX:
           return hasFlag(TILESTATE_FLOORCHANGE_SOUTH_EX);
         case CHANGE_EAST_EX:
           return hasFlag(TILESTATE_FLOORCHANGE_EAST_EX);
         case CHANGE_WEST_EX:
           return hasFlag(TILESTATE_FLOORCHANGE_WEST_EX);
         case CHANGE_NONE:
           return hasFlag(TILESTATE_FLOORCHANGE);
         default:
           break;
       }

       return false;
     }

     ZoneType_t getZone() const
     {
       if(hasFlag(TILESTATE_PROTECTIONZONE))
         return ZONE_PROTECTION;

       if(hasFlag(TILESTATE_OPTIONALZONE))
         return ZONE_OPTIONAL;

       if(hasFlag(TILESTATE_HARDCOREZONE))
         return ZONE_HARDCORE;

       return ZONE_OPEN;
     }

     bool hasHeight(uint32_t n) const;
     void moveCreature(Creature* actor, Creature* creature, Cylinder* toCylinder, bool forceTeleport = false);
     int32_t getClientIndexOfThing(const Player* player, const Thing* thing) const;

     //cylinder implementations
     virtual Cylinder* getParent() {return NULL;}
     virtual const Cylinder* getParent() const {return NULL;}
     virtual bool isRemoved() const {return false;}
     virtual Position getPosition() const {return pos;}
     virtual Tile* getTile() {return this;}
     virtual const Tile* getTile() const {return this;}
     virtual Item* getItem() {return NULL;}
     virtual const Item* getItem() const {return NULL;}
     virtual Creature* getCreature() {return NULL;}
     virtual const Creature* getCreature() const {return NULL;}

     virtual ReturnValue __queryAdd(int32_t index, const Thing* thing, uint32_t count,
       uint32_t flags) const;
     virtual ReturnValue __queryMaxCount(int32_t index, const Thing* thing, uint32_t count,
       uint32_t& maxQueryCount, uint32_t flags) const;
     virtual ReturnValue __queryRemove(const Thing* thing, uint32_t count, uint32_t flags) const;
     virtual Cylinder* __queryDestination(int32_t& index, const Thing* thing, Item** destItem,
       uint32_t& flags);

     virtual void __addThing(Creature* actor, Thing* thing) {__addThing(actor, 0, thing);}
     virtual void __addThing(Creature* actor, int32_t index, Thing* thing);

     virtual void __updateThing(Thing* thing, uint16_t itemId, uint32_t count);
     virtual void __replaceThing(uint32_t index, Thing* thing);

     virtual void __removeThing(Thing* thing, uint32_t count);

     virtual int32_t __getIndexOfThing(const Thing* thing) const;
     virtual int32_t __getFirstIndex() const {return 0;}
     virtual int32_t __getLastIndex() const {return thingCount;}
     virtual uint32_t __getItemTypeCount(uint16_t itemId, int32_t subType = -1) const;
     virtual Thing* __getThing(uint32_t index) const;

     virtual void postAddNotification(Creature* actor, Thing* thing, const Cylinder* oldParent,
       int32_t index, cylinderlink_t link = LINK_OWNER);
     virtual void postRemoveNotification(Creature* actor, Thing* thing, const Cylinder* newParent,
       int32_t index, bool isCompleteRemoval, cylinderlink_t link = LINK_OWNER);

     virtual void __internalAddThing(Thing* thing) {__internalAddThing(0, thing);}
     virtual void __internalAddThing(uint32_t index, Thing* thing);
     void onUpdateTile();

   private:
     void onAddTileItem(Item* item);
     void onUpdateTileItem(Item* oldItem, const ItemType& oldType, Item* newItem, const ItemType& newType);
     void onRemoveTileItem(const SpectatorVec& list, std::vector<int32_t>& oldStackPosVector, Item* item);

     void updateTileFlags(Item* item, bool remove);

   protected:
     bool isDynamic() const {return (m_flags & TILESTATE_DYNAMIC_TILE);}

   public:
     QTreeLeafNode* qt_node;
     Item* ground;

   protected:
     Position pos;
     uint32_t m_flags, thingCount;
};

Code:
ame.cpp: In member function ‘ReturnValue Game::internalMoveCreature(Creature*, Direction, uint32_t)’:
game.cpp:1206:11: error: conflicting declaration ‘Tile* toTile’
  Tile* toTile = toCylinder->getTile();
  ^
game.cpp:1203:12: note: previous declaration as ‘Cylinder* toTile’
  Cylinder* toTile = NULL;
  ^
game.cpp:1206:20: error: ‘toCylinder’ was not declared in this scope
  Tile* toTile = toCylinder->getTile();
  ^
game.cpp:1207:11: error: conflicting declaration ‘Tile* fromTile’
  Tile* fromTile = fromCylinder->getTile();
  ^
game.cpp:1202:12: note: previous declaration as ‘Cylinder* fromTile’
  Cylinder* fromTile = creature->getTile();
  ^
game.cpp:1207:22: error: ‘fromCylinder’ was not declared in this scope
  Tile* fromTile = fromCylinder->getTile();
  ^
game.cpp:1208:16: error: ‘class Cylinder’ has no member named ‘getHeight’
  if(toTile->getHeight() - fromTile->getHeight() >= 2) {
  ^
game.cpp:1208:40: error: ‘class Cylinder’ has no member named ‘getHeight’
  if(toTile->getHeight() - fromTile->getHeight() >= 2) {
  ^
mv -f .deps/dispatcher.Tpo .deps/dispatcher.Po
g++ -DHAVE_CONFIG_H -I.  -I/usr/include/libxml2  -I/usr/include/lua5.1  -O2 -fomit-frame-pointer -D__USE_MYSQL__  -D__ENABLE_SERVER_DIAGNOSTIC__ -D__ROOT_PERMISSION__ -D_THREAD_SAFE -D_REENTRANT -Wall -Wextra -Wno-strict-aliasing -Wno-unused-parameter -Wno-array-bounds -pthread -pipe -MT house.o -MD -MP -MF .deps/house.Tpo -c -o house.o house.cpp
Makefile:546: recipe for target 'game.o' failed
make[1]: *** [game.o] Error 1
 
Last edited:
U mean it?

I said... you should add it to "ReturnValue Game::internalMoveCreature(Creature* actor, Creature* creature, Cylinder* fromCylinder,
Cylinder* toCylinder, uint32_t flags/* = 0*/, bool forceTeleport/* = false*/)"

NOT "ReturnValue Game::internalMoveCreature(Creature*, Direction, uint32_t)"

Code:
ReturnValue Game::internalMoveCreature(Creature* actor, Creature* creature, Cylinder* fromCylinder,
   Cylinder* toCylinder, uint32_t flags/* = 0*/, bool forceTeleport/* = false*/)
{
   //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, forceTeleport);
   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;
}
 
I said... you should add it to "ReturnValue Game::internalMoveCreature(Creature* actor, Creature* creature, Cylinder* fromCylinder,
Cylinder* toCylinder, uint32_t flags/* = 0*/, bool forceTeleport/* = false*/)"

NOT "ReturnValue Game::internalMoveCreature(Creature*, Direction, uint32_t)"

Code:
ReturnValue Game::internalMoveCreature(Creature* actor, Creature* creature, Cylinder* fromCylinder,
   Cylinder* toCylinder, uint32_t flags/* = 0*/, bool forceTeleport/* = false*/)
{
   //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, forceTeleport);
   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;
}


I dont understand, srry, show me pls ( i made some changins)

game.cpp
http://hastebin.com/risowicaki.cpp

tile.h
http://hastebin.com/otuxuteqoj.cpp

tile.cpp
http://hastebin.com/pehajopayu.cpp

I coment the changes to 'elevation'
 
I dont understand, srry, show me pls ( i made some changins)

game.cpp
http://hastebin.com/risowicaki.cpp

tile.h
http://hastebin.com/otuxuteqoj.cpp

tile.cpp
http://hastebin.com/pehajopayu.cpp

I coment the changes to 'elevation'
WHY ARE YOU CHANGING "ReturnValue Game::internalMoveCreature(Creature* creature, Direction direction, uint32_t flags/* = 0*/)"

I CLEARLY SAID TO EDIT ONLY AND ONLY "ReturnValue Game::internalMoveCreature(Creature* actor, Creature* creature, Cylinder* fromCylinder, Cylinder* toCylinder, uint32_t flags/* = 0*/, bool forceTeleport/* = false*/)"

Remove EVERYTHING that you put into "ReturnValue Game::internalMoveCreature(Creature* creature, Direction direction, uint32_t flags/* = 0*/)"
 
How to fix UH Trap and Parcel Trap: (OTServ_SVN, don't know how it works in TFS)

game.cpp
Code:
Thing* Game::internalGetThing(Player* player, const Position& pos, int32_t index,
    uint32_t spriteId /*= 0*/, stackPosType_t type /*= STACKPOS_NORMAL*/)
{
    if(pos.x != 0xFFFF){
        Tile* tile = getTile(pos.x, pos.y, pos.z);

        if(tile){
            /*look at*/
            if(type == STACKPOS_LOOK){
                return tile->getTopThing();
            }

            Thing* thing = NULL;

            /*for move operations*/
            if(type == STACKPOS_MOVE){
                Item* item = tile->getTopDownItem();
                if(item && !item->isNotMoveable())
                    thing = item;
                else
                    thing = tile->getTopCreature();
            }
            /*use item*/
            else if(type == STACKPOS_USE){
                thing = tile->getTopDownItem();
            }
            else if(type == STACKPOS_USEITEM){
                //First check items with topOrder 2 (ladders, signs, splashes)
                Item* item =  tile->getItemByTopOrder(1);
                if(item && g_actions->hasAction(item)){
                    thing = item;
                }
                else{
                    //then down items
                    thing = tile->getTopDownItem();
                    if(thing == NULL){
                        //then last we check items with topOrder 3 (doors etc)
                        thing = tile->getTopTopItem();
                    }
                }
            }
            else{
                thing = tile->__getThing(index);
            }

            if(player){
                //do extra checks here if the thing is accessable
                if(thing && thing->getItem()){
                    if(tile->hasProperty(ISVERTICAL)){
                        if(player->getPosition().x + 1 == tile->getPosition().x){
                            thing = NULL;
                        }
                    }
                    else if(tile->hasProperty(ISHORIZONTAL)){
                        if(player->getPosition().y + 1 == tile->getPosition().y){
                            thing = NULL;
                        }
                    }
                }
            }

            return thing;
        }
    }
    else{
        //container
        if(pos.y & 0x40){
            uint8_t fromCid = pos.y & 0x0F;
            uint8_t slot = pos.z;

            Container* parentcontainer = player->getContainer(fromCid);
            if(!parentcontainer)
                return NULL;

            return parentcontainer->getItem(slot);
        }
        else if(pos.y == 0 && pos.z == 0){
            const ItemType& it = Item::items.getItemIdByClientId(spriteId);
            if(it.id == 0){
                return NULL;
            }

            int32_t subType = -1;
            if(it.isFluidContainer()){
                int32_t maxFluidType = sizeof(reverseFluidMap) / sizeof(uint32_t);
                if(index < maxFluidType){
                    subType = reverseFluidMap[index];
                }
            }

            return findItemOfType(player, it.id, true, subType);
        }
        //inventory
        else{
            slots_t slot = (slots_t)static_cast<unsigned char>(pos.y);
            return player->getInventoryItem(slot);
        }
    }

    return NULL;
}

game.cpp
Code:
ReturnValue Game::internalMoveCreature(Creature* creature, Direction direction, uint32_t flags /*= 0*/)
{
    Cylinder* fromTile = creature->getTile();
    Cylinder* toTile = NULL;

    const Position& currentPos = creature->getPosition();
    Position destPos = currentPos;

    bool canChangeFloor = true;
    switch(direction){
        case NORTH:
            destPos.y -= 1;
            break;

        case SOUTH:
            destPos.y += 1;
            break;

        case WEST:
            destPos.x -= 1;
            break;

        case EAST:
            destPos.x += 1;
            break;

        case SOUTHWEST:
            destPos.x -= 1;
            destPos.y += 1;
            canChangeFloor = false;
            break;

        case NORTHWEST:
            destPos.x -= 1;
            destPos.y -= 1;
            canChangeFloor = false;
            break;

        case NORTHEAST:
            destPos.x += 1;
            destPos.y -= 1;
            canChangeFloor = false;
            break;

        case SOUTHEAST:
            destPos.x += 1;
            destPos.y += 1;
            canChangeFloor = false;
            break;
    }

    if(creature->getPlayer() && canChangeFloor){
        //try go up
        if(currentPos.z != 8 && creature->getTile()->hasHeight(3)){
            Tile* tmpTile = map->getTile(currentPos.x, currentPos.y, currentPos.z - 1);
            if(tmpTile == NULL || (tmpTile->ground == NULL && !tmpTile->hasProperty(BLOCKSOLID))){
                tmpTile = map->getTile(destPos.x, destPos.y, destPos.z - 1);
                if(tmpTile && tmpTile->ground && !tmpTile->hasProperty(BLOCKSOLID)){
                    flags = flags | FLAG_IGNOREBLOCKITEM | FLAG_IGNOREBLOCKCREATURE;
                    destPos.z -= 1;
                }
            }
        }
        else{
            //try go down
            Tile* tmpTile = map->getTile(destPos);
            if(currentPos.z != 7 && (tmpTile == NULL || (tmpTile->ground == NULL && !tmpTile->hasProperty(BLOCKSOLID)))){
                tmpTile = map->getTile(destPos.x, destPos.y, destPos.z + 1);

                if(tmpTile && tmpTile->hasHeight(3)){
                    flags = flags | FLAG_IGNOREBLOCKITEM | FLAG_IGNOREBLOCKCREATURE;
                    destPos.z += 1;
                }
            }
        }
    }

    toTile = map->getTile(destPos);
   
    Tile* toPos = getTile(destPos.x, destPos.y, destPos.z);
    Tile* fromPos = getTile(currentPos.x, currentPos.y, currentPos.z);
   
    ReturnValue ret = RET_NOTPOSSIBLE;

    if(toTile != NULL){
        if (currentPos.z > destPos.z && toPos->getHeight() > 1);
            // not possible
        else if ((((toPos->getHeight() - fromPos->getHeight()) < 2)) || 
            (fromPos->hasHeight(3) && (currentPos.z == destPos.z)) ||
            ((currentPos.z < destPos.z) && (toPos->hasHeight(3) && (fromPos->getHeight() < 2))))
            ret = internalMoveCreature(creature, fromTile, toTile, flags);
    }

    if(ret != RET_NOERROR){
        if(Player* player = creature->getPlayer()){
            player->sendCancelMessage(ret);
            player->sendCancelWalk();
        }
    }

    return ret;
}

Tile.cpp:

Change
Code:
uint32_t Tile::getHeight() const

To this:
Code:
int32_t Tile::getHeight() const

Tile.h:

Change this:
Code:
uint32_t getHeight() const;

To this:
Code:
int32_t getHeight() const;
 
WHY ARE YOU CHANGING "ReturnValue Game::internalMoveCreature(Creature* creature, Direction direction, uint32_t flags/* = 0*/)"

I CLEARLY SAID TO EDIT ONLY AND ONLY "ReturnValue Game::internalMoveCreature(Creature* actor, Creature* creature, Cylinder* fromCylinder, Cylinder* toCylinder, uint32_t flags/* = 0*/, bool forceTeleport/* = false*/)"

Remove EVERYTHING that you put into "ReturnValue Game::internalMoveCreature(Creature* creature, Direction direction, uint32_t flags/* = 0*/)"

Matheus your script work to me, but i have a problem...

I can trhow 500 parcel on foot, and to other player get up he need 499 parcels
I want make like is on tibia... Just 4 is the higher...

What is the best way to fix?
 
Matheus your script work to me, but i have a problem...

I can trhow 500 parcel on foot, and to other player get up he need 499 parcels
I want make like is on tibia... Just 4 is the higher...

What is the best way to fix?
In getHeight you return std::max(height, 4)
 
Sorry it's std::min actually :s , you replace return height with return std::min(height, 4 I'm on cellphone can't copy.

I dont understand, sorry

Is this...
tile.cpp
Code:
int32_t Tile::getHeight() {
  int32_t height = 0;
  if(ground) {
  if(ground->hasProperty(HASHEIGHT) && height < 5) {
  ++height;
  }
  }

  if(const TileItemVector* items = getItemList()) {
  for(ItemVector::const_iterator it = items->begin(); it != items->end(); ++it) {
  if((*it)->hasProperty(HASHEIGHT) && height < 5) {
  ++height;
  }
  }
  }
  return height;
}
 
I dont understand, sorry

Is this...
tile.cpp
Code:
int32_t Tile::getHeight() {
  int32_t height = 0;
  if(ground) {
  if(ground->hasProperty(HASHEIGHT) && height < 5) {
  ++height;
  }
  }

  if(const TileItemVector* items = getItemList()) {
  for(ItemVector::const_iterator it = items->begin(); it != items->end(); ++it) {
  if((*it)->hasProperty(HASHEIGHT) && height < 5) {
  ++height;
  }
  }
  }
  return height;
}
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 std::min(height, 4);
}
 
Back
Top