Hi
How to save in house non pickupable items, grounds etc.
For example i create item /i 2737 (growing wheat) in house and i want to save this
I think this is a code
but wher is code resposible for what type of item to save?
EDIT.1
ok i fix this.
In iomapserialize.cpp
to
and this :
to this
How to save in house non pickupable items, grounds etc.
For example i create item /i 2737 (growing wheat) in house and i want to save this
I think this is a code
C++:
bool IOMapSerialize::saveHouseItems()
{
int64_t start = OTSYS_TIME();
Database& db = Database::getInstance();
//Start the transaction
DBTransaction transaction;
if (!transaction.begin()) {
return false;
}
//clear old tile data
if (!db.executeQuery("DELETE FROM `tile_store`")) {
return false;
}
DBInsert stmt("INSERT INTO `tile_store` (`house_id`, `data`) VALUES ");
PropWriteStream stream;
for (const auto& it : g_game.map.houses.getHouses()) {
//save house items
House* house = it.second;
for (HouseTile* tile : house->getTiles()) {
saveTile(stream, tile);
size_t attributesSize;
const char* attributes = stream.getStream(attributesSize);
if (attributesSize > 0) {
if (!stmt.addRow(fmt::format("{:d}, {:s}", house->getId(), db.escapeBlob(attributes, attributesSize)))) {
return false;
}
stream.clear();
}
}
}
if (!stmt.execute()) {
return false;
}
//End the transaction
bool success = transaction.commit();
std::cout << "> Saved house items in: " <<
(OTSYS_TIME() - start) / (1000.) << " s" << std::endl;
return success;
}
but wher is code resposible for what type of item to save?
EDIT.1
ok i fix this.
In iomapserialize.cpp
C++:
bool IOMapSerialize::loadItem(PropStream& propStream, Cylinder* parent)
{
uint16_t id;
if (!propStream.read<uint16_t>(id)) {
return false;
}
Tile* tile = nullptr;
if (parent->getParent() == nullptr) {
tile = parent->getTile();
}
const ItemType& iType = Item::items[id];
if (iType.moveable || iType.forceSerialize || !tile) {
//create a new item
Item* item = Item::CreateItem(id);
if (item) {
if (item->unserializeAttr(propStream)) {
Container* container = item->getContainer();
if (container && !loadContainer(propStream, container)) {
delete item;
return false;
}
parent->internalAddThing(item);
item->startDecaying();
} else {
std::cout << "WARNING: Unserialization error in IOMapSerialize::loadItem()" << id << std::endl;
delete item;
return false;
}
}
} else {
// Stationary items like doors/beds/blackboards/bookcases
Item* item = nullptr;
if (const TileItemVector* items = tile->getItemList()) {
for (Item* findItem : *items) {
if (findItem->getID() == id) {
item = findItem;
break;
} else if (iType.isDoor() && findItem->getDoor()) {
item = findItem;
break;
} else 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;
}
g_game.transformItem(item, id);
} else {
std::cout << "WARNING: Unserialization error in IOMapSerialize::loadItem()" << id << std::endl;
}
} else {
//The map changed since the last save, just read the attributes
std::unique_ptr<Item> dummy(Item::CreateItem(id));
if (dummy) {
dummy->unserializeAttr(propStream);
Container* container = dummy->getContainer();
if (container) {
if (!loadContainer(propStream, container)) {
return false;
}
} else if (BedItem* bedItem = dynamic_cast<BedItem*>(dummy.get())) {
uint32_t sleeperGUID = bedItem->getSleeper();
if (sleeperGUID != 0) {
g_game.removeBedSleeper(sleeperGUID);
}
}
}
}
}
return true;
to
C++:
bool IOMapSerialize::loadItem(PropStream& propStream, Cylinder* parent)
{
uint16_t id;
if (!propStream.read<uint16_t>(id)) {
return false;
}
Tile* tile = nullptr;
if (parent->getParent() == nullptr) {
tile = parent->getTile();
}
const ItemType& iType = Item::items[id];
if (iType.id) {
//create a new item
Item* item = Item::CreateItem(id);
if (item) {
if (item->unserializeAttr(propStream)) {
Container* container = item->getContainer();
if (container && !loadContainer(propStream, container)) {
delete item;
return false;
}
parent->internalAddThing(item);
item->startDecaying();
} else {
std::cout << "WARNING: Unserialization error in IOMapSerialize::loadItem()" << id << std::endl;
delete item;
return false;
}
}
} else {
// Stationary items like doors/beds/blackboards/bookcases
Item* item = nullptr;
if (const TileItemVector* items = tile->getItemList()) {
for (Item* findItem : *items) {
if (findItem->getID() == id) {
item = findItem;
break;
} else if (iType.isDoor() && findItem->getDoor()) {
item = findItem;
break;
} else 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;
}
g_game.transformItem(item, id);
} else {
std::cout << "WARNING: Unserialization error in IOMapSerialize::loadItem()" << id << std::endl;
}
} else {
//The map changed since the last save, just read the attributes
std::unique_ptr<Item> dummy(Item::CreateItem(id));
if (dummy) {
dummy->unserializeAttr(propStream);
Container* container = dummy->getContainer();
if (container) {
if (!loadContainer(propStream, container)) {
return false;
}
} else if (BedItem* bedItem = dynamic_cast<BedItem*>(dummy.get())) {
uint32_t sleeperGUID = bedItem->getSleeper();
if (sleeperGUID != 0) {
g_game.removeBedSleeper(sleeperGUID);
}
}
}
}
}
return true;
}
and this :
C++:
void IOMapSerialize::saveTile(PropWriteStream& stream, const Tile* tile)
{
const TileItemVector* tileItems = tile->getItemList();
if (!tileItems) {
return;
}
std::forward_list<Item*> items;
uint16_t count = 0;
for (Item* item : *tileItems) {
const ItemType& it = Item::items[item->getID()];
// Note that these are NEGATED, ie. these are the items that will be saved.
if (!(it.moveable || it.forceSerialize || item->getDoor() || (item->getContainer() && !item->getContainer()->empty()) || it.canWriteText || item->getBed())) {
continue;
}
items.push_front(item);
++count;
}
if (!items.empty()) {
const Position& tilePosition = tile->getPosition();
stream.write<uint16_t>(tilePosition.x);
stream.write<uint16_t>(tilePosition.y);
stream.write<uint8_t>(tilePosition.z);
stream.write<uint32_t>(count);
for (const Item* item : items) {
saveItem(stream, item);
}
}
}
to this
C++:
void IOMapSerialize::saveTile(PropWriteStream& stream, const Tile* tile)
{
const TileItemVector* tileItems = tile->getItemList();
if (!tileItems) {
return;
}
std::forward_list<Item*> items;
uint16_t count = 0;
for (Item* item : *tileItems) {
const ItemType& it = Item::items[item->getID()];
// Note that these are NEGATED, ie. these are the items that will be saved.
items.push_front(item);
++count;
}
if (!items.empty()) {
const Position& tilePosition = tile->getPosition();
stream.write<uint16_t>(tilePosition.x);
stream.write<uint16_t>(tilePosition.y);
stream.write<uint8_t>(tilePosition.z);
stream.write<uint32_t>(count);
for (const Item* item : items) {
saveItem(stream, item);
}
}
}
Last edited: