Postado Novembro 6, 2016 8 anos Queria adicionar o maxItemsPerPZTile na minha source, deixar só 5 items por Tile(SQM) como eu coloco nas source ? olha ai meu tile.cpp Citar //////////////////////////////////////////////////////////////////////// // OpenTibia - an opensource roleplaying game //////////////////////////////////////////////////////////////////////// // This program is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with this program. If not, see <http://www.gnu.org/licenses/>. //////////////////////////////////////////////////////////////////////// #include "otpch.h" #include <iostream> #include "tile.h" #include "housetile.h" #include "player.h" #include "creature.h" #include "teleport.h" #include "trashholder.h" #include "mailbox.h" #include "combat.h" #include "movement.h" #include "game.h" #include "configmanager.h" extern ConfigManager g_config; extern Game g_game; extern MoveEvents* g_moveEvents; StaticTile reallyNullTile(0xFFFF, 0xFFFF, 0xFFFF); Tile& Tile::nullTile = reallyNullTile; bool Tile::hasProperty(enum ITEMPROPERTY prop) const { if(ground && ground->hasProperty(prop)) return true; if(const TileItemVector* items = getItemList()) { for(ItemVector::const_iterator it = items->begin(); it != items->end(); ++it) { if((*it)->hasProperty(prop)) return true; } } return false; } bool Tile::hasProperty(Item* exclude, enum ITEMPROPERTY prop) const { assert(exclude); if(ground && exclude != ground && ground->hasProperty(prop)) return true; if(const TileItemVector* items = getItemList()) { Item* item = NULL; for(ItemVector::const_iterator it = items->begin(); it != items->end(); ++it) { if((item = (*it)) && item != exclude && item->hasProperty(prop)) return true; } } return false; } HouseTile* Tile::getHouseTile() { if(isHouseTile()) return static_cast<HouseTile*>(this); return NULL; } const HouseTile* Tile::getHouseTile() const { if(isHouseTile()) return static_cast<const HouseTile*>(this); return NULL; } bool Tile::hasHeight(uint32_t n) const { uint32_t height = 0; if(ground) { if(ground->hasProperty(HASHEIGHT)) ++height; if(n == height) return true; } if(const TileItemVector* items = getItemList()) { for(ItemVector::const_iterator it = items->begin(); it != items->end(); ++it) { if((*it)->hasProperty(HASHEIGHT)) ++height; if(n == height) return true; } } return false; } uint32_t Tile::getCreatureCount() const { if(const CreatureVector* creatures = getCreatures()) return creatures->size(); return 0; } uint32_t Tile::getItemCount() const { if(const TileItemVector* items = getItemList()) return (uint32_t)items->size(); return 0; } uint32_t Tile::getTopItemCount() const { if(const TileItemVector* items = getItemList()) return items->getTopItemCount(); return 0; } uint32_t Tile::getDownItemCount() const { if(const TileItemVector* items =getItemList()) return items->getDownItemCount(); return 0; } Teleport* Tile::getTeleportItem() const { if(!hasFlag(TILESTATE_TELEPORT)) return NULL; if(ground && ground->getTeleport()) return ground->getTeleport(); if(const TileItemVector* items = getItemList()) { for(ItemVector::const_reverse_iterator it = items->rbegin(); it != items->rend(); ++it) { if((*it)->getTeleport()) return (*it)->getTeleport(); } } return NULL; } MagicField* Tile::getFieldItem() const { if(!hasFlag(TILESTATE_MAGICFIELD)) return NULL; if(ground && ground->getMagicField()) return ground->getMagicField(); if(const TileItemVector* items = getItemList()) { for(ItemVector::const_reverse_iterator it = items->rbegin(); it != items->rend(); ++it) { if((*it)->getMagicField()) return (*it)->getMagicField(); } } return NULL; } TrashHolder* Tile::getTrashHolder() const { if(!hasFlag(TILESTATE_TRASHHOLDER)) return NULL; if(ground && ground->getTrashHolder()) return ground->getTrashHolder(); if(const TileItemVector* items = getItemList()) { for(ItemVector::const_reverse_iterator it = items->rbegin(); it != items->rend(); ++it) { if((*it)->getTrashHolder()) return (*it)->getTrashHolder(); } } return NULL; } Mailbox* Tile::getMailbox() const { if(!hasFlag(TILESTATE_MAILBOX)) return NULL; if(ground && ground->getMailbox()) return ground->getMailbox(); if(const TileItemVector* items = getItemList()) { for(ItemVector::const_reverse_iterator it = items->rbegin(); it != items->rend(); ++it) { if((*it)->getMailbox()) return (*it)->getMailbox(); } } return NULL; } BedItem* Tile::getBedItem() const { if(!hasFlag(TILESTATE_BED)) return NULL; if(ground && ground->getBed()) return ground->getBed(); if(const TileItemVector* items = getItemList()) { for(ItemVector::const_reverse_iterator it = items->rbegin(); it != items->rend(); ++it) { if((*it)->getBed()) return (*it)->getBed(); } } return NULL; } Creature* Tile::getTopCreature() { if(CreatureVector* creatures = getCreatures()) { if(!creatures->empty()) return *creatures->begin(); } return NULL; } Item* Tile::getTopDownItem() { if(TileItemVector* items = getItemList()) { if(items->getDownItemCount() > 0) return *items->getBeginDownItem(); } return NULL; } Item* Tile::getTopTopItem() { if(TileItemVector* items = getItemList()) { if(items->getTopItemCount() > 0) return *(items->getEndTopItem() - 1); } return NULL; } Item* Tile::getItemByTopOrder(uint32_t topOrder) { if(TileItemVector* items = getItemList()) { for(ItemVector::reverse_iterator it = ItemVector::reverse_iterator(items->getEndTopItem()), end = ItemVector::reverse_iterator(items->getBeginTopItem()); it != end; ++it) { if(Item::items[(*it)->getID()].alwaysOnTopOrder == (int32_t)topOrder) return (*it); } } return NULL; } Thing* Tile::getTopVisibleThing(const Creature* creature) { if(Creature* _creature = getTopVisibleCreature(creature)) return _creature; if(TileItemVector* items = getItemList()) { for(ItemVector::iterator it = items->getBeginDownItem(); it != items->getEndDownItem(); ++it) { const ItemType& iit = Item::items[(*it)->getID()]; if(!iit.lookThrough) return *it; } for(ItemVector::reverse_iterator it = ItemVector::reverse_iterator(items->getEndTopItem()), end = ItemVector::reverse_iterator(items->getBeginTopItem()); it != end; ++it) { const ItemType& iit = Item::items[(*it)->getID()]; if(!iit.lookThrough) return *it; } } return ground; } Creature* Tile::getTopVisibleCreature(const Creature* creature) { if(CreatureVector* creatures = getCreatures()) { for(CreatureVector::iterator cit = creatures->begin(); cit != creatures->end(); ++cit) { if(creature->canSeeCreature(*cit)) return (*cit); } } return NULL; } const Creature* Tile::getTopVisibleCreature(const Creature* creature) const { if(const CreatureVector* creatures = getCreatures()) { for(CreatureVector::const_iterator cit = creatures->begin(); cit != creatures->end(); ++cit) { if(creature->canSeeCreature(*cit)) return (*cit); } } return NULL; } void Tile::onAddTileItem(Item* item) { updateTileFlags(item, false); const Position& cylinderMapPos = pos; const SpectatorVec& list = g_game.getSpectators(cylinderMapPos); SpectatorVec::const_iterator it; //send to client Player* tmpPlayer = NULL; for(it = list.begin(); it != list.end(); ++it) { if((tmpPlayer = (*it)->getPlayer())) tmpPlayer->sendAddTileItem(this, cylinderMapPos, item); } //event methods for(it = list.begin(); it != list.end(); ++it) (*it)->onAddTileItem(this, cylinderMapPos, item); } void Tile::onUpdateTileItem(Item* oldItem, const ItemType& oldType, Item* newItem, const ItemType& newType) { const Position& cylinderMapPos = pos; const SpectatorVec& list = g_game.getSpectators(cylinderMapPos); SpectatorVec::const_iterator it; //send to client Player* tmpPlayer = NULL; for(it = list.begin(); it != list.end(); ++it) { if((tmpPlayer = (*it)->getPlayer())) tmpPlayer->sendUpdateTileItem(this, cylinderMapPos, oldItem, newItem); } //event methods for(it = list.begin(); it != list.end(); ++it) (*it)->onUpdateTileItem(this, cylinderMapPos, oldItem, oldType, newItem, newType); } void Tile::onRemoveTileItem(const SpectatorVec& list, std::vector<int32_t>& oldStackposVector, Item* item) { updateTileFlags(item, true); const Position& cylinderMapPos = pos; const ItemType& iType = Item::items[item->getID()]; SpectatorVec::const_iterator it; //send to client Player* tmpPlayer = NULL; uint32_t i = 0; for(it = list.begin(); it != list.end(); ++it) { if((tmpPlayer = (*it)->getPlayer())) tmpPlayer->sendRemoveTileItem(this, cylinderMapPos, oldStackposVector[i++], item); } //event methods for(it = list.begin(); it != list.end(); ++it) (*it)->onRemoveTileItem(this, cylinderMapPos, iType, item); } void Tile::onUpdateTile() { const Position& cylinderMapPos = pos; const SpectatorVec& list = g_game.getSpectators(cylinderMapPos); SpectatorVec::const_iterator it; //send to client Player* tmpPlayer = NULL; for(it = list.begin(); it != list.end(); ++it) { if((tmpPlayer = (*it)->getPlayer())) tmpPlayer->sendUpdateTile(this, cylinderMapPos); } //event methods for(it = list.begin(); it != list.end(); ++it) (*it)->onUpdateTile(this, cylinderMapPos); } void Tile::moveCreature(Creature* actor, Creature* creature, Cylinder* toCylinder, bool forceTeleport/* = false*/) { Tile* newTile = toCylinder->getTile(); SpectatorVec list; SpectatorVec::iterator it; g_game.getSpectators(list, pos, false, true); Position newPos = newTile->getPosition(); g_game.getSpectators(list, newPos, true, true); bool teleport = false; if(forceTeleport || !newTile->ground || !Position::areInRange<1,1,0>(pos, newPos)) teleport = true; std::vector<int32_t> oldStackposVector; Player* tmpPlayer = NULL; for(it = list.begin(); it != list.end(); ++it) { if((tmpPlayer = (*it)->getPlayer())) oldStackposVector.push_back(getClientIndexOfThing(tmpPlayer, creature)); } int32_t oldStackpos = __getIndexOfThing(creature); //remove the creature __removeThing(creature, 0); //switch the node ownership if(qt_node != newTile->qt_node) { qt_node->removeCreature(creature); newTile->qt_node->addCreature(creature); } //add the creature newTile->__addThing(actor, creature); int32_t newStackpos = newTile->__getIndexOfThing(creature); if(!teleport) { if(pos.y > newPos.y) creature->setDirection(NORTH); else if(pos.y < newPos.y) creature->setDirection(SOUTH); if(pos.x < newPos.x) creature->setDirection(EAST); else if(pos.x > newPos.x) creature->setDirection(WEST); } //send to client int32_t i = 0; for(it = list.begin(); it != list.end(); ++it) { if((tmpPlayer = (*it)->getPlayer())) tmpPlayer->sendCreatureMove(creature, newTile, newPos, this, pos, oldStackposVector[i++], teleport); } //event method for(it = list.begin(); it != list.end(); ++it) (*it)->onCreatureMove(creature, newTile, newPos, this, pos, teleport); postRemoveNotification(actor, creature, toCylinder, oldStackpos, true); newTile->postAddNotification(actor, creature, this, newStackpos); } ReturnValue Tile::__queryAdd(int32_t, const Thing* thing, uint32_t, uint32_t flags) const { const CreatureVector* creatures = getCreatures(); const TileItemVector* items = getItemList(); if(const Creature* creature = thing->getCreature()) { if(hasBitSet(FLAG_NOLIMIT, flags)) return RET_NOERROR; if(hasBitSet(FLAG_PATHFINDING, flags)) { if(floorChange() || positionChange()) return RET_NOTPOSSIBLE; } if(!ground) return RET_NOTPOSSIBLE; if(const Monster* monster = creature->getMonster()) { if(hasFlag(TILESTATE_PROTECTIONZONE)) return RET_NOTPOSSIBLE; if(floorChange() || positionChange()) return RET_NOTPOSSIBLE; if(monster->canPushCreatures() && !monster->isSummon()) { if(creatures && !creatures->empty()) { Creature* tmp = NULL; for(uint32_t i = 0; i < creatures->size(); ++i) { tmp = creatures->at(i); if(creature->canWalkthrough(tmp)) continue; if(!tmp->getMonster() || !tmp->isPushable() || tmp->isPlayerSummon()) return RET_NOTPOSSIBLE; } } } else if(creatures && !creatures->empty()) { for(CreatureVector::const_iterator cit = creatures->begin(); cit != creatures->end(); ++cit) { if(!creature->canWalkthrough(*cit)) return RET_NOTENOUGHROOM; //NOTPOSSIBLE } } if(hasFlag(TILESTATE_IMMOVABLEBLOCKSOLID)) return RET_NOTPOSSIBLE; if(hasBitSet(FLAG_PATHFINDING, flags) && hasFlag(TILESTATE_IMMOVABLENOFIELDBLOCKPATH)) return RET_NOTPOSSIBLE; if((hasFlag(TILESTATE_BLOCKSOLID) || (hasBitSet(FLAG_PATHFINDING, flags) && hasFlag(TILESTATE_NOFIELDBLOCKPATH))) && (!(monster->canPushItems() || hasBitSet(FLAG_IGNOREBLOCKITEM, flags)))) return RET_NOTPOSSIBLE; if(!items) // Do not seek for fields if there are no items return RET_NOERROR; MagicField* field = getFieldItem(); if(!field) return RET_NOERROR; if(field->isBlocking(creature)) return RET_NOTPOSSIBLE; CombatType_t combatType = field->getCombatType(); //There is 3 options for a monster to enter a magic field //1) Monster is immune if(monster->isImmune(combatType)) return RET_NOERROR; //1) Monster is "strong" enough to handle the damage //2) Monster is already afflicated by this type of condition if(!hasBitSet(FLAG_IGNOREFIELDDAMAGE, flags)) return RET_NOTPOSSIBLE; return !monster->hasCondition(Combat::DamageToConditionType(combatType), -1, false) && !monster->canPushItems() ? RET_NOTPOSSIBLE : RET_NOERROR; } if(const Player* player = creature->getPlayer()) { if(creatures && !creatures->empty() && !hasBitSet(FLAG_IGNOREBLOCKCREATURE, flags)) { for(CreatureVector::const_iterator cit = creatures->begin(); cit != creatures->end(); ++cit) { if(!creature->canWalkthrough(*cit)) return RET_NOTENOUGHROOM; //NOTPOSSIBLE } } if(!player->getParent() && hasFlag(TILESTATE_NOLOGOUT)) //player is trying to login to a "no logout" tile return RET_NOTPOSSIBLE; if(player->isPzLocked() && !player->getTile()->hasFlag(TILESTATE_HARDCOREZONE) && hasFlag(TILESTATE_HARDCOREZONE)) //player is trying to enter a pvp zone while being pz-locked return RET_PLAYERISPZLOCKEDENTERPVPZONE; if(player->isPzLocked() && player->getTile()->hasFlag(TILESTATE_HARDCOREZONE) && !hasFlag(TILESTATE_HARDCOREZONE)) //player is trying to leave a pvp zone while being pz-locked return RET_PLAYERISPZLOCKEDLEAVEPVPZONE; if(hasFlag(TILESTATE_OPTIONALZONE) && player->isPzLocked()) return RET_PLAYERISPZLOCKED; if(hasFlag(TILESTATE_PROTECTIONZONE) && player->isPzLocked()) return RET_PLAYERISPZLOCKED; } else if(creatures && !creatures->empty() && !hasBitSet(FLAG_IGNOREBLOCKCREATURE, flags)) { for(CreatureVector::const_iterator cit = creatures->begin(); cit != creatures->end(); ++cit) { if(!creature->canWalkthrough(*cit)) return RET_NOTENOUGHROOM; //NOTPOSSIBLE } } if(items) { MagicField* field = getFieldItem(); if(field && field->isBlocking(creature)) return RET_NOTPOSSIBLE; if(hasBitSet(FLAG_IGNOREBLOCKITEM, flags)) //if the FLAG_IGNOREBLOCKITEM bit isn't set we dont have to iterate every single item { //FLAG_IGNOREBLOCKITEM is set if(ground) { const ItemType& iType = Item::items[ground->getID()]; if(ground->isBlocking(creature) && (!iType.moveable || (ground->isLoadedFromMap() && (ground->getUniqueId() || (ground->getActionId() && ground->getContainer()))))) return RET_NOTPOSSIBLE; } if(const TileItemVector* items = getItemList()) { for(ItemVector::const_iterator it = items->begin(); it != items->end(); ++it) { const ItemType& iType = Item::items[(*it)->getID()]; if((*it)->isBlocking(creature) && (!iType.moveable || ((*it)->isLoadedFromMap() && ((*it)->getUniqueId() || ((*it)->getActionId() && (*it)->getContainer()))))) return RET_NOTPOSSIBLE; } } } else if(hasFlag(TILESTATE_BLOCKSOLID)) return RET_NOTPOSSIBLE; } } else if(const Item* item = thing->getItem()) { #ifdef __DEBUG__ if(thing->getParent() == NULL && !hasBitSet(FLAG_NOLIMIT, flags)) std::clog << "[Notice - Tile::__queryAdd] thing->getParent() == NULL" << std::endl; #endif if(items && items->size() >= 0xFFFF) return RET_NOTPOSSIBLE; if(hasBitSet(FLAG_NOLIMIT, flags)) return RET_NOERROR; bool itemIsHangable = item->isHangable(); if(!ground && !itemIsHangable) return RET_NOTPOSSIBLE; if(creatures && !creatures->empty() && !hasBitSet(FLAG_IGNOREBLOCKCREATURE, flags)) { for(CreatureVector::const_iterator cit = creatures->begin(); cit != creatures->end(); ++cit) { if(!(*cit)->isGhost() && item->isBlocking(*cit)) return RET_NOTENOUGHROOM; //NOTPOSSIBLE } } const uint32_t itemLimit = g_config.getNumber( hasFlag(TILESTATE_PROTECTIONZONE) ? ConfigManager::PROTECTION_TILE_LIMIT : ConfigManager::TILE_LIMIT); if(itemLimit && getThingCount() > itemLimit && !item->getMagicField()) return RET_TILEISFULL; bool hasHangable = false, supportHangable = false; if(items) { Thing* iThing = NULL; for(uint32_t i = 0; i < getThingCount(); ++i) { iThing = __getThing(i); if(const Item* iItem = iThing->getItem()) { const ItemType& iType = Item::items[iItem->getID()]; if(iType.isHangable) hasHangable = true; if(iType.isHorizontal || iType.isVertical) supportHangable = true; if(itemIsHangable && (iType.isHorizontal || iType.isVertical)) continue; else if(iItem->isBlocking(NULL)) { if(!item->isPickupable()) return RET_NOTPOSSIBLE; if(iType.allowPickupable) continue; if(!iType.hasHeight || iType.pickupable || iType.isBed()) return RET_NOTPOSSIBLE; } } } } if(itemIsHangable && hasHangable && supportHangable) return RET_NEEDEXCHANGE; } return RET_NOERROR; } ReturnValue Tile::__queryMaxCount(int32_t, const Thing*, uint32_t count, uint32_t& maxQueryCount, uint32_t ) const { maxQueryCount = std::max((uint32_t)1, count); return RET_NOERROR; } ReturnValue Tile::__queryRemove(const Thing* thing, uint32_t count, uint32_t flags) const { int32_t index = __getIndexOfThing(thing); if(index == -1) return RET_NOTPOSSIBLE; const Item* item = thing->getItem(); if(!item || !count || (item->isStackable() && count > item->getItemCount()) || (!item->isMoveable() && !hasBitSet(FLAG_IGNORENOTMOVEABLE, flags))) return RET_NOTPOSSIBLE; return RET_NOERROR; } Cylinder* Tile::__queryDestination(int32_t&, const Thing*, Item** destItem, uint32_t& flags) { Tile* destTile = NULL; *destItem = NULL; Position _pos = pos; if(floorChange(CHANGE_DOWN)) { _pos.z++; for(int32_t i = CHANGE_FIRST_EX; i < CHANGE_LAST; ++i) { Position __pos = _pos; Tile* tmpTile = NULL; switch(i) { case CHANGE_NORTH_EX: __pos.y++; if((tmpTile = g_game.getTile(__pos))) __pos.y++; break; case CHANGE_SOUTH_EX: __pos.y--; if((tmpTile = g_game.getTile(__pos))) __pos.y--; break; case CHANGE_EAST_EX: __pos.x--; if((tmpTile = g_game.getTile(__pos))) __pos.x--; break; case CHANGE_WEST_EX: __pos.x++; if((tmpTile = g_game.getTile(__pos))) __pos.x++; break; default: break; } if(!tmpTile || !tmpTile->floorChange((FloorChange_t)i)) continue; destTile = g_game.getTile(__pos); break; } if(!destTile) { if(Tile* downTile = g_game.getTile(_pos)) { if(downTile->floorChange(CHANGE_NORTH) || downTile->floorChange(CHANGE_NORTH_EX)) _pos.y++; if(downTile->floorChange(CHANGE_SOUTH) || downTile->floorChange(CHANGE_SOUTH_EX)) _pos.y--; if(downTile->floorChange(CHANGE_EAST) || downTile->floorChange(CHANGE_EAST_EX)) _pos.x--; if(downTile->floorChange(CHANGE_WEST) || downTile->floorChange(CHANGE_WEST_EX)) _pos.x++; destTile = g_game.getTile(_pos); } } } else if(floorChange()) { _pos.z--; if(floorChange(CHANGE_NORTH)) _pos.y--; if(floorChange(CHANGE_SOUTH)) _pos.y++; if(floorChange(CHANGE_EAST)) _pos.x++; if(floorChange(CHANGE_WEST)) _pos.x--; if(floorChange(CHANGE_NORTH_EX)) _pos.y -= 2; if(floorChange(CHANGE_SOUTH_EX)) _pos.y += 2; if(floorChange(CHANGE_EAST_EX)) _pos.x += 2; if(floorChange(CHANGE_WEST_EX)) _pos.x -= 2; destTile = g_game.getTile(_pos); } if(!destTile) destTile = this; else flags |= FLAG_NOLIMIT; //will ignore that there is blocking items/creatures if(destTile) { if(Item* item = destTile->getTopDownItem()) *destItem = item; } return destTile; } void Tile::__addThing(Creature* actor, int32_t, Thing* thing) { if(Creature* creature = thing->getCreature()) { g_game.clearSpectatorCache(); creature->setParent(this); CreatureVector* creatures = makeCreatures(); creatures->insert(creatures->begin(), creature); ++thingCount; return; } Item* item = thing->getItem(); if(!item) { #ifdef __DEBUG_MOVESYS__ std::clog << "[Failure - Tile::__addThing] item == NULL" << std::endl; #endif return/* RET_NOTPOSSIBLE*/; } TileItemVector* items = getItemList(); if(items && items->size() >= 0xFFFF) return/* RET_NOTPOSSIBLE*/; if(g_config.getBool(ConfigManager::STORE_TRASH) && !hasFlag(TILESTATE_TRASHED)) { g_game.addTrash(pos); setFlag(TILESTATE_TRASHED); } item->setParent(this); if(item->isGroundTile()) { if(ground) { const ItemType& oldType = Item::items[ground->getID()]; int32_t oldGroundIndex = __getIndexOfThing(ground); Item* oldGround = ground; ground->setParent(NULL); g_game.freeThing(ground); ground = item; updateTileFlags(oldGround, true); updateTileFlags(item, false); onUpdateTileItem(oldGround, oldType, item, Item::items[item->getID()]); postRemoveNotification(actor, oldGround, NULL, oldGroundIndex, true); onUpdateTile(); } else { ground = item; ++thingCount; onAddTileItem(item); } } else if(item->isAlwaysOnTop()) { if(item->isSplash()) { //remove old splash if exists if(items) { for(ItemVector::iterator it = items->getBeginTopItem(); it != items->getEndTopItem(); ++it) { if(!(*it)->isSplash()) continue; int32_t oldSplashIndex = __getIndexOfThing(*it); Item* oldSplash = *it; __removeThing(oldSplash, 1); oldSplash->setParent(NULL); g_game.freeThing(oldSplash); postRemoveNotification(actor, oldSplash, NULL, oldSplashIndex, true); break; } } } bool isInserted = false; if(items) { for(ItemVector::iterator it = items->getBeginTopItem(); it != items->getEndTopItem(); ++it) { //Note: this is different from internalAddThing if(Item::items[item->getID()].alwaysOnTopOrder > Item::items[(*it)->getID()].alwaysOnTopOrder) continue; items->insert(it, item); ++thingCount; isInserted = true; break; } } else items = makeItemList(); if(!isInserted) { items->push_back(item); ++thingCount; } onAddTileItem(item); } else { if(item->isMagicField()) { //remove old field item if exists if(items) { MagicField* oldField = NULL; for(ItemVector::iterator it = items->getBeginDownItem(); it != items->getEndDownItem(); ++it) { if(!(oldField = (*it)->getMagicField())) continue; if(oldField->isReplacable()) { int32_t oldFieldIndex = __getIndexOfThing(*it); __removeThing(oldField, 1); oldField->setParent(NULL); g_game.freeThing(oldField); postRemoveNotification(actor, oldField, NULL, oldFieldIndex, true); break; } //This magic field cannot be replaced. item->setParent(NULL); g_game.freeThing(item); return; } } } if(item->getID() == ITEM_WATERBALL_SPLASH && !hasFlag(TILESTATE_TRASHHOLDER)) item->setID(ITEM_WATERBALL); items = makeItemList(); items->insert(items->getBeginDownItem(), item); ++items->downItemCount; ++thingCount; onAddTileItem(item); } } void Tile::__updateThing(Thing* thing, uint16_t itemId, uint32_t count) { int32_t index = __getIndexOfThing(thing); if(index == -1) { #ifdef __DEBUG_MOVESYS__ std::clog << "[Failure - Tile::__updateThing] index == -1" << std::endl; #endif return/* RET_NOTPOSSIBLE*/; } Item* item = thing->getItem(); if(!item) { #ifdef __DEBUG_MOVESYS__ std::clog << "[Failure - Tile::__updateThing] item == NULL" << std::endl; #endif return/* RET_NOTPOSSIBLE*/; } //Need to update it here too since the old and new item is the same uint16_t oldId = item->getID(); updateTileFlags(item, true); item->setID(itemId); item->setSubType(count); updateTileFlags(item, false); onUpdateTileItem(item, Item::items[oldId], item, Item::items[itemId]); } void Tile::__replaceThing(uint32_t index, Thing* thing) { Item* item = thing->getItem(); if(!item) { #ifdef __DEBUG_MOVESYS__ std::clog << "[Failure - Tile::__replaceThing] item == NULL" << std::endl; #endif return/* RET_NOTPOSSIBLE*/; } int32_t pos = index; Item* oldItem = NULL; if(ground) { if(!pos) { oldItem = ground; ground = item; } --pos; } TileItemVector* items = NULL; if(!oldItem) items = getItemList(); if(items) { int32_t topItemSize = getTopItemCount(); if(pos < topItemSize) { ItemVector::iterator it = items->getBeginTopItem(); it += pos; oldItem = (*it); it = items->erase(it); items->insert(it, item); } pos -= topItemSize; } if(!oldItem) { if(CreatureVector* creatures = getCreatures()) { if(pos < (int32_t)creatures->size()) { #ifdef __DEBUG_MOVESYS__ std::clog << "[Failure - Tile::__replaceThing] Update object is a creature" << std::endl; #endif return/* RET_NOTPOSSIBLE*/; } pos -= (uint32_t)creatures->size(); } } if(!oldItem && items) { int32_t downItemSize = getDownItemCount(); if(pos < downItemSize) { ItemVector::iterator it = items->begin(); it += pos; pos = 0; oldItem = (*it); it = items->erase(it); items->insert(it, item); } } item->setParent(this); if(oldItem) updateTileFlags(oldItem, true); updateTileFlags(item, false); if(oldItem) { onUpdateTileItem(oldItem, Item::items[oldItem->getID()], item, Item::items[item->getID()]); oldItem->setParent(NULL); return/* RET_NOERROR*/; } #ifdef __DEBUG_MOVESYS__ std::clog << "[Failure - Tile::__replaceThing] Update object not found" << std::endl; #endif } void Tile::__removeThing(Thing* thing, uint32_t count) { Creature* creature = thing->getCreature(); if(creature) { if(CreatureVector* creatures = getCreatures()) { CreatureVector::iterator it = std::find(creatures->begin(), creatures->end(), thing); if(it == creatures->end()) { #ifdef __DEBUG_MOVESYS__ std::clog << "[Failure - Tile::__removeThing] creature not found" << std::endl; #endif return/* RET_NOTPOSSIBLE*/; } g_game.clearSpectatorCache(); creatures->erase(it); --thingCount; } #ifdef __DEBUG_MOVESYS__ else std::clog << "[Failure - Tile::__removeThing] creature not found" << std::endl; #endif return; } Item* item = thing->getItem(); if(!item) { #ifdef __DEBUG_MOVESYS__ std::clog << "[Failure - Tile::__removeThing] item == NULL" << std::endl; #endif return/* RET_NOTPOSSIBLE*/; } int32_t index = __getIndexOfThing(item); if(index == -1) { #ifdef __DEBUG_MOVESYS__ std::clog << "[Failure - Tile::__removeThing] index == -1" << std::endl; #endif return/* RET_NOTPOSSIBLE*/; } if(item == ground) { const SpectatorVec& list = g_game.getSpectators(pos); std::vector<int32_t> oldStackposVector; Player* tmpPlayer = NULL; for(SpectatorVec::const_iterator it = list.begin(); it != list.end(); ++it) { if((tmpPlayer = (*it)->getPlayer())) oldStackposVector.push_back(getClientIndexOfThing(tmpPlayer, ground)); } ground->setParent(NULL); ground = NULL; --thingCount; onRemoveTileItem(list, oldStackposVector, item); return/* RET_NOERROR*/; } TileItemVector* items = getItemList(); if(!items) return; if(item->isAlwaysOnTop()) { for(ItemVector::iterator it = items->getBeginTopItem(); it != items->getEndTopItem(); ++it) { if(*it != item) continue; const SpectatorVec& list = g_game.getSpectators(pos); std::vector<int32_t> oldStackposVector; Player* tmpPlayer = NULL; for(SpectatorVec::const_iterator iit = list.begin(); iit != list.end(); ++iit) { if((tmpPlayer = (*iit)->getPlayer())) oldStackposVector.push_back(getClientIndexOfThing(tmpPlayer, *it)); } (*it)->setParent(NULL); items->erase(it); --thingCount; onRemoveTileItem(list, oldStackposVector, item); return/* RET_NOERROR*/; } } else { for(ItemVector::iterator it = items->getBeginDownItem(); it != items->getEndDownItem(); ++it) { if((*it) != item) continue; if(item->isStackable() && count != item->getItemCount()) { uint8_t newCount = (uint8_t)std::max((int32_t)0, (int32_t)(item->getItemCount() - count)); updateTileFlags(item, true); item->setItemCount(newCount); updateTileFlags(item, false); const ItemType& it = Item::items[item->getID()]; onUpdateTileItem(item, it, item, it); } else { const SpectatorVec& list = g_game.getSpectators(pos); std::vector<int32_t> oldStackposVector; Player* tmpPlayer = NULL; for(SpectatorVec::const_iterator iit = list.begin(); iit != list.end(); ++iit) { if((tmpPlayer = (*iit)->getPlayer())) oldStackposVector.push_back(getClientIndexOfThing(tmpPlayer, *it)); } (*it)->setParent(NULL); items->erase(it); --items->downItemCount; --thingCount; onRemoveTileItem(list, oldStackposVector, item); } return/* RET_NOERROR*/; } } #ifdef __DEBUG_MOVESYS__ std::clog << "[Failure - Tile::__removeThing] thing not found" << std::endl; #endif } int32_t Tile::getClientIndexOfThing(const Player* player, const Thing* thing) const { if(ground && ground == thing) return 0; int32_t n = 0; if(!ground) n--; const TileItemVector* items = getItemList(); if(items) { if(thing && thing->getItem()) { for(ItemVector::const_iterator it = items->getBeginTopItem(); it != items->getEndTopItem(); ++it) { ++n; if((*it) == thing) return n; } } else n += items->getTopItemCount(); } if(const CreatureVector* creatures = getCreatures()) { for(CreatureVector::const_reverse_iterator cit = creatures->rbegin(); cit != creatures->rend(); ++cit) { if((*cit) == thing) return ++n; if(player->canSeeCreature(*cit)) ++n; } } if(items) { if(thing && thing->getItem()) { for(ItemVector::const_iterator it = items->getBeginDownItem(); it != items->getEndDownItem(); ++it) { ++n; if((*it) == thing) return n; } } else n += items->getDownItemCount(); } return -1; } int32_t Tile::__getIndexOfThing(const Thing* thing) const { if(ground && ground == thing) return 0; int32_t n = 0; if(!ground) n--; const TileItemVector* items = getItemList(); if(items) { if(thing && thing->getItem()) { for(ItemVector::const_iterator it = items->getBeginTopItem(); it != items->getEndTopItem(); ++it) { ++n; if((*it) == thing) return n; } } else n += items->getTopItemCount(); } if(const CreatureVector* creatures = getCreatures()) { for(CreatureVector::const_iterator cit = creatures->begin(); cit != creatures->end(); ++cit) { ++n; if((*cit) == thing) return n; } } if(items) { if(thing && thing->getItem()) { for(ItemVector::const_iterator it = items->getBeginDownItem(); it != items->getEndDownItem(); ++it) { ++n; if((*it) == thing) return n; } } else n += items->getDownItemCount(); } return -1; } uint32_t Tile::__getItemTypeCount(uint16_t itemId, int32_t subType /*= -1*/) const { uint32_t count = 0; Thing* thing = NULL; for(uint32_t i = 0; i < getThingCount(); ++i) { if(!(thing = __getThing(i))) continue; if(const Item* item = thing->getItem()) { if(item->getID() == itemId) count += Item::countByType(item, subType); } } return count; } Thing* Tile::__getThing(uint32_t index) const { if(ground) { if(!index) return ground; --index; } const TileItemVector* items = getItemList(); if(items) { uint32_t topItemSize = items->getTopItemCount(); if(index < topItemSize) return items->at(items->downItemCount + index); index -= topItemSize; } if(const CreatureVector* creatures = getCreatures()) { if(index < (uint32_t)creatures->size()) return creatures->at(index); index -= (uint32_t)creatures->size(); } if(items && index < items->getDownItemCount()) return items->at(index); return NULL; } void Tile::postAddNotification(Creature* actor, Thing* thing, const Cylinder* oldParent, int32_t index, cylinderlink_t link/* = LINK_OWNER*/) { const Position& cylinderMapPos = pos; const SpectatorVec& list = g_game.getSpectators(cylinderMapPos); SpectatorVec::const_iterator it; Player* tmpPlayer = NULL; for(it = list.begin(); it != list.end(); ++it) { if((tmpPlayer = (*it)->getPlayer())) tmpPlayer->postAddNotification(actor, thing, oldParent, index, LINK_NEAR); } //add a reference to this item, it may be deleted after being added (mailbox for example) thing->addRef(); if(link == LINK_OWNER) { //calling movement scripts if(Creature* creature = thing->getCreature()) { const Tile* fromTile = NULL; if(oldParent) fromTile = oldParent->getTile(); g_moveEvents->onCreatureMove(actor, creature, fromTile, this, true); } else if(Item* item = thing->getItem()) { g_moveEvents->onAddTileItem(this, item); g_moveEvents->onItemMove(actor, item, this, true); } if(hasFlag(TILESTATE_TELEPORT)) { if(Teleport* teleport = getTeleportItem()) teleport->__addThing(actor, thing); } else if(hasFlag(TILESTATE_TRASHHOLDER)) { if(TrashHolder* trashHolder = getTrashHolder()) trashHolder->__addThing(actor, thing); } else if(hasFlag(TILESTATE_MAILBOX)) { if(Mailbox* mailbox = getMailbox()) mailbox->__addThing(actor, thing); } } //release the reference to this item onces we are finished g_game.freeThing(thing); } void Tile::postRemoveNotification(Creature* actor, Thing* thing, const Cylinder* newParent, int32_t index, bool isCompleteRemoval, cylinderlink_t /*link = LINK_OWNER*/) { const Position& cylinderMapPos = pos; const SpectatorVec& list = g_game.getSpectators(cylinderMapPos); SpectatorVec::const_iterator it; if(/*isCompleteRemoval && */getThingCount() > 8) onUpdateTile(); Player* tmpPlayer = NULL; for(it = list.begin(); it != list.end(); ++it) { if((tmpPlayer = (*it)->getPlayer())) tmpPlayer->postRemoveNotification(actor, thing, newParent, index, isCompleteRemoval, LINK_NEAR); } //calling movement scripts if(Creature* creature = thing->getCreature()) { const Tile* toTile = NULL; if(newParent) toTile = newParent->getTile(); g_moveEvents->onCreatureMove(actor, creature, this, toTile, false); } else if(Item* item = thing->getItem()) { g_moveEvents->onRemoveTileItem(this, item); g_moveEvents->onItemMove(actor, item, this, false); } } void Tile::__internalAddThing(uint32_t, Thing* thing) { thing->setParent(this); if(Creature* creature = thing->getCreature()) { g_game.clearSpectatorCache(); CreatureVector* creatures = makeCreatures(); creatures->insert(creatures->begin(), creature); ++thingCount; return; } Item* item = thing->getItem(); if(!item) return; TileItemVector* items = makeItemList(); if(items && items->size() >= 0xFFFF) return/* RET_NOTPOSSIBLE*/; if(item->isGroundTile()) { if(!ground) { ground = item; ++thingCount; } } else if(item->isAlwaysOnTop()) { bool isInserted = false; for(ItemVector::iterator it = items->getBeginTopItem(); it != items->getEndTopItem(); ++it) { if(Item::items[(*it)->getID()].alwaysOnTopOrder <= Item::items[item->getID()].alwaysOnTopOrder) continue; items->insert(it, item); ++thingCount; isInserted = true; break; } if(!isInserted) { items->push_back(item); ++thingCount; } } else { items->insert(items->getBeginDownItem(), item); ++items->downItemCount; ++thingCount; } updateTileFlags(item, false); } void Tile::updateTileFlags(Item* item, bool remove) { if(!remove) { if(!hasFlag(TILESTATE_FLOORCHANGE)) { if(item->floorChange(CHANGE_DOWN)) { setFlag(TILESTATE_FLOORCHANGE); setFlag(TILESTATE_FLOORCHANGE_DOWN); } if(item->floorChange(CHANGE_NORTH)) { setFlag(TILESTATE_FLOORCHANGE); setFlag(TILESTATE_FLOORCHANGE_NORTH); } if(item->floorChange(CHANGE_SOUTH)) { setFlag(TILESTATE_FLOORCHANGE); setFlag(TILESTATE_FLOORCHANGE_SOUTH); } if(item->floorChange(CHANGE_EAST)) { setFlag(TILESTATE_FLOORCHANGE); setFlag(TILESTATE_FLOORCHANGE_EAST); } if(item->floorChange(CHANGE_WEST)) { setFlag(TILESTATE_FLOORCHANGE); setFlag(TILESTATE_FLOORCHANGE_WEST); } if(item->floorChange(CHANGE_NORTH_EX)) { setFlag(TILESTATE_FLOORCHANGE); setFlag(TILESTATE_FLOORCHANGE_NORTH_EX); } if(item->floorChange(CHANGE_SOUTH_EX)) { setFlag(TILESTATE_FLOORCHANGE); setFlag(TILESTATE_FLOORCHANGE_SOUTH_EX); } if(item->floorChange(CHANGE_EAST_EX)) { setFlag(TILESTATE_FLOORCHANGE); setFlag(TILESTATE_FLOORCHANGE_EAST_EX); } if(item->floorChange(CHANGE_WEST_EX)) { setFlag(TILESTATE_FLOORCHANGE); setFlag(TILESTATE_FLOORCHANGE_WEST_EX); } } if(item->getTeleport()) setFlag(TILESTATE_TELEPORT); if(item->getMagicField()) setFlag(TILESTATE_MAGICFIELD); if(item->getMailbox()) setFlag(TILESTATE_MAILBOX); if(item->getTrashHolder()) setFlag(TILESTATE_TRASHHOLDER); if(item->getBed()) setFlag(TILESTATE_BED); if(item->getContainer() && item->getContainer()->getDepot()) setFlag(TILESTATE_DEPOT); if(item->hasProperty(BLOCKSOLID)) setFlag(TILESTATE_BLOCKSOLID); if(item->hasProperty(IMMOVABLEBLOCKSOLID)) setFlag(TILESTATE_IMMOVABLEBLOCKSOLID); if(item->hasProperty(BLOCKPATH)) setFlag(TILESTATE_BLOCKPATH); if(item->hasProperty(NOFIELDBLOCKPATH)) setFlag(TILESTATE_NOFIELDBLOCKPATH); if(item->hasProperty(IMMOVABLENOFIELDBLOCKPATH)) setFlag(TILESTATE_IMMOVABLENOFIELDBLOCKPATH); } else { if(item->floorChange(CHANGE_DOWN)) { resetFlag(TILESTATE_FLOORCHANGE); resetFlag(TILESTATE_FLOORCHANGE_DOWN); } if(item->floorChange(CHANGE_NORTH)) { resetFlag(TILESTATE_FLOORCHANGE); resetFlag(TILESTATE_FLOORCHANGE_NORTH); } if(item->floorChange(CHANGE_SOUTH)) { resetFlag(TILESTATE_FLOORCHANGE); resetFlag(TILESTATE_FLOORCHANGE_SOUTH); } if(item->floorChange(CHANGE_EAST)) { resetFlag(TILESTATE_FLOORCHANGE); resetFlag(TILESTATE_FLOORCHANGE_EAST); } if(item->floorChange(CHANGE_WEST)) { resetFlag(TILESTATE_FLOORCHANGE); resetFlag(TILESTATE_FLOORCHANGE_WEST); } if(item->floorChange(CHANGE_NORTH_EX)) { resetFlag(TILESTATE_FLOORCHANGE); resetFlag(TILESTATE_FLOORCHANGE_NORTH_EX); } if(item->floorChange(CHANGE_SOUTH_EX)) { resetFlag(TILESTATE_FLOORCHANGE); resetFlag(TILESTATE_FLOORCHANGE_SOUTH_EX); } if(item->floorChange(CHANGE_EAST_EX)) { resetFlag(TILESTATE_FLOORCHANGE); resetFlag(TILESTATE_FLOORCHANGE_EAST_EX); } if(item->floorChange(CHANGE_WEST_EX)) { resetFlag(TILESTATE_FLOORCHANGE); resetFlag(TILESTATE_FLOORCHANGE_WEST_EX); } if(item->getTeleport()) resetFlag(TILESTATE_TELEPORT); if(item->getMagicField()) resetFlag(TILESTATE_MAGICFIELD); if(item->getMailbox()) resetFlag(TILESTATE_MAILBOX); if(item->getTrashHolder()) resetFlag(TILESTATE_TRASHHOLDER); if(item->getBed()) resetFlag(TILESTATE_BED); if(item->getContainer() && item->getContainer()->getDepot()) resetFlag(TILESTATE_DEPOT); if(item->hasProperty(BLOCKSOLID) && !hasProperty(item, BLOCKSOLID)) resetFlag(TILESTATE_BLOCKSOLID); if(item->hasProperty(IMMOVABLEBLOCKSOLID) && !hasProperty(item, IMMOVABLEBLOCKSOLID)) resetFlag(TILESTATE_IMMOVABLEBLOCKSOLID); if(item->hasProperty(BLOCKPATH) && !hasProperty(item, BLOCKPATH)) resetFlag(TILESTATE_BLOCKPATH); if(item->hasProperty(NOFIELDBLOCKPATH) && !hasProperty(item, NOFIELDBLOCKPATH)) resetFlag(TILESTATE_NOFIELDBLOCKPATH); if(item->hasProperty(IMMOVABLEBLOCKPATH) && !hasProperty(item, IMMOVABLEBLOCKPATH)) resetFlag(TILESTATE_IMMOVABLEBLOCKPATH); if(item->hasProperty(IMMOVABLENOFIELDBLOCKPATH) && !hasProperty(item, IMMOVABLENOFIELDBLOCKPATH)) resetFlag(TILESTATE_IMMOVABLENOFIELDBLOCKPATH); } }
Postado Novembro 11, 2016 8 anos Coloque o código no pastebin.com não deu para ler nada direito nesse code.
Postado Novembro 19, 2016 8 anos Autor Em 11/11/2016 em 17:49, vankk disse: Coloque o código no pastebin.com não deu para ler nada direito nesse code. http://pastebin.com/8xzv5KTR vlw
Postado Novembro 19, 2016 8 anos Em 06/11/2016 em 20:21, Henrry disse: Queria adicionar o maxItemsPerPZTile na minha source, deixar só 5 items por Tile(SQM) como eu coloco nas source ? olha ai meu tile.cpp Não entendi muito bem o porque de mudar na source, mas em config.lua você pode alterar isso.. Lá você procura: Citar maxItemsPerPZTile = 0 E altera para: Citar maxItemsPerPZTile = 5 Bem.. Meio óbvio .. Mas espero ter ajudado
Postado Novembro 20, 2016 8 anos Autor Em 19/11/2016 em 22:29, Vinicius Xxgamexx disse: Não entendi muito bem o porque de mudar na source, mas em config.lua você pode alterar isso.. Lá você procura: E altera para: Bem.. Meio óbvio .. Mas espero ter ajudado Claro que já tentei amigo. Mas é só pela source mesmo. vlw
Participe da conversa
Você pode postar agora e se cadastrar mais tarde. Se você tem uma conta, faça o login para postar com sua conta.