House* Houses::getHouseByPlayerId(uint32_t playerId) { for(HouseMap::iterator it = houseMap.begin(); it != houseMap.end(); ++it){ House* house = it->second; if(house->getHouseOwner() == playerId){ return house; } } return NULL; }
void Commands::sellHouse(Player* player, const std::string& cmd, const std::string& param) { Player* tradePartner = g_game.getPlayerByName(param); if (!tradePartner || tradePartner == player) { player->sendCancel("Trade player not found."); return; } if (!Position::areInRange<2, 2, 0>(tradePartner->getPosition(), player->getPosition())) { player->sendCancel("Trade player is too far away."); return; } if (!tradePartner->isPremium()) { player->sendCancel("Trade player does not have a premium account."); return; } HouseTile* houseTile = dynamic_cast<HouseTile*>(player->getTile()); if (!houseTile) { player->sendCancel("You must stand in your house to initiate the trade."); return; } House* house = houseTile->getHouse(); if (!house || house->getHouseOwner() != player->guid) { player->sendCancel("You don't own this house."); return; } if (Houses::getInstance().getHouseByPlayerId(tradePartner->guid)) { player->sendCancel("Trade player already owns a house."); return; } if (IOLoginData::hasBiddedOnHouse(tradePartner->guid)) { player->sendCancel("Trade player is currently the highest bidder of an auctioned house."); return; } Item* transferItem = house->getTransferItem(); if (!transferItem) { player->sendCancel("You can not trade this house."); return; } transferItem->getParent()->setParent(player); if (!g_game.internalStartTrade(player, tradePartner, transferItem)) { house->resetTransferItem(); } }
void Commands::buyHouse(Player* player, const std::string& cmd, const std::string& param) { if (!player->isPremium()) { player->sendCancelMessage(RET_YOUNEEDPREMIUMACCOUNT); return; } Position pos = player->getPosition(); pos = getNextPosition(player->direction, pos); Tile* tile = g_game.getTile(pos.x, pos.y, pos.z); if (!tile) { player->sendCancel("You have to be looking at the door of the house you would like to buy."); return; } HouseTile* houseTile = dynamic_cast<HouseTile*>(tile); if (!houseTile) { player->sendCancel("You have to be looking at the door of the house you would like to buy."); return; } House* house = houseTile->getHouse(); if (!house || !house->getDoorByPosition(pos)) { player->sendCancel("You have to be looking at the door of the house you would like to buy."); return; } if (house->getHouseOwner()) { player->sendCancel("This house alreadly has an owner."); return; } for (const auto& it : Houses::getInstance().getHouses()) { if (it.second->getHouseOwner() == player->guid) { player->sendCancel("You are already the owner of a house."); return; } } uint64_t price = house->getHouseTiles().size() * g_config.getNumber(ConfigManager::HOUSE_PRICE); if (!g_game.removeMoney(player, price)) { player->sendCancel("You do not have enough money."); return; } house->setHouseOwner(player->guid); player->sendTextMessage(MSG_INFO_DESCR, "You have successfully bought this house, be sure to have the money for the rent in the bank."); }
bool IOMapSerialize::loadHouseInfo(Map* map) { Database* db = Database::getInstance(); std::ostringstream query; DBResult* result = db->storeQuery("SELECT `id`, `owner`, `paid`, `warnings` FROM `houses`"); if (!result) { return false; } do { House* house = Houses::getInstance().getHouse(result->getDataInt("id")); if (house) { house->setHouseOwner(result->getDataInt("owner")); house->setPaidUntil(result->getDataInt("paid")); house->setPayRentWarnings(result->getDataInt("warnings")); } } while (result->next()); db->freeResult(result); for (const auto& it : Houses::getInstance().getHouses()) { House* house = it.second; if (house->getHouseOwner() != 0 && house->getHouseId() != 0) { query.str(""); query << "SELECT `listid`, `list` FROM `house_lists` WHERE `house_id` = " << house->getHouseId(); if ((result = db->storeQuery(query.str()))) { do { house->setAccessList(result->getDataInt("listid"), result->getDataString("list")); } while (result->next()); db->freeResult(result); } } } return true; }
bool Houses::payHouses() { if(rentPeriod == RENTPERIOD_NEVER) { return true; } uint32_t currentTime = std::time(NULL); for(HouseMap::iterator it = houseMap.begin(); it != houseMap.end(); ++it){ House* house = it->second; if(house->getHouseOwner() != 0 && house->getPaidUntil() < currentTime && house->getRent() != 0){ uint32_t ownerid = house->getHouseOwner(); Town* town = Towns::getInstance().getTown(house->getTownId()); if(!town){ #ifdef __DEBUG_HOUSES__ std::cout << "Warning: [Houses::payHouses] town = NULL, townid = " << house->getTownId() << ", houseid = " << house->getHouseId() << std::endl; #endif continue; } std::string name; if(!IOPlayer::instance()->getNameByGuid(ownerid, name)){ //player doesnt exist, remove it as house owner? //house->setHouseOwner(0); continue; } Player* player = g_game.getPlayerByName(name); if(!player){ player = new Player(name, NULL); if(!IOPlayer::instance()->loadPlayer(player, name)){ #ifdef __DEBUG__ std::cout << "Failure: [Houses::payHouses], can not load player: " << name << std::endl; #endif delete player; continue; } } Depot* depot = player->getDepot(town->getTownID(), true); // savePlayerHere is an ugly hack // to avoid saving 2 times a not online player // when items are transferred to his depot bool savePlayerHere = true; if(depot){ //get money from depot bool useAccBalance = g_config.getBool(ConfigManager::USE_ACCBALANCE) != 0; bool hasEnoughMoney = false; if(useAccBalance){ if(player->balance >= house->getRent()){ player->balance -= house->getRent(); hasEnoughMoney = true; } } else{ hasEnoughMoney = g_game.removeMoney(depot, house->getRent(), FLAG_NOLIMIT); } if(hasEnoughMoney){ uint32_t paidUntil = currentTime; switch(rentPeriod){ case RENTPERIOD_DAILY: paidUntil += 24 * 60 * 60; break; case RENTPERIOD_WEEKLY: paidUntil += 24 * 60 * 60 * 7; break; case RENTPERIOD_MONTHLY: paidUntil += 24 * 60 * 60 * 30; break; case RENTPERIOD_YEARLY: paidUntil += 24 * 60 * 60 * 365; case RENTPERIOD_NEVER: break; } house->setPaidUntil(paidUntil); } else if(currentTime >= house->getLastWarning() + 24 * 60 * 60){ if(house->getPayRentWarnings() >= 7){ house->setHouseOwner(0); // setHouseOwner will load the player, // transfer house items to his depot and then // will save it, so here should not be saved // again savePlayerHere = false; } else{ int daysLeft = 7 - house->getPayRentWarnings(); Item* letter = Item::CreateItem(ITEM_LETTER_STAMPED); std::string period = ""; switch(rentPeriod){ case RENTPERIOD_DAILY: period = "daily"; break; case RENTPERIOD_WEEKLY: period = "weekly"; break; case RENTPERIOD_MONTHLY: period = "monthly"; break; case RENTPERIOD_YEARLY: period = "annual"; break; case RENTPERIOD_NEVER: // break; } std::stringstream warningText; warningText << "Warning! \n" << "The " << period << " rent of " << house->getRent() << " gold for your house \"" << house->getName() << "\" is payable. Have it available within " << daysLeft << " days, or you will lose this house."; letter->setText(warningText.str()); g_game.internalAddItem(depot, letter, INDEX_WHEREEVER, FLAG_NOLIMIT); house->setPayRentWarnings(house->getPayRentWarnings() + 1); house->setLastWarning(currentTime); } } } if(player->isOffline()){ if(savePlayerHere){ IOPlayer::instance()->savePlayer(player); } delete player; } } } return true; }
bool Houses::payHouses() { if (rentPeriod == RENTPERIOD_NEVER) { return true; } time_t currentTime = time(NULL); for (HouseMap::iterator it = houseMap.begin(); it != houseMap.end(); ++it) { House* house = it->second; if (house->getHouseOwner() != 0) { uint32_t ownerid = house->getHouseOwner(); Town* town = Towns::getInstance().getTown(house->getTownId()); if (!town) { #ifdef __DEBUG_HOUSES__ std::cout << "Warning: [Houses::payHouses] town = NULL, townid = " << house->getTownId() << ", houseid = " << house->getHouseId() << std::endl; #endif continue; } std::string name; if (!IOLoginData::getInstance()->getNameByGuid(ownerid, name)) { //player doesnt exist, remove it as house owner? house->setHouseOwner(0); continue; } Player* player = g_game.getPlayerByName(name); if (!player) { player = new Player(name, NULL); if (!IOLoginData::getInstance()->loadPlayer(player, name)) { #ifdef __DEBUG__ std::cout << "Failure: [Houses::payHouses], can not load player: " << name << std::endl; #endif delete player; continue; } } bool paid = false; if (player->getBankBalance() >= house->getRent()) { player->setBankBalance(player->getBankBalance() - house->getRent()); paid = true; } if (paid) { time_t paidUntil = currentTime; switch (rentPeriod) { case RENTPERIOD_DAILY: paidUntil += 24 * 60 * 60; break; case RENTPERIOD_WEEKLY: paidUntil += 24 * 60 * 60 * 7; break; case RENTPERIOD_MONTHLY: paidUntil += 24 * 60 * 60 * 30; break; case RENTPERIOD_YEARLY: paidUntil += 24 * 60 * 60 * 365; break; default: break; } house->setPaidUntil(paidUntil); } else { if (house->getPayRentWarnings() < 7) { int32_t daysLeft = 7 - house->getPayRentWarnings(); Item* letter = Item::CreateItem(ITEM_LETTER_STAMPED); std::string period = ""; switch (rentPeriod) { case RENTPERIOD_DAILY: period = "daily"; break; case RENTPERIOD_WEEKLY: period = "weekly"; break; case RENTPERIOD_MONTHLY: period = "monthly"; break; case RENTPERIOD_YEARLY: period = "annual"; break; default: break; } std::ostringstream ss; ss << "Warning! \nThe " << period << " rent of " << house->getRent() << " gold for your house \"" << house->getName() << "\" is payable. Have it within " << daysLeft << " days or you will lose this house."; letter->setText(ss.str()); g_game.internalAddItem(player->getInbox(), letter, INDEX_WHEREEVER, FLAG_NOLIMIT); house->setPayRentWarnings(house->getPayRentWarnings() + 1); } else { house->setHouseOwner(0, true, player); } } if (player->isOffline()) { IOLoginData::getInstance()->savePlayer(player); delete player; } } } return true; }
bool IOMapSerialize::saveHouseInfo(Map* map) { Database* db = Database::getInstance(); DBTransaction transaction; if (!transaction.begin()) { return false; } if (!db->executeQuery("DELETE FROM `house_lists`")) { return false; } std::ostringstream query; for (const auto& it : Houses::getInstance().getHouses()) { House* house = it.second; query << "SELECT `id` FROM `houses` WHERE `id` = " << house->getHouseId(); DBResult* result = db->storeQuery(query.str()); if (result) { db->freeResult(result); query.str(""); query << "UPDATE `houses` SET `owner` = " << house->getHouseOwner() << ", `paid` = " << house->getPaidUntil() << ", `warnings` = " << house->getPayRentWarnings() << ", `name` = " << db->escapeString(house->getName()) << ", `town_id` = " << house->getTownId() << ", `rent` = " << house->getRent() << ", `size` = " << house->getHouseTiles().size() << ", `beds` = " << house->getBedCount() << " WHERE `id` = " << house->getHouseId(); } else { query.str(""); query << "INSERT INTO `houses` (`id`, `owner`, `paid`, `warnings`, `name`, `town_id`, `rent`, `size`, `beds`) VALUES (" << house->getHouseId() << "," << house->getHouseOwner() << "," << house->getPaidUntil() << "," << house->getPayRentWarnings() << "," << db->escapeString(house->getName()) << "," << house->getTownId() << "," << house->getRent() << "," << house->getHouseTiles().size() << "," << house->getBedCount() << ")"; } db->executeQuery(query.str()); query.str(""); } DBInsert stmt; stmt.setQuery("INSERT INTO `house_lists` (`house_id` , `listid` , `list`) VALUES "); for (const auto& it : Houses::getInstance().getHouses()) { House* house = it.second; std::string listText; if (house->getAccessList(GUEST_LIST, listText) && listText != "") { query << house->getHouseId() << "," << GUEST_LIST << "," << db->escapeString(listText); if (!stmt.addRow(query)) { return false; } } if (house->getAccessList(SUBOWNER_LIST, listText) && listText != "") { query << house->getHouseId() << "," << SUBOWNER_LIST << "," << db->escapeString(listText); if (!stmt.addRow(query)) { return false; } } for (Door* door : house->getHouseDoors()) { if (door->getAccessList(listText) && listText != "") { query << house->getHouseId() << "," << door->getDoorId() << "," << db->escapeString(listText); if (!stmt.addRow(query)) { return false; } } } } if (!stmt.execute()) { return false; } return transaction.commit(); }