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::internalAddThing(uint32_t, Thing* thing) { thing->setParent(this); Creature* creature = thing->getCreature(); if (creature) { g_game.map.clearSpectatorCache(); CreatureVector* creatures = makeCreatures(); creatures->insert(creatures->begin(), creature); } else { Item* item = thing->getItem(); if (item == nullptr) { return; } const ItemType& itemType = Item::items[item->getID()]; if (itemType.isGroundTile()) { if (ground == nullptr) { ground = item; setTileFlags(item); } return; } TileItemVector* items = makeItemList(); if (items->size() >= 0xFFFF) { return /*RETURNVALUE_NOTPOSSIBLE*/; } if (itemType.alwaysOnTop) { bool isInserted = false; for (ItemVector::iterator it = items->getBeginTopItem(), end = items->getEndTopItem(); it != end; ++it) { if (Item::items[(*it)->getID()].alwaysOnTopOrder > itemType.alwaysOnTopOrder) { items->insert(it, item); isInserted = true; break; } } if (!isInserted) { items->push_back(item); } } else { items->insert(items->getBeginDownItem(), item); items->addDownItemCount(1); } setTileFlags(item); } }
void Tile::replaceThing(uint32_t index, Thing* thing) { int32_t pos = index; Item* item = thing->getItem(); if (item == nullptr) { return /*RETURNVALUE_NOTPOSSIBLE*/; } Item* oldItem = nullptr; bool isInserted = false; if (ground) { if (pos == 0) { oldItem = ground; ground = item; isInserted = true; } --pos; } TileItemVector* items = getItemList(); if (items && !isInserted) { int32_t topItemSize = getTopItemCount(); if (pos < topItemSize) { ItemVector::iterator it = items->getBeginTopItem(); it += pos; oldItem = (*it); it = items->erase(it); items->insert(it, item); isInserted = true; } pos -= topItemSize; } CreatureVector* creatures = getCreatures(); if (creatures) { if (!isInserted && pos < static_cast<int32_t>(creatures->size())) { return /*RETURNVALUE_NOTPOSSIBLE*/; } pos -= static_cast<uint32_t>(creatures->size()); } if (items && !isInserted) { int32_t downItemSize = getDownItemCount(); if (pos < downItemSize) { ItemVector::iterator it = items->getBeginDownItem() + pos; oldItem = *it; it = items->erase(it); items->insert(it, item); isInserted = true; } } if (isInserted) { item->setParent(this); resetTileFlags(oldItem); setTileFlags(item); const ItemType& oldType = Item::items[oldItem->getID()]; const ItemType& newType = Item::items[item->getID()]; onUpdateTileItem(oldItem, oldType, item, newType); oldItem->setParent(nullptr); return /*RETURNVALUE_NOERROR*/; } }
void Tile::addThing(int32_t, Thing* thing) { Creature* creature = thing->getCreature(); if (creature) { g_game.map.clearSpectatorCache(); creature->setParent(this); CreatureVector* creatures = makeCreatures(); creatures->insert(creatures->begin(), creature); } else { Item* item = thing->getItem(); if (item == nullptr) { return /*RETURNVALUE_NOTPOSSIBLE*/; } TileItemVector* items = getItemList(); if (items && items->size() >= 0xFFFF) { return /*RETURNVALUE_NOTPOSSIBLE*/; } item->setParent(this); const ItemType& itemType = Item::items[item->getID()]; if (itemType.isGroundTile()) { if (ground == nullptr) { ground = item; onAddTileItem(item); } else { const ItemType& oldType = Item::items[ground->getID()]; Item* oldGround = ground; ground->setParent(nullptr); g_game.ReleaseItem(ground); ground = item; resetTileFlags(oldGround); setTileFlags(item); onUpdateTileItem(oldGround, oldType, item, itemType); postRemoveNotification(oldGround, nullptr, 0); } } else if (itemType.alwaysOnTop) { if (itemType.isSplash() && items) { //remove old splash if exists for (ItemVector::const_iterator it = items->getBeginTopItem(), end = items->getEndTopItem(); it != end; ++it) { Item* oldSplash = *it; if (!Item::items[oldSplash->getID()].isSplash()) { continue; } removeThing(oldSplash, 1); oldSplash->setParent(nullptr); g_game.ReleaseItem(oldSplash); postRemoveNotification(oldSplash, nullptr, 0); break; } } bool isInserted = false; if (items) { for (ItemVector::iterator it = items->getBeginTopItem(), end = items->getEndTopItem(); it != end; ++it) { //Note: this is different from internalAddThing if (itemType.alwaysOnTopOrder <= Item::items[(*it)->getID()].alwaysOnTopOrder) { items->insert(it, item); isInserted = true; break; } } } else { items = makeItemList(); } if (!isInserted) { items->push_back(item); } onAddTileItem(item); } else { if (itemType.isMagicField()) { //remove old field item if exists if (items) { for (ItemVector::const_iterator it = items->getBeginDownItem(), end = items->getEndDownItem(); it != end; ++it) { MagicField* oldField = (*it)->getMagicField(); if (oldField) { if (oldField->isReplaceable()) { removeThing(oldField, 1); oldField->setParent(nullptr); g_game.ReleaseItem(oldField); postRemoveNotification(oldField, nullptr, 0); break; } else { //This magic field cannot be replaced. item->setParent(nullptr); g_game.ReleaseItem(item); return; } } } } } items = makeItemList(); items->insert(items->getBeginDownItem(), item); items->addDownItemCount(1); onAddTileItem(item); } } }
void Tile::__addThing(int32_t index, Thing* thing) { Creature* creature = thing->getCreature(); if (creature) { g_game.clearSpectatorCache(); creature->setParent(this); CreatureVector* creatures = makeCreatures(); creatures->insert(creatures->begin(), creature); ++thingCount; } else { Item* item = thing->getItem(); if (!item) { #ifdef __DEBUG__MOVESYS__ std::cout << "Failure: [Tile::__addThing] item == NULL" << std::endl; DEBUG_REPORT #endif return /*RET_NOTPOSSIBLE*/; } TileItemVector* items = getItemList(); if (items && items->size() > 0xFFFF) { return /*RET_NOTPOSSIBLE*/; } item->setParent(this); if (item->isGroundTile()) { if (!ground) { ground = item; ++thingCount; onAddTileItem(item); } else { const ItemType& oldType = Item::items[ground->getID()]; const ItemType& newType = Item::items[item->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, newType); postRemoveNotification(oldGround, NULL, oldGroundIndex, true); } } 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()) { int32_t oldSplashIndex = __getIndexOfThing(*it); Item* oldSplash = *it; __removeThing(oldSplash, 1); oldSplash->setParent(NULL); g_game.FreeThing(oldSplash); postRemoveNotification(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) { 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())) { if (oldField->isReplaceable()) { int32_t oldFieldIndex = __getIndexOfThing(*it); __removeThing(oldField, 1); oldField->setParent(NULL); g_game.FreeThing(oldField); postRemoveNotification(oldField, NULL, oldFieldIndex, true); break; } else { //This magic field cannot be replaced. item->setParent(NULL); g_game.FreeThing(item); return; } } } } } items = makeItemList(); items->insert(items->getBeginDownItem(), item); ++items->downItemCount; ++thingCount; onAddTileItem(item); } }
void Tile::__replaceThing(uint32_t index, Thing* thing) { int32_t pos = index; Item* item = thing->getItem(); if (item == NULL) { return /*RET_NOTPOSSIBLE*/; } Item* oldItem = NULL; bool isInserted = false; if (ground) { if (pos == 0) { oldItem = ground; ground = item; isInserted = true; } --pos; } TileItemVector* items = getItemList(); if (items && !isInserted) { int32_t topItemSize = getTopItemCount(); if (pos < topItemSize) { ItemVector::iterator it = items->getBeginTopItem(); it += pos; oldItem = (*it); it = items->erase(it); items->insert(it, item); isInserted = true; } pos -= topItemSize; } CreatureVector* creatures = getCreatures(); if (creatures) { if (!isInserted && pos < (int32_t)creatures->size()) { return /*RET_NOTPOSSIBLE*/; } pos -= (uint32_t)creatures->size(); } if (items && !isInserted) { 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); isInserted = true; } } if (isInserted) { item->setParent(this); updateTileFlags(oldItem, true); updateTileFlags(item, false); const ItemType& oldType = Item::items[oldItem->getID()]; const ItemType& newType = Item::items[item->getID()]; onUpdateTileItem(oldItem, oldType, item, newType); oldItem->setParent(NULL); return /*RET_NOERROR*/; } }
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) { int32_t oldGroundIndex = __getIndexOfThing(ground); Item* oldGround = ground; updateTileFlags(oldGround, true); updateTileFlags(item, false); ground = item; #ifdef __GROUND_CACHE__ std::map<Item*, int32_t>::iterator it = g_game.grounds.find(oldGround); bool erase = it == g_game.grounds.end(); if(!erase) { it->second--; erase = it->second < 1; if(erase) g_game.grounds.erase(it); } if(erase) { #endif oldGround->setParent(NULL); g_game.freeThing(oldGround); #ifdef __GROUND_CACHE__ } #endif 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::__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); } } if(oldItem) { item->setParent(this); updateTileFlags(oldItem, true); updateTileFlags(item, false); onUpdateTileItem(oldItem, Item::items[oldItem->getID()], item, Item::items[item->getID()]); #ifdef __GROUND_CACHE__ std::map<Item*, int32_t>::iterator it = g_game.grounds.find(oldItem); bool erase = it == g_game.grounds.end(); if(!erase) { it->second--; erase = it->second < 1; if(erase) g_game.grounds.erase(it); } if(erase) { #endif oldItem->setParent(NULL); g_game.freeThing(oldItem); #ifdef __GROUND_CACHE__ } #endif return/* RET_NOERROR*/; } #ifdef __DEBUG_MOVESYS__ std::clog << "[Failure - Tile::__replaceThing] Update object not found" << std::endl; #endif }