Skip to content

Commit

Permalink
Added several functions mainly related to banker NPC (#3085)
Browse files Browse the repository at this point in the history
These functions were added in order for the upcoming sample `Banker` NPC #2934 and in the future for the guild balance feature #2214 

- function getPlayerDatabaseInfo(name_or_guid)
TFS 1.3 function that queries for player information from the database, returns a table of useful information if success, false if player doesn't exist.

- function isNumber(str)
used in several distros but wasn't there on compat.lua yet
- function Player.transferMoneyTo(self, target, amount)
- function Player.withdrawMoney(self, amount)
- function Player.depositMoney(self, amount)
- function isValidMoney(money)
- function getMoneyCount(string)
- function getMoneyWeight(money)

Co-authored-by: Znote <stefan_brannfjell@live.no>
  • Loading branch information
Evil Puncker and Znote authored Jun 16, 2020
1 parent d37e264 commit 3cb5405
Show file tree
Hide file tree
Showing 4 changed files with 225 additions and 0 deletions.
96 changes: 96 additions & 0 deletions data/global.lua
Original file line number Diff line number Diff line change
Expand Up @@ -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
4 changes: 4 additions & 0 deletions data/lib/compat/compat.lua
Original file line number Diff line number Diff line change
Expand Up @@ -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
103 changes: 103 additions & 0 deletions data/lib/core/player.lua
Original file line number Diff line number Diff line change
Expand Up @@ -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
22 changes: 22 additions & 0 deletions data/npc/lib/npc.lua
Original file line number Diff line number Diff line change
Expand Up @@ -132,3 +132,25 @@ end
function Player.getTotalMoney(self)
return self:getMoney() + self:getBankBalance()
end

function isValidMoney(money)
return isNumber(money) and money > 0

This comment has been minimized.

Copy link
@luanluciano93

luanluciano93 Jun 24, 2020

Contributor

Couldn't you directly use "return tonumber (money) ~ = nil and money> 0" instead of using the isValidMoney (money) function?

This comment has been minimized.

Copy link
@manojo123

manojo123 Aug 1, 2020

I think OP did the refactored function for more cleaner solution

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

0 comments on commit 3cb5405

Please sign in to comment.