bool IOMapSerialize::loadItem(PropStream& propStream, Cylinder* parent, bool depotTransfer/* = false*/) { Tile* tile = NULL; if(!parent->getItem()) tile = parent->getTile(); uint16_t id = 0; propStream.GET_USHORT(id); Item* item = NULL; const ItemType& iType = Item::items[id]; if(iType.moveable || iType.forceSerialize || (!depotTransfer && !tile)) { if(!(item = Item::CreateItem(id))) return true; if(!item->unserializeAttr(propStream)) { std::cout << "[Warning - IOMapSerialize::loadItem] Unserialization error [0] for item type " << id << std::endl; delete item; return false; } if(Container* container = item->getContainer()) { if(!loadContainer(propStream, container)) { delete item; return false; } } if(parent) { parent->__internalAddThing(item); item->__startDecaying(); } else delete item; return true; } if(tile) { //Stationary items Item* findItem = NULL; for(uint32_t i = 0; i < tile->getThingCount(); ++i) { if(!(findItem = tile->__getThing(i)->getItem())) continue; if(findItem->getID() == id) { item = findItem; break; } if(iType.isDoor() && findItem->getDoor()) { item = findItem; break; } if(iType.isBed() && findItem->getBed()) { item = findItem; break; } } } if(item) { if(item->unserializeAttr(propStream)) { Container* container = item->getContainer(); if(container && !loadContainer(propStream, container)) return false; item = g_game.transformItem(item, id); } else std::cout << "[Warning - IOMapSerialize::loadItem] Unserialization error [1] for item type " << id << std::endl; return true; } //The map changed since the last save, just read the attributes if(!(item = Item::CreateItem(id))) return true; item->unserializeAttr(propStream); if(Container* container = item->getContainer()) { if(!loadContainer(propStream, container)) { delete item; return false; } if(depotTransfer) { for(ItemList::const_iterator it = container->getItems(); it != container->getEnd(); ++it) parent->__addThing(NULL, (*it)); container->itemlist.clear(); } } delete item; return true; }
bool IOMapSerialize::loadItems(Database* db, DBResult* result, Cylinder* parent, bool depotTransfer/* = false*/) { ItemMap itemMap; Tile* tile = NULL; if(!parent->getItem()) tile = parent->getTile(); Item* item = NULL; int32_t sid, pid, id, count; do { sid = result->getDataInt("sid"); pid = result->getDataInt("pid"); id = result->getDataInt("itemtype"); count = result->getDataInt("count"); item = NULL; uint64_t attrSize = 0; const char* attr = result->getDataStream("attributes", attrSize); PropStream propStream; propStream.init(attr, attrSize); const ItemType& iType = Item::items[id]; if(iType.moveable || iType.forceSerialize || pid) { if(!(item = Item::CreateItem(id, count))) continue; if(item->unserializeAttr(propStream)) { if(!pid) { parent->__internalAddThing(item); item->__startDecaying(); } } else std::cout << "[Warning - IOMapSerialize::loadItems] Unserialization error [0] for item type " << id << std::endl; } else if(tile) { //find this type in the tile Item* findItem = NULL; for(uint32_t i = 0; i < tile->getThingCount(); ++i) { if(!(findItem = tile->__getThing(i)->getItem())) continue; if(findItem->getID() == id) { item = findItem; break; } if(iType.isDoor() && findItem->getDoor()) { item = findItem; break; } if(iType.isBed() && findItem->getBed()) { item = findItem; break; } } } if(item) { if(item->unserializeAttr(propStream)) { if((item = g_game.transformItem(item, id))) itemMap[sid] = std::make_pair(item, pid); } else std::cout << "[Warning - IOMapSerialize::loadItems] Unserialization error [1] for item type " << id << std::endl; } else if((item = Item::CreateItem(id))) { item->unserializeAttr(propStream); if(!depotTransfer) std::cout << "[Warning - IOMapSerialize::loadItems] NULL item at " << tile->getPosition() << " (type = " << id << ", sid = " << sid << ", pid = " << pid << ")" << std::endl; else itemMap[sid] = std::make_pair(parent->getItem(), pid); delete item; item = NULL; } } while(result->next()); ItemMap::iterator it; for(ItemMap::reverse_iterator rit = itemMap.rbegin(); rit != itemMap.rend(); ++rit) { if(!(item = rit->second.first)) continue; int32_t pid = rit->second.second; it = itemMap.find(pid); if(it == itemMap.end()) continue; if(Container* container = it->second.first->getContainer()) { container->__internalAddThing(item); g_game.startDecay(item); } } return true; }