Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: cyclopedia house auction #3022

Open
wants to merge 32 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
32 commits
Select commit Hold shift + click to select a range
fef5579
init
murilo09 Oct 27, 2024
f16662f
Code format - (Clang-format)
github-actions[bot] Oct 27, 2024
8b3e60f
sonar issues
murilo09 Oct 27, 2024
bf22602
revert
murilo09 Oct 28, 2024
6ace26f
Merge branch 'main' into test-house
murilo09 Oct 29, 2024
75fc10d
fix: load state into house object
phacUFPE Oct 29, 2024
f6a76ff
feat: show move out info
murilo09 Oct 30, 2024
d27a246
fix days to end bid
murilo09 Oct 30, 2024
9f7cc62
Merge branch 'main' into test-house
murilo09 Oct 30, 2024
6a35471
fix load house logic
murilo09 Oct 30, 2024
e057cd0
feat: transfer
murilo09 Oct 30, 2024
95c16ed
Code format - (Clang-format)
github-actions[bot] Oct 30, 2024
19ce395
missing column schema.sql
murilo09 Oct 30, 2024
1a8c761
some fixes
murilo09 Oct 30, 2024
aab4b95
error handling
murilo09 Oct 30, 2024
f53b628
Code format - (Clang-format)
github-actions[bot] Oct 30, 2024
f3667aa
missing errors
murilo09 Oct 30, 2024
cbbdc2d
configurable days to close bid
murilo09 Oct 30, 2024
53bf0cf
Merge branch 'main' into test-house
murilo09 Oct 30, 2024
798ece7
fix compilation
murilo09 Oct 30, 2024
eead52a
Merge branch 'main' into test-house
majestyotbr Oct 30, 2024
da4398d
fix migration
murilo09 Oct 30, 2024
6a5ecf2
sonar issue
murilo09 Oct 30, 2024
c75da85
fix copy
murilo09 Oct 31, 2024
45e0baf
Merge branch 'main' into test-house
murilo09 Oct 31, 2024
1a2934d
Code format - (Clang-format)
github-actions[bot] Oct 31, 2024
7370433
fix: using enum
murilo09 Oct 31, 2024
0fe8b2d
fix: remove items from house when removing owner
murilo09 Oct 31, 2024
ff66f91
Merge branch 'main' into test-house
murilo09 Oct 31, 2024
2c5bf60
Merge branch 'main' into test-house
murilo09 Nov 1, 2024
26a2d60
Merge branch 'main' into test-house
murilo09 Nov 4, 2024
e2e9ddf
fix: reversed houseBidId with accountId on db query
phacUFPE Nov 19, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 3 additions & 1 deletion config.lua.dist
Original file line number Diff line number Diff line change
Expand Up @@ -344,9 +344,11 @@ Setting this to false may pose risks; if a house is abandoned and contains a lar
]]
-- Periods: daily/weekly/monthly/yearly/never
-- Base: sqm,rent,sqm+rent
toggleCyclopediaHouseAuction = true
daysToCloseBid = 7
housePriceRentMultiplier = 0.0
housePriceEachSQM = 1000
houseRentPeriod = "never"
houseRentPeriod = "monthly"
houseRentRate = 1.0
houseOwnedByAccount = false
houseBuyLevel = 100
Expand Down
28 changes: 27 additions & 1 deletion data-otservbr-global/migrations/46.lua
Original file line number Diff line number Diff line change
@@ -1,3 +1,29 @@
function onUpdateDatabase()
return false -- true = There are others migrations file | false = this is the last migration file
logger.info("Updating database to version 44 (House Auction)")

db.query([[
ALTER TABLE `houses`
DROP `bid`,
DROP `bid_end`,
DROP `last_bid`,
DROP `highest_bidder`
]])

db.query([[
ALTER TABLE `houses`
ADD `bidder` int(11) NOT NULL DEFAULT '0',
ADD `bidder_name` varchar(255) NOT NULL DEFAULT '',
ADD `highest_bid` int(11) NOT NULL DEFAULT '0',
ADD `internal_bid` int(11) NOT NULL DEFAULT '0',
ADD `bid_end_date` int(11) NOT NULL DEFAULT '0',
ADD `state` smallint(5) UNSIGNED NOT NULL DEFAULT '0',
ADD `transfer_status` tinyint(1) DEFAULT '0'
]])

db.query([[
ALTER TABLE `accounts`
ADD `house_bid_id` int(11) NOT NULL DEFAULT '0'
]])

return true
end
3 changes: 3 additions & 0 deletions data-otservbr-global/migrations/47.lua
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
function onUpdateDatabase()
return false -- true = There are others migrations file | false = this is the last migration file
end
1,970 changes: 985 additions & 985 deletions data-otservbr-global/world/otservbr-house.xml

Large diffs are not rendered by default.

24 changes: 0 additions & 24 deletions data/scripts/globalevents/server_initialization.lua
Original file line number Diff line number Diff line change
Expand Up @@ -27,29 +27,6 @@ local function moveExpiredBansToHistory()
end
end

-- Function to check and process house auctions
local function processHouseAuctions()
local resultId = db.storeQuery("SELECT `id`, `highest_bidder`, `last_bid`, " .. "(SELECT `balance` FROM `players` WHERE `players`.`id` = `highest_bidder`) AS `balance` " .. "FROM `houses` WHERE `owner` = 0 AND `bid_end` != 0 AND `bid_end` < " .. os.time())
if resultId then
repeat
local house = House(Result.getNumber(resultId, "id"))
if house then
local highestBidder = Result.getNumber(resultId, "highest_bidder")
local balance = Result.getNumber(resultId, "balance")
local lastBid = Result.getNumber(resultId, "last_bid")
if balance >= lastBid then
db.query("UPDATE `players` SET `balance` = " .. (balance - lastBid) .. " WHERE `id` = " .. highestBidder)
house:setHouseOwner(highestBidder)
end

db.asyncQuery("UPDATE `houses` SET `last_bid` = 0, `bid_end` = 0, `highest_bidder` = 0, `bid` = 0 " .. "WHERE `id` = " .. house:getId())
end
until not Result.next(resultId)

Result.free(resultId)
end
end

-- Function to store towns in the database
local function storeTownsInDatabase()
db.query("TRUNCATE TABLE `towns`")
Expand Down Expand Up @@ -150,7 +127,6 @@ function serverInitialization.onStartup()

cleanupDatabase()
moveExpiredBansToHistory()
processHouseAuctions()
storeTownsInDatabase()
checkAndLogDuplicateValues({ "Global", "GlobalStorage", "Storage" })
updateEventRates()
Expand Down
8 changes: 5 additions & 3 deletions data/scripts/talkactions/player/buy_house.lua
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,8 @@ function buyHouse.onSay(player, words, param)
return true
end

buyHouse:separator(" ")
buyHouse:groupType("normal")
buyHouse:register()
if not configManager.getBoolean(configKeys.CYCLOPEDIA_HOUSE_AUCTION) then
buyHouse:separator(" ")
buyHouse:groupType("normal")
buyHouse:register()
end
8 changes: 5 additions & 3 deletions data/scripts/talkactions/player/leave_house.lua
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,8 @@ function leaveHouse.onSay(player, words, param)
return true
end

leaveHouse:separator(" ")
leaveHouse:groupType("normal")
leaveHouse:register()
if not configManager.getBoolean(configKeys.CYCLOPEDIA_HOUSE_AUCTION) then
leaveHouse:separator(" ")
leaveHouse:groupType("normal")
leaveHouse:register()
end
8 changes: 5 additions & 3 deletions data/scripts/talkactions/player/sell_house.lua
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,8 @@ function sellHouse.onSay(player, words, param)
return true
end

sellHouse:separator(" ")
sellHouse:groupType("normal")
sellHouse:register()
if not configManager.getBoolean(configKeys.CYCLOPEDIA_HOUSE_AUCTION) then
sellHouse:separator(" ")
sellHouse:groupType("normal")
sellHouse:register()
end
14 changes: 9 additions & 5 deletions schema.sql
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ CREATE TABLE IF NOT EXISTS `server_config` (
CONSTRAINT `server_config_pk` PRIMARY KEY (`config`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

INSERT INTO `server_config` (`config`, `value`) VALUES ('db_version', '46'), ('motd_hash', ''), ('motd_num', '0'), ('players_record', '0');
INSERT INTO `server_config` (`config`, `value`) VALUES ('db_version', '47'), ('motd_hash', ''), ('motd_num', '0'), ('players_record', '0');

-- Table structure `accounts`
CREATE TABLE IF NOT EXISTS `accounts` (
Expand All @@ -24,6 +24,7 @@ CREATE TABLE IF NOT EXISTS `accounts` (
`tournament_coins` int(12) UNSIGNED NOT NULL DEFAULT '0',
`creation` int(11) UNSIGNED NOT NULL DEFAULT '0',
`recruiter` INT(6) DEFAULT 0,
`house_bid_id` int(11) NOT NULL DEFAULT '0',
CONSTRAINT `accounts_pk` PRIMARY KEY (`id`),
CONSTRAINT `accounts_unique` UNIQUE (`name`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
Expand Down Expand Up @@ -451,13 +452,16 @@ CREATE TABLE IF NOT EXISTS `houses` (
`name` varchar(255) NOT NULL,
`rent` int(11) NOT NULL DEFAULT '0',
`town_id` int(11) NOT NULL DEFAULT '0',
`bid` int(11) NOT NULL DEFAULT '0',
`bid_end` int(11) NOT NULL DEFAULT '0',
`last_bid` int(11) NOT NULL DEFAULT '0',
`highest_bidder` int(11) NOT NULL DEFAULT '0',
`size` int(11) NOT NULL DEFAULT '0',
`guildid` int(11),
`beds` int(11) NOT NULL DEFAULT '0',
`bidder` int(11) NOT NULL DEFAULT '0',
`bidder_name` varchar(255) NOT NULL DEFAULT '',
`highest_bid` int(11) NOT NULL DEFAULT '0',
`internal_bid` int(11) NOT NULL DEFAULT '0',
`bid_end_date` int(11) NOT NULL DEFAULT '0',
`state` smallint(5) UNSIGNED NOT NULL DEFAULT '0',
`transfer_status` tinyint(1) DEFAULT '0',
INDEX `owner` (`owner`),
INDEX `town_id` (`town_id`),
CONSTRAINT `houses_pk` PRIMARY KEY (`id`)
Expand Down
7 changes: 7 additions & 0 deletions src/account/account.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -300,3 +300,10 @@ uint32_t Account::getAccountAgeInDays() const {
[[nodiscard]] time_t Account::getPremiumLastDay() const {
return m_account->premiumLastDay;
}

uint32_t Account::getHouseBidId() const {
return m_account->houseBidId;
}
void Account::setHouseBidId(uint32_t houseId) {
m_account->houseBidId = houseId;
}
3 changes: 3 additions & 0 deletions src/account/account.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -119,6 +119,9 @@ class Account {

std::tuple<phmap::flat_hash_map<std::string, uint64_t>, AccountErrors_t> getAccountPlayers() const;

void setHouseBidId(uint32_t houseId);
uint32_t getHouseBidId() const;

// Old protocol compat
void setProtocolCompat(bool toggle);

Expand Down
1 change: 1 addition & 0 deletions src/account/account_info.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -28,4 +28,5 @@ struct AccountInfo {
time_t sessionExpires = 0;
uint32_t premiumDaysPurchased = 0;
uint32_t creationTime = 0;
uint32_t houseBidId = 0;
};
3 changes: 2 additions & 1 deletion src/account/account_repository_db.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -47,12 +47,13 @@ bool AccountRepositoryDB::loadBySession(const std::string &sessionKey, std::uniq
bool AccountRepositoryDB::save(const std::unique_ptr<AccountInfo> &accInfo) {
bool successful = g_database().executeQuery(
fmt::format(
"UPDATE `accounts` SET `type` = {}, `premdays` = {}, `lastday` = {}, `creation` = {}, `premdays_purchased` = {} WHERE `id` = {}",
"UPDATE `accounts` SET `type` = {}, `premdays` = {}, `lastday` = {}, `creation` = {}, `premdays_purchased` = {}, `house_bid_id` = {} WHERE `id` = {}",
accInfo->accountType,
accInfo->premiumRemainingDays,
accInfo->premiumLastDay,
accInfo->creationTime,
accInfo->premiumDaysPurchased,
accInfo->houseBidId,
accInfo->id
)
);
Expand Down
2 changes: 2 additions & 0 deletions src/config/config_enums.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@ enum ConfigKey_t : uint16_t {
CONVERT_UNSAFE_SCRIPTS,
CORE_DIRECTORY,
CRITICALCHANCE,
CYCLOPEDIA_HOUSE_AUCTION,
DATA_DIRECTORY,
DAY_KILLS_TO_RED,
DEATH_LOSE_PERCENT,
Expand Down Expand Up @@ -110,6 +111,7 @@ enum ConfigKey_t : uint16_t {
HAZARD_PODS_TIME_TO_DAMAGE,
HAZARD_PODS_TIME_TO_SPAWN,
HAZARD_SPAWN_PLUNDER_MULTIPLIER,
DAYS_TO_CLOSE_BID,
HOUSE_BUY_LEVEL,
HOUSE_LOSE_AFTER_INACTIVITY,
HOUSE_OWNED_BY_ACCOUNT,
Expand Down
2 changes: 2 additions & 0 deletions src/config/configmanager.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -157,6 +157,7 @@ bool ConfigManager::load() {
loadBoolConfig(L, VIP_SYSTEM_ENABLED, "vipSystemEnabled", false);
loadBoolConfig(L, WARN_UNSAFE_SCRIPTS, "warnUnsafeScripts", true);
loadBoolConfig(L, XP_DISPLAY_MODE, "experienceDisplayRates", true);
loadBoolConfig(L, CYCLOPEDIA_HOUSE_AUCTION, "toggleCyclopediaHouseAuction", true);

loadFloatConfig(L, BESTIARY_RATE_CHARM_SHOP_PRICE, "bestiaryRateCharmShopPrice", 1.0);
loadFloatConfig(L, COMBAT_CHAIN_SKILL_FORMULA_AXE, "combatChainSkillFormulaAxe", 0.9);
Expand Down Expand Up @@ -255,6 +256,7 @@ bool ConfigManager::load() {
loadIntConfig(L, HAZARD_PODS_TIME_TO_DAMAGE, "hazardPodsTimeToDamage", 2000);
loadIntConfig(L, HAZARD_PODS_TIME_TO_SPAWN, "hazardPodsTimeToSpawn", 4000);
loadIntConfig(L, HAZARD_SPAWN_PLUNDER_MULTIPLIER, "hazardSpawnPlunderMultiplier", 25);
loadIntConfig(L, DAYS_TO_CLOSE_BID, "daysToCloseBid", 7);
loadIntConfig(L, HOUSE_BUY_LEVEL, "houseBuyLevel", 0);
loadIntConfig(L, HOUSE_LOSE_AFTER_INACTIVITY, "houseLoseAfterInactivity", 0);
loadIntConfig(L, HOUSE_PRICE_PER_SQM, "housePriceEachSQM", 1000);
Expand Down
122 changes: 122 additions & 0 deletions src/creatures/players/player.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@
#include "enums/object_category.hpp"
#include "enums/player_blessings.hpp"
#include "enums/player_icons.hpp"
#include "enums/player_cyclopedia.hpp"
#include "game/game.hpp"
#include "game/modal_window/modal_window.hpp"
#include "game/scheduling/dispatcher.hpp"
Expand Down Expand Up @@ -2264,6 +2265,22 @@ void Player::sendOutfitWindow() const {
}
}

void Player::sendCyclopediaHouseList(const HouseMap &houses) const {
if (client) {
client->sendCyclopediaHouseList(houses);
}
}
void Player::sendResourceBalance(Resource_t resourceType, uint64_t value) const {
if (client) {
client->sendResourceBalance(resourceType, value);
}
}
void Player::sendHouseAuctionMessage(uint32_t houseId, HouseAuctionType type, uint8_t index, bool bidSuccess /* = false*/) const {
if (client) {
client->sendHouseAuctionMessage(houseId, type, index, bidSuccess);
}
}

// Imbuements

void Player::onApplyImbuement(const Imbuement* imbuement, const std::shared_ptr<Item> &item, uint8_t slot, bool protectionCharm) {
Expand Down Expand Up @@ -10427,3 +10444,108 @@ uint16_t Player::getPlayerVocationEnum() const {

return Vocation_t::VOCATION_NONE;
}

BidErrorMessage Player::canBidHouse(uint32_t houseId) {
using enum BidErrorMessage;
const auto house = g_game().map.houses.getHouseByClientId(houseId);
if (!house) {
return Internal;
}

if (getPlayerVocationEnum() == Vocation_t::VOCATION_NONE) {
return Rookgaard;
}

if (!isPremium()) {
return Premium;
}

if (getAccount()->getHouseBidId() != 0) {
return OnlyOneBid;
}

if (getBankBalance() < (house->getRent() + house->getHighestBid())) {
return NotEnoughMoney;
}

if (house->isGuildhall()) {
if (getGuildRank() && getGuildRank()->level != 3) {
return Guildhall;
}

if (getGuild() && getGuild()->getBankBalance() < (house->getRent() + house->getHighestBid())) {
return NotEnoughGuildMoney;
}
}

return NoError;
}

TransferErrorMessage Player::canTransferHouse(uint32_t houseId, uint32_t newOwnerGUID) {
using enum TransferErrorMessage;
const auto house = g_game().map.houses.getHouseByClientId(houseId);
if (!house) {
return Internal;
}

if (getGUID() != house->getOwner()) {
return NotHouseOwner;
}

if (getGUID() == newOwnerGUID) {
return AlreadyTheOwner;
}

const auto newOwner = g_game().getPlayerByGUID(newOwnerGUID, true);
if (!newOwner) {
return CharacterNotExist;
}

if (newOwner->getPlayerVocationEnum() == Vocation_t::VOCATION_NONE) {
return Rookgaard;
}

if (!newOwner->isPremium()) {
return Premium;
}

if (newOwner->getAccount()->getHouseBidId() != 0) {
return OnlyOneBid;
}

return Success;
}

AcceptTransferErrorMessage Player::canAcceptTransferHouse(uint32_t houseId) {
using enum AcceptTransferErrorMessage;
const auto house = g_game().map.houses.getHouseByClientId(houseId);
if (!house) {
return Internal;
}

if (getGUID() != house->getBidder()) {
return NotNewOwner;
}

if (!isPremium()) {
return Premium;
}

if (getAccount()->getHouseBidId() != 0) {
return AlreadyBid;
}

if (getPlayerVocationEnum() == Vocation_t::VOCATION_NONE) {
return Rookgaard;
}

if (getBankBalance() < (house->getRent() + house->getInternalBid())) {
return Frozen;
}

if (house->getTransferStatus()) {
return AlreadyAccepted;
}

return Success;
}
Loading
Loading