diff --git a/data/global.lua b/data/global.lua index 0c2e01e219..0e1ba54f64 100644 --- a/data/global.lua +++ b/data/global.lua @@ -68,3 +68,99 @@ end if not nextUseStaminaTime then nextUseStaminaTime = {} end + +function getPlayerDatabaseInfo(name_or_guid) + local sql_where = "" + + if type(name_or_guid) == 'string' then + sql_where = "WHERE `p`.`name`=" .. db.escapeString(name_or_guid) .. "" + elseif type(name_or_guid) == 'number' then + sql_where = "WHERE `p`.`id`='" .. name_or_guid .. "'" + else + return false + end + + local sql_query = [[ + SELECT + `p`.`id` as `guid`, + `p`.`name`, + CASE WHEN `po`.`player_id` IS NULL + THEN 0 + ELSE 1 + END AS `online`, + `p`.`group_id`, + `p`.`level`, + `p`.`experience`, + `p`.`vocation`, + `p`.`maglevel`, + `p`.`skill_fist`, + `p`.`skill_club`, + `p`.`skill_sword`, + `p`.`skill_axe`, + `p`.`skill_dist`, + `p`.`skill_shielding`, + `p`.`skill_fishing`, + `p`.`town_id`, + `p`.`balance`, + `gm`.`guild_id`, + `gm`.`nick`, + `g`.`name` AS `guild_name`, + CASE WHEN `p`.`id` = `g`.`ownerid` + THEN 1 + ELSE 0 + END AS `is_leader`, + `gr`.`name` AS `rank_name`, + `gr`.`level` AS `rank_level`, + `h`.`id` AS `house_id`, + `h`.`name` AS `house_name`, + `h`.`town_id` AS `house_town` + FROM `players` AS `p` + LEFT JOIN `players_online` AS `po` + ON `p`.`id` = `po`.`player_id` + LEFT JOIN `guild_membership` AS `gm` + ON `p`.`id` = `gm`.`player_id` + LEFT JOIN `guilds` AS `g` + ON `gm`.`guild_id` = `g`.`id` + LEFT JOIN `guild_ranks` AS `gr` + ON `gm`.`rank_id` = `gr`.`id` + LEFT JOIN `houses` AS `h` + ON `p`.`id` = `h`.`owner` + ]] .. sql_where + + local query = db.storeQuery(sql_query) + if not query then + return false + end + + local info = { + ["guid"] = result.getNumber(query, "guid"), + ["name"] = result.getString(query, "name"), + ["online"] = result.getNumber(query, "online"), + ["group_id"] = result.getNumber(query, "group_id"), + ["level"] = result.getNumber(query, "level"), + ["experience"] = result.getNumber(query, "experience"), + ["vocation"] = result.getNumber(query, "vocation"), + ["maglevel"] = result.getNumber(query, "maglevel"), + ["skill_fist"] = result.getNumber(query, "skill_fist"), + ["skill_club"] = result.getNumber(query, "skill_club"), + ["skill_sword"] = result.getNumber(query, "skill_sword"), + ["skill_axe"] = result.getNumber(query, "skill_axe"), + ["skill_dist"] = result.getNumber(query, "skill_dist"), + ["skill_shielding"] = result.getNumber(query, "skill_shielding"), + ["skill_fishing"] = result.getNumber(query, "skill_fishing"), + ["town_id"] = result.getNumber(query, "town_id"), + ["balance"] = result.getNumber(query, "balance"), + ["guild_id"] = result.getNumber(query, "guild_id"), + ["nick"] = result.getString(query, "nick"), + ["guild_name"] = result.getString(query, "guild_name"), + ["is_leader"] = result.getNumber(query, "is_leader"), + ["rank_name"] = result.getString(query, "rank_name"), + ["rank_level"] = result.getNumber(query, "rank_level"), + ["house_id"] = result.getNumber(query, "house_id"), + ["house_name"] = result.getString(query, "house_name"), + ["house_town"] = result.getNumber(query, "house_town") + } + + result.free(query) + return info +end diff --git a/data/lib/compat/compat.lua b/data/lib/compat/compat.lua index 0beaba1a27..4ba4dc6236 100644 --- a/data/lib/compat/compat.lua +++ b/data/lib/compat/compat.lua @@ -1312,3 +1312,7 @@ end function doPlayerTakeItem(cid, itemid, count) return Player(cid):removeItem(itemid, count) end + +function isNumber(str) + return tonumber(str) ~= nil +end diff --git a/data/lib/core/player.lua b/data/lib/core/player.lua index 819d0ea3d2..403a91c8c9 100644 --- a/data/lib/core/player.lua +++ b/data/lib/core/player.lua @@ -100,3 +100,106 @@ function Player.addManaSpent(...) APPLY_SKILL_MULTIPLIER = true return ret end + +-- Always pass the number through the isValidMoney function first before using the transferMoneyTo +function Player.transferMoneyTo(self, target, amount) + if not target then + return false + end + + -- See if you can afford this transfer + local balance = self:getBankBalance() + if amount > balance then + return false + end + + -- See if player is online + local targetPlayer = Player(target.guid) + if targetPlayer then + targetPlayer:setBankBalance(targetPlayer:getBankBalance() + amount) + else + db.query("UPDATE `players` SET `balance` = `balance` + " .. amount .. " WHERE `id` = '" .. target.guid .. "'") + end + + self:setBankBalance(self:getBankBalance() - amount) + return true +end + +function Player.canCarryMoney(self, amount) + -- Anyone can carry as much imaginary money as they desire + if amount == 0 then + return true + end + + -- The 3 below loops will populate these local variables + local totalWeight = 0 + local inventorySlots = 0 + + -- Add crystal coins to totalWeight and inventorySlots + local type_crystal = ItemType(ITEM_CRYSTAL_COIN) + local crystalCoins = math.floor(amount / 10000) + if crystalCoins > 0 then + amount = amount - (crystalCoins * 10000) + while crystalCoins > 0 do + local count = math.min(100, crystalCoins) + totalWeight = totalWeight + type_crystal:getWeight(count) + crystalCoins = crystalCoins - count + inventorySlots = inventorySlots + 1 + end + end + + -- Add platinum coins to totalWeight and inventorySlots + local type_platinum = ItemType(ITEM_PLATINUM_COIN) + local platinumCoins = math.floor(amount / 100) + if platinumCoins > 0 then + amount = amount - (platinumCoins * 100) + while platinumCoins > 0 do + local count = math.min(100, platinumCoins) + totalWeight = totalWeight + type_platinum:getWeight(count) + platinumCoins = platinumCoins - count + inventorySlots = inventorySlots + 1 + end + end + + -- Add gold coins to totalWeight and inventorySlots + local type_gold = ItemType(ITEM_GOLD_COIN) + if amount > 0 then + while amount > 0 do + local count = math.min(100, amount) + totalWeight = totalWeight + type_gold:getWeight(count) + amount = amount - count + inventorySlots = inventorySlots + 1 + end + end + + -- If player don't have enough capacity to carry this money + if self:getFreeCapacity() < totalWeight then + return false + end + + -- If player don't have enough available inventory slots to carry this money + local backpack = self:getSlotItem(CONST_SLOT_BACKPACK) + if not backpack or backpack:getEmptySlots(true) < inventorySlots then + return false + end + return true +end + +function Player.withdrawMoney(self, amount) + local balance = self:getBankBalance() + if amount > balance or not self:addMoney(amount) then + return false + end + + self:setBankBalance(balance - amount) + return true +end + +function Player.depositMoney(self, amount) + if not self:removeMoney(amount) then + return false + end + + self:setBankBalance(self:getBankBalance() + amount) + return true +end diff --git a/data/npc/lib/npc.lua b/data/npc/lib/npc.lua index 87d64beefe..a0974c352d 100644 --- a/data/npc/lib/npc.lua +++ b/data/npc/lib/npc.lua @@ -132,3 +132,25 @@ end function Player.getTotalMoney(self) return self:getMoney() + self:getBankBalance() end + +function isValidMoney(money) + return isNumber(money) and money > 0 +end + +function getMoneyCount(string) + local b, e = string:find("%d+") + local money = b and e and tonumber(string:sub(b, e)) or -1 + if isValidMoney(money) then + return money + end + return -1 +end + +function getMoneyWeight(money) + local gold = money + local crystal = math.floor(gold / 10000) + gold = gold - crystal * 10000 + local platinum = math.floor(gold / 100) + gold = gold - platinum * 100 + return (ItemType(ITEM_CRYSTAL_COIN):getWeight() * crystal) + (ItemType(ITEM_PLATINUM_COIN):getWeight() * platinum) + (ItemType(ITEM_GOLD_COIN):getWeight() * gold) +end