2018-11-10 14:16:52 -08:00
--- Returns true if given value is a finite number; otherwise false or nil if value is not of type string nor number.
function x_marketplace . isfinite ( value )
if type ( value ) == " string " then
value = tonumber ( value )
if value == nil then return nil end
elseif type ( value ) ~= " number " then
return nil
end
return value > - math.huge and value < math.huge
end
--- Returns true if given value is not a number (NaN); otherwise false or nil if value is not of type string nor number.
function x_marketplace . isnan ( value )
if type ( value ) == " string " then
value = tonumber ( value )
if value == nil then return nil end
elseif type ( value ) ~= " number " then
return nil
end
return value ~= value
end
2018-11-13 15:48:25 -08:00
local function esc ( x )
return ( x : gsub ( ' %% ' , ' %%%% ' )
: gsub ( ' ^%^ ' , ' %%^ ' )
: gsub ( ' %$$ ' , ' %%$ ' )
: gsub ( ' %( ' , ' %%( ' )
: gsub ( ' %) ' , ' %%) ' )
: gsub ( ' %. ' , ' %%. ' )
: gsub ( ' %, ' , ' %%, ' )
: gsub ( ' %; ' , ' %%; ' )
: gsub ( ' %[ ' , ' %%[ ' )
: gsub ( ' %] ' , ' %%] ' )
: gsub ( ' %* ' , ' %%* ' )
: gsub ( ' %+ ' , ' %%+ ' )
: gsub ( ' %- ' , ' %%- ' )
: gsub ( ' %? ' , ' %%? ' ) )
end
2018-11-10 14:16:52 -08:00
-- rounds a number to the nearest decimal places
local function round ( val , decimal )
if ( decimal ) then
return math.floor ( ( val * 10 ^ decimal ) + 0.5 ) / ( 10 ^ decimal )
else
return math.floor ( val + 0.5 )
end
end
2018-11-02 13:24:33 -07:00
-- Search items in marketplace object
-- @param string the string
-- @return string with found items, if no items found returns boolean false
function x_marketplace . store_find ( string )
local found = " "
2018-11-13 15:48:25 -08:00
local str = esc ( string )
2018-11-02 13:24:33 -07:00
for k , v in pairs ( x_marketplace.store_list ) do
2018-11-13 15:48:25 -08:00
if string.find ( k , str ) then
2018-11-02 13:24:33 -07:00
found = found .. k .. " buy: " .. string.format ( " %.2f " , v.buy ) .. " sell: " .. string.format ( " %.2f " , v.sell ) .. " \n "
end
end
if found == " " then
found = false
end
return found
end
-- Get random items from the store
-- @param number the integer
-- @return string with found items
function x_marketplace . store_get_random ( number )
local keys , i , suggest = { } , 1 , " "
local how_many = number or 5
for k , v in pairs ( x_marketplace.store_list ) do
keys [ i ] = k
i = i + 1
end
for i = 1 , how_many do
suggest = suggest .. " \n " .. keys [ math.random ( 1 , # keys ) ]
end
return suggest
end
-- Get players balance of BitGold
-- @param name the string of player name
-- @return string the current balance
function x_marketplace . get_player_balance ( name )
if not name then
return " "
end
local player = minetest.get_player_by_name ( name )
local balance = player : get_attribute ( " balance " ) or 0
return balance
end
-- Set players balance of BitGold
-- @param name the string of player name
-- @param amount the number of what should be added/deducted (if negative) from players balance
-- @return string the balance info message, returns false if not enough funds
function x_marketplace . set_player_balance ( name , amount )
if not name or not amount then
return " "
end
local player = minetest.get_player_by_name ( name )
local balance = player : get_attribute ( " balance " ) or 0
local new_balance = balance + amount
if new_balance < 0 then
2018-11-09 16:15:04 -08:00
return false , " below "
end
if new_balance > x_marketplace.max_balance then
return false , " above "
2018-11-02 13:24:33 -07:00
end
player : set_attribute ( " balance " , new_balance )
return new_balance
end
2018-11-10 14:16:52 -08:00
function x_marketplace . find_signs ( player_pos , text )
local pos0 = vector.subtract ( player_pos , 2 )
local pos1 = vector.add ( player_pos , 2 )
local positions = minetest.find_nodes_in_area ( pos0 , pos1 , " default:sign_wall_steel " )
local found = false
if # positions <= 0 then
return false
end
for k , v in pairs ( positions ) do
local sign_meta = minetest.get_meta ( v )
local sign_text = sign_meta : get_string ( " text " ) : trim ( )
if sign_text == text then
found = true
break
end
end
return found
end
minetest.register_craftitem ( " x_marketplace:head " , {
description = " head " ,
inventory_image = " x_marketplace_head-front.png " ,
wield_image = " x_marketplace_head-front.png " ,
stack_max = 1 ,
wield_scale = { x = 1.5 , y = 1.5 , z = 6 } ,
on_use = function ( itemstack , user , pointed_thing )
minetest.chat_send_player ( user : get_player_name ( ) , minetest.colorize ( x_marketplace.colors . yellow , " MARKET PLACE: If you want to sell the head, you have to punch steel sign with text '/mp sellhead' on it. " ) )
if pointed_thing.type == " node " then
local node = minetest.get_node ( pointed_thing.under )
if node.name == " default:sign_wall_steel " then
local node_meta = minetest.get_meta ( pointed_thing.under )
if node_meta : get_string ( " text " ) : trim ( ) == " /mp sellhead " then
local stack_meta = itemstack : to_table ( ) . meta
local stack_meta_value = tonumber ( stack_meta.value )
local stack_meta_owner = stack_meta.owner
-- sell item
local new_balance = x_marketplace.set_player_balance ( user : get_player_name ( ) , stack_meta_value )
if new_balance then
minetest.sound_play ( " x_marketplace_gold " , {
object = user ,
max_hear_distance = 10 ,
gain = 1.0
} )
minetest.chat_send_player ( user : get_player_name ( ) , minetest.colorize ( x_marketplace.colors . green , " MARKET PLACE: You sold " .. stack_meta_owner .. " head for " .. stack_meta_value .. " BitGold. Your new balance is: " .. new_balance .. " BitGold " ) )
itemstack : take_item ( )
else
minetest.chat_send_player ( user : get_player_name ( ) , minetest.colorize ( x_marketplace.colors . yellow , " MARKET PLACE: You will go above the maximum balance if you sell this item. Transaction cancelled. " ) )
end
end
end
end
return itemstack
end ,
} )
minetest.register_on_dieplayer ( function ( player )
local player_name = player : get_player_name ( )
local balance = tonumber ( x_marketplace.get_player_balance ( player_name ) )
local lost_value , new_balance
if balance then
-- no money, nothing to loose
if balance == 0 then
return
-- almost no money, drop everything
elseif balance <= 10 then
lost_value = balance
-- loose between 5-10% from balance
else
lost_value = ( balance / 100 ) * math.random ( 5 , 10 )
end
lost_value = round ( lost_value , 2 )
new_balance = x_marketplace.set_player_balance ( player_name , lost_value * - 1 )
local pos = vector.round ( player : getpos ( ) )
local itemstack = ItemStack ( " x_marketplace:head " )
local meta = itemstack : get_meta ( )
local item_description = minetest.registered_items [ " x_marketplace:head " ] [ " description " ]
meta : set_string ( " owner " , player_name )
meta : set_string ( " value " , lost_value )
meta : set_string ( " description " , player_name .. " " .. item_description .. " \n value: " .. lost_value .. " BitGold " )
local obj = minetest.add_item ( pos , itemstack )
if obj then
obj : set_velocity ( {
x = math.random ( - 10 , 10 ) / 9 ,
y = 5 ,
z = math.random ( - 10 , 10 ) / 9 ,
} )
end
minetest.chat_send_player ( player_name , minetest.colorize ( x_marketplace.colors . yellow , " MARKET PLACE: When you died you lost " .. lost_value .. " BitGold " ) )
end
end )