forked from minetest-mods/global_exchange
		
	Compare commits
	
		
			4 Commits
		
	
	
		
			nalc-1.0
			...
			9c8f62320e
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
| 9c8f62320e | |||
| b22b72f5c2 | |||
| ce33c159fd | |||
| c1a527eeea | 
							
								
								
									
										132
									
								
								atm.lua
									
									
									
									
									
								
							
							
						
						
									
										132
									
								
								atm.lua
									
									
									
									
									
								
							| @@ -1,5 +1,6 @@ | ||||
| -- A telling machine. Call this file with the exchange argument. | ||||
| local exchange, formlib = ... | ||||
| local S = minetest.get_translator("global_exchange") | ||||
|  | ||||
| local atm_form = "global_exchange:atm_form" | ||||
| local atm_pos = {} | ||||
| @@ -11,34 +12,60 @@ local unique = (function(unique_num) | ||||
| 	end | ||||
| end)(0) | ||||
|  | ||||
| local coins_convert = { | ||||
| 	["minercantile:copper_coin"]=1, ["minercantile:silver_coin"]=9, ["minercantile:gold_coin"]=81, | ||||
| 	["maptools:copper_coin"]=1, ["maptools:silver_coin"]=9, ["maptools:gold_coin"]=81, | ||||
| 	["bitchange:mineninth"]=729, ["bitchange:minecoin"]=6561, ["bitchange:minecoinblock"]=59049 | ||||
| local coins = { | ||||
| 	[1] = "bitchange:minecoinblock", [2] = "bitchange:minecoin", [3] = "bitchange:mineninth", | ||||
| 	[4] = "maptools:gold_coin", [5] = "maptools:silver_coin", [6] = "maptools:copper_coin" | ||||
| } | ||||
|  | ||||
| local function deposit_fs(fs, p_name) | ||||
| 	local balance = exchange:get_balance(p_name) | ||||
| local coins_convert = { | ||||
| 	[coins[6]]=1, [coins[5]]=9, [coins[4]]=81, [coins[3]]=729, [coins[2]]=6561, [coins[1]]=59049, | ||||
| 	["minercantile:copper_coin"]=1, ["minercantile:silver_coin"]=9, ["minercantile:gold_coin"]=81 | ||||
| } | ||||
|  | ||||
| local function withdraw_fs(fs, p_name, amount) | ||||
| 	local spos = atm_pos[p_name].x..","..atm_pos[p_name].y..","..atm_pos[p_name].z | ||||
| 	local inv = minetest.get_inventory({ type = "node", pos={x=atm_pos[p_name].x, y=atm_pos[p_name].y, z=atm_pos[p_name].z} }) | ||||
|  | ||||
| 	fs:size(8,9) | ||||
| 	 | ||||
| 	if not balance then | ||||
| 		fs:label(0.5,0.5, "You don't have an account.") | ||||
| 	else | ||||
| 		fs:label(0.5,0.5, "Balance: " .. balance) | ||||
| 		fs:label(1,1,"Put your coins to credit your account") | ||||
| 		fs:list(3.5,2.5, 1,1, "nodemeta:"..spos, "main") | ||||
| 		fs:list(0,4, 8,4, "current_player", "main") | ||||
| 		--fs("list[nodemeta:"..spos..";main;3.5,2.5;1,1;]".. | ||||
| 		--		"list[current_player;main;0,4.85;8,1;]".. | ||||
| 		--		"list[current_player;main;0,6.08;8,3;8]" .. | ||||
| 		fs("listring[nodemeta:"..spos..";main]".. | ||||
| 				"listring[current_player;main]" | ||||
| 		) | ||||
| 	local msg = "" | ||||
| 	local w_amount = tonumber(amount) | ||||
| 	if w_amount and math.floor(w_amount) == w_amount and w_amount > 0 then | ||||
| 		local succ, err = exchange:give_credits(p_name, 0 - w_amount, S("Cash withdrawal: (-@1)", w_amount)) | ||||
| 		if succ then | ||||
| 			local index = 1 | ||||
| 			repeat | ||||
| 				local m = math.floor(w_amount / coins_convert[coins[index]]) | ||||
| 				if m > 0 then | ||||
| 					inv:add_item( "main", ItemStack({ name = coins[index], count = m }) ) | ||||
| 				end | ||||
| 				w_amount = w_amount - (coins_convert[coins[index]] * m) | ||||
| 				index = index + 1 | ||||
| 			until ( w_amount == 0) | ||||
| 		else | ||||
| 			msg = err | ||||
| 		end | ||||
| 	elseif w_amount then | ||||
| 		msg = S("Invalid number ! Must be an Integer > 0") | ||||
| 	end | ||||
|  | ||||
| 	fs:button(1,2, 2,1, "logout", "Log Out") | ||||
| 	local balance = exchange:get_balance(p_name) | ||||
| 	 | ||||
| 	fs:size(8,10) | ||||
|  | ||||
| 	if not balance then | ||||
| 		fs:label(0.5, 0.5, S("You don't have an account.")) | ||||
| 	else | ||||
| 		fs:label(3,8.9, S("Balance: @1", balance)) | ||||
| 		fs:field(0.75, 1.25, 3.25, 1, "w_amount", S("Desired amount:")) | ||||
| 		fs:button(4, 1, 3.25, 1, "withdraw", S("Get !")) | ||||
| 		fs:label(1, 2.25, S("Or deposit your coins to credit your account:")) | ||||
| 		fs:list(1,3,6,1, "nodemeta:"..spos, "main") | ||||
| 		fs:list(0,4.25, 8,4, "current_player", "main") | ||||
| 		fs("listring[current_player;main]".. | ||||
| 				"listring[nodemeta:"..spos..";main]" | ||||
| 		) | ||||
| 		fs:label(0,9.75, msg) | ||||
| 	end | ||||
| 	fs:button(0,8.75, 2,1, "logout", S("Log Out")) | ||||
| end | ||||
|  | ||||
| local function info_fs(fs, p_name) | ||||
| @@ -47,12 +74,12 @@ local function info_fs(fs, p_name) | ||||
| 	fs:size(4,3) | ||||
|  | ||||
| 	if balance then | ||||
| 		fs:label(0.5,0.5, "Balance: " .. balance) | ||||
| 		fs:label(0.5,0.5, S("Balance: @1", balance)) | ||||
| 	else | ||||
| 		fs:label(0.5,0.5, "You don't have an account.") | ||||
| 		fs:label(0.5,0.5, S("You don't have an account.")) | ||||
| 	end | ||||
|  | ||||
| 	fs:button(1,2, 2,1, "logout", "Log Out") | ||||
| 	fs:button(1,2, 2,1, "logout", S("Log Out")) | ||||
| end | ||||
|  | ||||
|  | ||||
| @@ -65,15 +92,15 @@ local function wire_fs(fs, p_name) | ||||
| 		-- To detect duplicate/stale form submission | ||||
| 		fs:field(-100, -100, 0,0, "trans_id", "", unique()) | ||||
|  | ||||
| 		fs:label(0.50,0.325, "Balance: " .. balance) | ||||
| 		fs:field(0.75,1.750, 3,1, "recipient", "Send to:", "") | ||||
| 		fs:field(0.75,3.000, 3,1, "amount", "Amount", "") | ||||
| 		fs:label(0.50,0.325, S("Balance: @1", balance)) | ||||
| 		fs:field(0.75,1.750, 3,1, "recipient", S("Send to:"), "") | ||||
| 		fs:field(0.75,3.000, 3,1, "amount", S("Amount"), "") | ||||
|  | ||||
| 		fs:button(0,4.25, 2,1, "logout", "Log Out") | ||||
| 		fs:button(2,4.25, 2,1, "send", "Send") | ||||
| 		fs:button(0,4.25, 2,1, "logout", S("Log Out")) | ||||
| 		fs:button(2,4.25, 2,1, "send", S("Send")) | ||||
| 	else | ||||
| 		fs:button(0,4, 2,1, "logout", "Back") | ||||
| 		fs:label(0.5,0.5, "You don't have an account.") | ||||
| 		fs:button(0,4, 2,1, "logout", S("Back")) | ||||
| 		fs:label(0.5,0.5, S("You don't have an account.")) | ||||
| 	end | ||||
| end | ||||
|  | ||||
| @@ -81,13 +108,13 @@ end | ||||
| local function send_fs(fs, p_name, receiver, amt_str) | ||||
| 	fs:size(10,3) | ||||
|  | ||||
| 	fs:button(4,2, 2,1, "wire", "Back") | ||||
| 	fs:button(4,2, 2,1, "wire", S("Back")) | ||||
|  | ||||
| 	local amt = tonumber(amt_str) | ||||
| 	local msg = nil | ||||
|  | ||||
| 	if not amt or amt <= 0 then | ||||
| 		msg = "Invalid transfer amount." | ||||
| 		msg = S("Invalid transfer amount.") | ||||
| 	else | ||||
| 		local succ, err = exchange:transfer_credits(p_name, receiver, amt) | ||||
|  | ||||
| @@ -106,7 +133,7 @@ end | ||||
| local function log_fs(fs, p_name) | ||||
| 	fs:size(14,8) | ||||
|  | ||||
| 	fs:label(0,0, "Transaction Log") | ||||
| 	fs:label(0,0, S("Transaction Log")) | ||||
|  | ||||
| 	fs:element("tablecolumns", "text", "text") | ||||
|  | ||||
| @@ -116,16 +143,16 @@ local function log_fs(fs, p_name) | ||||
| 	end | ||||
| 	fs("]") | ||||
|  | ||||
| 	fs:button(6,7.5, 2,1, "logout", "Log Out") | ||||
| 	fs:button(6,7.5, 2,1, "logout", S("Log Out")) | ||||
| end | ||||
|  | ||||
|  | ||||
| local function main_menu_fs(fs, p_name) | ||||
| 	fs:size(6,2) | ||||
| 	fs:button(0,0.125, 2,1, "deposit", "Cash Deposit") | ||||
| 	fs:button(2,0.125, 2,1, "info", "Account Info") | ||||
| 	fs:button(4,0.125, 2,1, "wire", "Wire Monies") | ||||
| 	fs:button(0.50,1.125, 5.0,1, "transaction_log", "Transaction Log") | ||||
| 	fs:size(8,2) | ||||
| 	fs:button(0,0.125, 4,1, "withdraw", S("Cash deposit and withdrawal")) | ||||
| 	fs:button(4,0.125, 2,1, "info", S("Account Info")) | ||||
| 	fs:button(6,0.125, 2,1, "wire", S("Wire Monies")) | ||||
| 	fs:button(0.50, 1.125, 7, 1, "transaction_log", S("Transaction Log")) | ||||
| end | ||||
|  | ||||
|  | ||||
| @@ -159,12 +186,12 @@ minetest.register_on_player_receive_fields(function(player, formname, fields) | ||||
| 		show_atm_form(info_fs, p_name) | ||||
| 	elseif fields.wire then | ||||
| 		show_atm_form(wire_fs, p_name) | ||||
| 	elseif fields.withdraw then | ||||
| 		show_atm_form(withdraw_fs, p_name, fields and fields.w_amount) | ||||
| 	elseif fields.send then | ||||
| 		show_atm_form(send_fs, p_name, fields.recipient, fields.amount) | ||||
| 	elseif fields.transaction_log then | ||||
| 		show_atm_form(log_fs, p_name) | ||||
| 	elseif fields.deposit then | ||||
| 		show_atm_form(deposit_fs, p_name) | ||||
| 	end | ||||
|  | ||||
| 	return true | ||||
| @@ -172,7 +199,7 @@ end) | ||||
|  | ||||
|  | ||||
| minetest.register_node("global_exchange:atm_bottom", { | ||||
| 	description = "ATM", | ||||
|    description = "ATM", | ||||
| 	inventory_image = "global_exchange_atm_icon.png", | ||||
| 	wield_image = "global_exchange_atm_hi_front.png", | ||||
| 	drawtype = "nodebox", | ||||
| @@ -242,6 +269,11 @@ minetest.register_node("global_exchange:atm_bottom", { | ||||
| 			return itemstack | ||||
| 		end | ||||
| 	end, | ||||
| 	can_dig = function(pos,player) | ||||
| 		local meta = minetest.get_meta(pos); | ||||
| 		local inv = meta:get_inventory() | ||||
| 		return inv:is_empty("main") | ||||
| 	end, | ||||
| 	on_destruct = function(pos) | ||||
| 		local pos2 = {x = pos.x, y = pos.y + 1, z = pos.z} | ||||
| 		local n2 = minetest.get_node(pos2) | ||||
| @@ -253,7 +285,7 @@ minetest.register_node("global_exchange:atm_bottom", { | ||||
| 		local meta = minetest.get_meta(pos) | ||||
| 		meta:set_string("infotext", "ATM") | ||||
| 		local inv = meta:get_inventory() | ||||
| 		inv:set_size("main", 1) | ||||
| 		inv:set_size("main", 6) | ||||
| 	end, | ||||
| 	allow_metadata_inventory_put = function(pos, listname, index, stack, player) | ||||
| 		local itname = stack:get_name() | ||||
| @@ -262,6 +294,9 @@ minetest.register_node("global_exchange:atm_bottom", { | ||||
| 		end | ||||
| 		return 0 | ||||
| 	end, | ||||
| 	allow_metadata_inventory_take = function(pos, listname, index, stack, player) | ||||
| 		return stack:get_count() | ||||
| 	end, | ||||
| 	on_metadata_inventory_put = function(pos, listname, index, stack, player) | ||||
| 		local itname = stack:get_name() | ||||
| 		if coins_convert[itname] ~= nil then | ||||
| @@ -270,17 +305,20 @@ minetest.register_node("global_exchange:atm_bottom", { | ||||
| 			local inv = meta:get_inventory() | ||||
| 			local nb = stack:get_count() | ||||
| 			local amount = coins_convert[itname] * nb | ||||
| 			local succ, msg = exchange:give_credits(p_name, amount, "Cash deposit (+"..amount..")") | ||||
| 			local succ, msg = exchange:give_credits(p_name, amount, S("Cash deposit (+@1)", amount)) | ||||
| 			if succ then | ||||
| 				inv:set_stack(listname, index, nil) | ||||
| 				minetest.log("action", p_name.." put "..nb.." "..stack:get_name() .. " to ATM at " .. minetest.pos_to_string(pos)) | ||||
| 				show_atm_form(deposit_fs, p_name) | ||||
| 				show_atm_form(withdraw_fs, p_name) | ||||
| 				--minetest.show_formspec(p_name, atm_form, deposit_fs(p_name)) | ||||
| 			else | ||||
| 				minetest.log("error", p_name.." want to put "..nb.." "..stack:get_name().." to ATM at ".. minetest.pos_to_string(pos).." but: "..msg) | ||||
| 			end | ||||
| 		end | ||||
| 	end, | ||||
| 	on_metadata_inventory_take = function(pos, listname, index, stack, player) | ||||
| 		minetest.log("action", player:get_player_name().." take "..stack:get_count().." "..stack:get_name().." from ATM at "..minetest.pos_to_string(pos)) | ||||
| 	end, | ||||
| 	on_rightclick = function(pos, _, clicker) | ||||
| 		local p_name = clicker:get_player_name() | ||||
| 		atm_pos[p_name] = pos | ||||
|   | ||||
							
								
								
									
										89
									
								
								exchange.lua
									
									
									
									
									
								
							
							
						
						
									
										89
									
								
								exchange.lua
									
									
									
									
									
								
							| @@ -2,6 +2,7 @@ | ||||
| local insecure_env = ... | ||||
| local sql = insecure_env.require("lsqlite3") | ||||
| local exports = {} | ||||
| local S = minetest.get_translator("global_exchange") | ||||
|  | ||||
| local order_book_cache = (function(cache) | ||||
| 	return function(ex_name) | ||||
| @@ -284,7 +285,7 @@ local function exec_stmt(db, stmt, names) | ||||
| 	stmt:reset() | ||||
|  | ||||
| 	if res == sqlite3.BUSY then | ||||
| 		return false, "Database Busy." | ||||
| 		return false, S("Database Busy.") | ||||
| 	elseif res ~= sqlite3.DONE then | ||||
| 		sql_error(db:errmsg()) | ||||
| 	else | ||||
| @@ -368,9 +369,9 @@ function ex_methods.log(self, message, recipient) | ||||
| 	if res == sqlite3.ERROR then | ||||
| 		sql_error(db:errmsg()) | ||||
| 	elseif res == sqlite3.MISUSE then | ||||
| 		error("Programmer error.") | ||||
| 		error(S("Programmer error.")) | ||||
| 	elseif res == sqlite3.BUSY then | ||||
| 		return false, "Failed to log message." | ||||
| 		return false, S("Failed to log message.") | ||||
| 	else | ||||
| 		return true | ||||
| 	end | ||||
| @@ -385,7 +386,7 @@ function ex_methods.new_account(self, p_name, amt) | ||||
| 	local exists = self:get_balance(p_name) | ||||
|  | ||||
| 	if exists then | ||||
| 		return false, "Account already exists." | ||||
| 		return false, S("Account already exists.") | ||||
| 	end | ||||
|  | ||||
| 	db:exec("BEGIN TRANSACTION;") | ||||
| @@ -401,11 +402,11 @@ function ex_methods.new_account(self, p_name, amt) | ||||
| 	local res = stmt:step() | ||||
|  | ||||
| 	if res == sqlite3.MISUSE then | ||||
| 		error("Programmer error.") | ||||
| 		error(S("Programmer error.")) | ||||
| 	elseif res == sqlite3.BUSY then | ||||
| 		stmt:reset() | ||||
| 		db:exec("ROLLBACK;") | ||||
| 		return false, "Database Busy." | ||||
| 		return false, S("Database Busy.") | ||||
| 	elseif res ~= sqlite3.DONE then | ||||
| 		sql_error(db:errmsg()) | ||||
| 	end | ||||
| @@ -444,7 +445,7 @@ function ex_methods.get_balance(self, p_name) | ||||
| 	if res == sqlite3.ERROR then | ||||
| 		sql_error(db:errmsg()) | ||||
| 	elseif res == sqlite3.MISUSE then | ||||
| 		error("Programmer error.") | ||||
| 		error(S("Programmer error.")) | ||||
| 	elseif res == sqlite3.ROW then | ||||
| 		local balance = stmt:get_value(0) | ||||
| 		stmt:reset() | ||||
| @@ -465,7 +466,7 @@ function ex_methods.set_balance(self, p_name, new_bal) | ||||
| 	local bal = self:get_balance(p_name) | ||||
|  | ||||
| 	if not bal then | ||||
| 		return false, p_name .. " does not have an account." | ||||
| 		return false, S("@1 does not have an account.", p_name) | ||||
| 	end | ||||
|  | ||||
| 	set_stmt:bind_names({ | ||||
| @@ -478,10 +479,10 @@ function ex_methods.set_balance(self, p_name, new_bal) | ||||
| 	if res == sqlite3.ERROR then | ||||
| 		sql_error(db:errmsg()) | ||||
| 	elseif res == sqlite3.MISUSE then | ||||
| 		error("Programmer error.") | ||||
| 		error(S("Programmer error.")) | ||||
| 	elseif res == sqlite3.BUSY then | ||||
| 		set_stmt:reset() | ||||
| 		return false, "Database busy" | ||||
| 		return false, S("Database busy.") | ||||
| 	else | ||||
| 		set_stmt:reset() | ||||
| 		return true | ||||
| @@ -499,11 +500,11 @@ function ex_methods.change_balance(self, p_name, delta) | ||||
| 	local bal = self:get_balance(p_name) | ||||
|  | ||||
| 	if not bal then | ||||
| 		return false, p_name .. " does not have an account." | ||||
| 		return false, S("@1 does not have an account.", p_name) | ||||
| 	end | ||||
|  | ||||
| 	if bal + delta < 0 then | ||||
| 		return false, p_name .. " does not have enough money." | ||||
| 		return false, S("@1 does not have enough money.", p_name) | ||||
| 	end | ||||
|  | ||||
| 	return self:set_balance(p_name, bal + delta) | ||||
| @@ -516,7 +517,7 @@ function ex_methods.transfer_credits(self, sender, receiver, amt) | ||||
| 	local db = self.db | ||||
|  | ||||
| 	if not is_integer(amt) then | ||||
| 		return false, "Non-integer credit amount" | ||||
| 		return false, S("Non-integer credit amount") | ||||
| 	end | ||||
|  | ||||
| 	db:exec("BEGIN TRANSACTION;") | ||||
| @@ -539,14 +540,14 @@ function ex_methods.transfer_credits(self, sender, receiver, amt) | ||||
|  | ||||
| 	if not succ_log1 then | ||||
| 		db:exec("ROLLBACK") | ||||
| 		return false, "Failed to log sender message" | ||||
| 		return false, S("Failed to log sender message") | ||||
| 	end | ||||
|  | ||||
| 	local succ_log2 = self:log("Received " .. amt .. " credits from " .. sender, receiver) | ||||
|  | ||||
| 	if not succ_log2 then | ||||
| 		db:exec("ROLLBACK") | ||||
| 		return false, "Failed to log receiver message" | ||||
| 		return false, S("Failed to log receiver message") | ||||
| 	end | ||||
|  | ||||
| 	db:exec("COMMIT;") | ||||
| @@ -669,17 +670,17 @@ end | ||||
| -- Adds a new order. Returns success, and an error string if failed. | ||||
| function ex_methods.add_order(self, p_name, ex_name, order_type, item_name, wear, amount, rate) | ||||
| 	if not is_integer(amount) then | ||||
| 		return false, "Noninteger quantity" | ||||
| 		return false, S("Noninteger quantity") | ||||
| 	elseif amount <= 0 then | ||||
| 		return false, "Nonpositive quantity" | ||||
| 		return false, S("Nonpositive quantity") | ||||
| 	elseif not is_integer(rate) then | ||||
| 		return false, "Noninteger rate" | ||||
| 		return false, S("Noninteger rate") | ||||
| 	elseif rate <= 0 then | ||||
| 		return false, "Nonpositive rate" | ||||
| 		return false, S("Nonpositive rate") | ||||
| 	elseif not is_integer(wear) then | ||||
| 		return false, "Noninteger wear" | ||||
| 		return false, S("Noninteger wear") | ||||
| 	elseif wear < 0 or wear > 65535 then | ||||
| 		return false, "Invalid wear" | ||||
| 		return false, S("Invalid wear") | ||||
| 	end | ||||
|  | ||||
| 	order_book_cache(ex_name)[item_name] = nil | ||||
| @@ -702,7 +703,7 @@ function ex_methods.add_order(self, p_name, ex_name, order_type, item_name, wear | ||||
|  | ||||
| 	if res == sqlite3.BUSY then | ||||
| 		stmt:reset() | ||||
| 		return false, "Database Busy" | ||||
| 		return false, S("Database Busy.") | ||||
| 	elseif res ~= sqlite3.DONE then | ||||
| 		sql_error(db:errmsg()) | ||||
| 	end | ||||
| @@ -730,13 +731,13 @@ function ex_methods.cancel_order(self, p_name, id) | ||||
| 	if res == sqlite3.ERROR then | ||||
| 		sql_error(db:errmsg()) | ||||
| 	elseif res == sqlite3.MISUSE then | ||||
| 		error("Programmer error.") | ||||
| 		error(S("Programmer error.")) | ||||
| 	elseif res == sqlite3.ROW then | ||||
| 		order = get_stmt:get_named_values() | ||||
| 		get_stmt:reset() | ||||
| 	else | ||||
| 		db:exec("ROLLBACK;") | ||||
| 		return false, "No such order." | ||||
| 		return false, S("No such order.") | ||||
| 	end | ||||
|  | ||||
| 	order_book_cache(order.Exchange)[order.Item] = nil | ||||
| @@ -783,7 +784,7 @@ function ex_methods.put_in_inbox(self, p_name, item_name, wear, amount) | ||||
| 	if res == sqlite3.BUSY then | ||||
| 		search_stmt:reset() | ||||
| 		db:exec("ROLLBACK;") | ||||
| 		return false, "Database Busy." | ||||
| 		return false, S("Database Busy.") | ||||
| 	elseif res == sqlite3.ROW then | ||||
| 		row = search_stmt:get_named_values() | ||||
| 	elseif res ~= sqlite3.DONE then | ||||
| @@ -817,7 +818,7 @@ function ex_methods.put_in_inbox(self, p_name, item_name, wear, amount) | ||||
| 	if res == sqlite3.BUSY then | ||||
| 		stmt:reset() | ||||
| 		db:exec("ROLLBACK;") | ||||
| 		return false, "Database Busy." | ||||
| 		return false, S("Database Busy.") | ||||
| 	elseif res ~= sqlite3.DONE then | ||||
| 		sql_error(db:errmsg()) | ||||
| 	end | ||||
| @@ -835,17 +836,17 @@ end | ||||
| -- bought. If failed, returns an error message | ||||
| function ex_methods.buy(self, p_name, ex_name, item_name, wear, amount, rate) | ||||
| 	if not is_integer(amount) then | ||||
| 		return false, "Noninteger quantity" | ||||
| 		return false, S("Noninteger quantity") | ||||
| 	elseif amount <= 0 then | ||||
| 		return false, "Nonpositive quantity" | ||||
| 		return false, S("Nonpositive quantity") | ||||
| 	elseif not is_integer(rate) then | ||||
| 		return false, "Noninteger rate" | ||||
| 		return false, S("Noninteger rate") | ||||
| 	elseif rate <= 0 then | ||||
| 		return false, "Nonpositive rate" | ||||
| 		return false, S("Nonpositive rate") | ||||
| 	elseif not is_integer(wear) then | ||||
| 		return false, "Noninteger wear" | ||||
| 		return false, S("Noninteger wear") | ||||
| 	elseif wear < 0 or wear > 65535 then | ||||
| 		return false, "Invalid wear" | ||||
| 		return false, S("Invalid wear") | ||||
| 	end | ||||
|  | ||||
| 	local db = self.db | ||||
| @@ -856,7 +857,7 @@ function ex_methods.buy(self, p_name, ex_name, item_name, wear, amount, rate) | ||||
| 	 | ||||
| 	if not balance then | ||||
| 		db:exec("ROLLBACK;") | ||||
| 		return false, p_name .. " does not have an account." | ||||
| 		return false, S("@1 does not have an account.", p_name) | ||||
| 	end | ||||
|  | ||||
| 	local bought = {} | ||||
| @@ -909,7 +910,7 @@ function ex_methods.buy(self, p_name, ex_name, item_name, wear, amount, rate) | ||||
| 			red_del_stmt:reset() | ||||
| 			search_stmt:reset() | ||||
| 			db:exec("ROLLBACK;") | ||||
| 			return false, "Database Busy." | ||||
| 			return false, S("Database Busy.") | ||||
| 		elseif red_del_res ~= sqlite3.DONE then | ||||
| 			red_del_stmt:reset() | ||||
| 			search_stmt:reset() | ||||
| @@ -1018,17 +1019,17 @@ end | ||||
| -- remaining desired amount. Returns success. If failed, returns an error message. | ||||
| function ex_methods.sell(self, p_name, ex_name, item_name, wear, amount, rate) | ||||
| 	if not is_integer(amount) then | ||||
| 		return false, "Noninteger quantity" | ||||
| 		return false, S("Noninteger quantity") | ||||
| 	elseif amount <= 0 then | ||||
| 		return false, "Nonpositive quantity" | ||||
| 		return false, S("Nonpositive quantity") | ||||
| 	elseif not is_integer(rate) then | ||||
| 		return false, "Noninteger rate" | ||||
| 		return false, S("Noninteger rate") | ||||
| 	elseif rate <= 0 then | ||||
| 		return false, "Nonpositive rate" | ||||
| 		return false, S("Nonpositive rate") | ||||
| 	elseif not is_integer(wear) then | ||||
| 		return false, "Noninteger wear" | ||||
| 		return false, S("Noninteger wear") | ||||
| 	elseif wear < 0 or wear > 65535 then | ||||
| 		return false, "Invalid wear" | ||||
| 		return false, S("Invalid wear") | ||||
| 	end | ||||
|  | ||||
| 	local db = self.db | ||||
| @@ -1081,7 +1082,7 @@ function ex_methods.sell(self, p_name, ex_name, item_name, wear, amount, rate) | ||||
| 		if red_del_res == sqlite3.BUSY then | ||||
| 			search_stmt:reset() | ||||
| 			db:exec("ROLLBACK;") | ||||
| 			return false, "Database Busy." | ||||
| 			return false, S("Database Busy.") | ||||
| 		elseif red_del_res ~= sqlite3.DONE then | ||||
| 			search_stmt:reset() | ||||
| 			sql_error(db:errmsg()) | ||||
| @@ -1214,10 +1215,10 @@ function ex_methods.take_inbox(self, id, amount) | ||||
|  | ||||
| 	if res == sqlite3.BUSY then | ||||
| 		get_stmt:reset() | ||||
| 		return false, "Database Busy." | ||||
| 		return false, S("Database Busy.") | ||||
| 	elseif res == sqlite3.DONE then | ||||
| 		get_stmt:reset() | ||||
| 		return false, "Order does not exist." | ||||
| 		return false, S("Order does not exist.") | ||||
| 	elseif res ~= sqlite3.ROW then | ||||
| 		sql_error(db:errmsg()) | ||||
| 	end | ||||
| @@ -1246,7 +1247,7 @@ function ex_methods.take_inbox(self, id, amount) | ||||
| 	if red_del_res == sqlite3.BUSY then | ||||
| 		red_del_stmt:reset() | ||||
| 		db:exec("ROLLBACK;") | ||||
| 		return false, "Database Busy." | ||||
| 		return false, S("Database Busy.") | ||||
| 	elseif red_del_res ~= sqlite3.DONE then | ||||
| 		sql_error(db:errmsg()) | ||||
| 	end | ||||
|   | ||||
| @@ -5,13 +5,19 @@ local summary_interval = 600 | ||||
|  | ||||
| local global_inv = nil | ||||
|  | ||||
| local S = minetest.get_translator("global_exchange") | ||||
|  | ||||
| -- NALC split() function | ||||
| local function split(str, sep) | ||||
| 	if not str then return nil end | ||||
| 	if not str then return "Item doesn't exist" end | ||||
| 	local result = {} | ||||
| 	local regex = ("([^%s]+)"):format(sep) | ||||
| 	for each in str:gmatch(regex) do | ||||
| 		table.insert(result, each) | ||||
| 		local sub = nil | ||||
| 		if #each > 25 then | ||||
| 			sub = string.sub(each, 1, 25).."..." | ||||
| 		end | ||||
| 		table.insert(result, sub or each) | ||||
| 	end | ||||
| 	return result | ||||
| end | ||||
| @@ -36,18 +42,18 @@ local function mk_summary_fs() | ||||
| 	fs:table(0,0, 11.75,9, "summary_table", function(add_row) | ||||
| 		add_row("Item", | ||||
| 		        "Description", | ||||
| 				"Wear", | ||||
| 		        "Buy Vol", | ||||
| 		        "Buy Max", | ||||
| 		        "Sell Vol", | ||||
| 		        "Sell Min") | ||||
| 				  S("Wear"), | ||||
| 		        S("Buy Vol"), | ||||
| 		        S("Buy Max"), | ||||
| 		        S("Sell Vol"), | ||||
| 		        S("Sell Min")) | ||||
|  | ||||
| 		local all_items = minetest.registered_items | ||||
| 		for i, row in ipairs(exchange:market_summary()) do | ||||
| 			local def = all_items[row.Item] or {} | ||||
| 			add_row(row.Item, | ||||
| 			        split(def.description, "\n")[1] or "Unknown Item", | ||||
| 					wear_string(row.Wear), | ||||
| 			        split(def.description, "\n")[1] or S("Unknown Item"), | ||||
| 					  wear_string(row.Wear), | ||||
| 			        row.Buy_Volume  or 0, | ||||
| 			        row.Buy_Max     or "N/A", | ||||
| 			        row.Sell_Volume or 0, | ||||
| @@ -72,10 +78,10 @@ end) | ||||
|  | ||||
|  | ||||
| local wear_levels = { | ||||
| 	[1] = { index = 1, text = "New (-0%)",    wear = math.floor(0.00*65535) }, | ||||
| 	[2] = { index = 2, text = "Good (-10%)",  wear = math.floor(0.10*65535) }, | ||||
| 	[3] = { index = 3, text = "Worn (-50%)",  wear = math.floor(0.50*65535) }, | ||||
| 	[4] = { index = 4, text = "Junk (-100%)", wear = math.floor(1.00*65535) }, | ||||
| 	[1] = { index = 1, text = S("New (-0%)"),    wear = math.floor(0.00*65535) }, | ||||
| 	[2] = { index = 2, text = S("Good (-10%)"),  wear = math.floor(0.10*65535) }, | ||||
| 	[3] = { index = 3, text = S("Worn (-50%)"),  wear = math.floor(0.50*65535) }, | ||||
| 	[4] = { index = 4, text = S("Junk (-100%)"), wear = math.floor(1.00*65535) }, | ||||
| } | ||||
|  | ||||
| -- Allow lookup by text label as well as index | ||||
| @@ -95,9 +101,12 @@ minetest.register_on_joinplayer(function(player) | ||||
| 		buy_wear       = wear_levels[1].text, | ||||
| 		buy_price      = "", | ||||
| 		buy_amount     = "1", | ||||
| 		buy_filter     = "", | ||||
| 		sell_price     = "", | ||||
| 		buy_page       = 1, | ||||
| 		buy_pagemax    = 0, | ||||
| 		selected_index = 0, | ||||
| 		filtered_list  = nil, | ||||
| 	} | ||||
| end) | ||||
|  | ||||
| @@ -126,20 +135,34 @@ minetest.after(0, function() | ||||
| 	pagemax = math.max(math.ceil(#selectable_list / pageitems), 1) | ||||
| end) | ||||
|  | ||||
| local function filter_list(filter) | ||||
| 	local filtered_list = {} | ||||
| 	if not filter or filter == "" then return nil, pagemax end | ||||
| 	 | ||||
| 	for index, name in ipairs(selectable_list) do | ||||
| 		local match = string.match(name, filter) or nil | ||||
| 		if match then | ||||
| 			filtered_list[#filtered_list+1] = name | ||||
| 		end | ||||
| 	end | ||||
|  | ||||
| 	return filtered_list, math.max(math.ceil(#filtered_list / pageitems), 1) | ||||
| end | ||||
|  | ||||
| local main_form = "global_exchange:exchange_main" | ||||
|  | ||||
| local function table_from_results(fs, results, name, x, y, w, h, selected) | ||||
| 	fs:tablecolumns("text", "text", "text", "text", "text", "text", "text") | ||||
| 	fs:table(x,y, w,h, name, function(add_row) | ||||
| 		add_row("Poster", "Type", "Item", | ||||
| 					add_row(S("Poster"), "Type", "Item", | ||||
| 		        "Description", | ||||
| 				"Wear", "Amount", "Rate") | ||||
| 				  S("Wear"), S("Qty"), S("Rate")) | ||||
|  | ||||
| 		local all_items = minetest.registered_items | ||||
| 		for i, row in ipairs(results) do | ||||
| 			local def = all_items[row.Item] or {} | ||||
| 			add_row(row.Poster, row.Type, row.Item, | ||||
| 			        split(def.description, "\n")[1] or "Unknown Item", | ||||
| 			        split(def.description, "\n")[1] or S("Unknown Item"), | ||||
| 					wear_string(row.Wear), row.Amount, row.Rate) | ||||
| 		end | ||||
| 	end, math.max(0, tonumber(selected) or 0) + 1) | ||||
| @@ -154,7 +177,7 @@ local function mk_main_order_book_fs(fs, p_name, x, y, w, h, item_name) | ||||
|  | ||||
| 	fs:tablecolumns("text", "text", "text", "text") | ||||
| 	fs:table(x,y, w,h, "order_book", function(add_row) | ||||
| 		add_row("Type", "Rate", "Wear", "Amount") | ||||
| 		add_row("Type", S("Rate"), S("Wear"), S("Qty")) | ||||
| 		for _,row in ipairs(order_book) do | ||||
| 			add_row(row.Type, row.Rate, wear_string(row.Wear), row.Amount) | ||||
| 		end | ||||
| @@ -166,7 +189,7 @@ local function mk_main_buy_fs(fs, p_name, state) | ||||
|  | ||||
| 	fs:item_image_button(9,0, 1,1, "buy_item", state.buy_item) | ||||
|  | ||||
| 	fs:field(10.25,0.40, 2,1, "buy_amount", "Quantity", state.buy_amount, false) | ||||
| 	fs:field(10.25,0.40, 2,1, "buy_amount", S("Quantity"), state.buy_amount, false) | ||||
|  | ||||
| 	local wear = wear_levels[state.buy_wear] or wear_levels[1] | ||||
| 	fs:dropdown(9,1, 3, "buy_wear", function(add_item) | ||||
| @@ -175,22 +198,26 @@ local function mk_main_buy_fs(fs, p_name, state) | ||||
| 		end | ||||
| 	end, wear.index) | ||||
|  | ||||
| 	fs:field(9.35,2.40, 2.9,1, "buy_price", "Bid (ea.)", state.buy_price, false) | ||||
| 	fs:field(9.35,2.40, 2.9,1, "buy_price", S("Bid (ea.)"), state.buy_price, false) | ||||
|  | ||||
| 	fs:button(9,3, 3,1, "buy", "Place Bid") | ||||
| 	fs:button(9,3, 3,1, "buy", S("Place Bid")) | ||||
|  | ||||
| 	fs:container(0,4, function() | ||||
| 		fs:button( 0,0.25, 1,1, "buy_left",  "<<") | ||||
| 		fs:button( 5,0.25, 2,1, "position",  state.buy_page .. "/" .. pagemax) | ||||
| 		fs:button(11,0.25, 1,1, "buy_right", ">>") | ||||
| 		fs:button( 1,0.25, 2,1, "position",  state.buy_page .. "/" .. state.buy_pagemax) | ||||
| 		fs:button(3,0.25, 1,1, "buy_right", ">>") | ||||
| 		 | ||||
| 		fs:field(5.28,0.55, 3,1, "buy_filter", S("Filter"), state.buy_filter, false) | ||||
| 		fs:button(8, 0.25, 2,1, "filter", S("Search")) | ||||
| 		fs:button(10, 0.25, 2,1, "reset_filter", S("Reset")) | ||||
|  | ||||
| 		local firstitem = ((state.buy_page - 1) * pageitems) | ||||
| 		local item_list = state.filtered_list or selectable_list | ||||
| 		for y=0,(pageheight-1) do | ||||
| 			for x=0,(pagewidth-1) do | ||||
| 				local index = firstitem + (pagewidth * y) + x + 1 | ||||
| 				if selectable_list[index] then | ||||
| 					fs:item_image_button(x,1.25+y, 1,1, "select_" .. index, | ||||
| 						selectable_list[index]) | ||||
| 				if item_list[index] then | ||||
| 					fs:item_image_button(x,1.25+y, 1,1, "select_" .. index, item_list[index]) | ||||
| 				end | ||||
| 			end | ||||
| 		end | ||||
| @@ -206,9 +233,9 @@ local function mk_main_sell_fs(fs, p_name, state) | ||||
|  | ||||
| 	fs:list(9,0, 1,1, "detached:global_exchange", "p_" .. p_name) | ||||
|  | ||||
| 	fs:field(9.35,2.40, 2.9,1, "sell_price", "Ask (ea.)", state.sell_price, false) | ||||
| 	fs:field(9.35,2.40, 2.9,1, "sell_price", S("Ask (ea.)"), state.sell_price, false) | ||||
|  | ||||
| 	fs:button(9,3, 3,1, "sell", "Sell") | ||||
| 	fs:button(9,3, 3,1, "sell", S("Sell")) | ||||
|  | ||||
| 	fs:box(1.9375,5.1875, 7.96875,4.03, "#00000020") | ||||
|  | ||||
| @@ -223,14 +250,14 @@ local function mk_main_own_orders_fs(fs, p_name, state) | ||||
| 	state.selected_index = math.min(state.selected_index or 0, #state.own_results) | ||||
|  | ||||
| 	table_from_results(fs, state.own_results, "result_table", 0, 0, 11.75, 8.5, state.selected_index) | ||||
| 	fs:button(4.5,8.5, 3,1, "cancel", "Cancel Order") | ||||
| 	fs:button(4.5,8.5, 3,1, "cancel", S("Cancel Order")) | ||||
| end | ||||
|  | ||||
| local main_tabs = { | ||||
| 	[1] = { text = "Market",    mk_fs = mk_main_market_fs     }, | ||||
| 	[2] = { text = "Buy",       mk_fs = mk_main_buy_fs        }, | ||||
| 	[3] = { text = "Sell",      mk_fs = mk_main_sell_fs       }, | ||||
| 	[4] = { text = "My Orders", mk_fs = mk_main_own_orders_fs }, | ||||
| 	[1] = { text = S("Market"),    mk_fs = mk_main_market_fs     }, | ||||
| 	[2] = { text = S("Buy"),       mk_fs = mk_main_buy_fs        }, | ||||
| 	[3] = { text = S("Sell"),      mk_fs = mk_main_sell_fs       }, | ||||
| 	[4] = { text = S("My Orders"), mk_fs = mk_main_own_orders_fs }, | ||||
| } | ||||
|  | ||||
| local function mk_main_fs(fs, p_name, err_str, success) | ||||
| @@ -279,23 +306,23 @@ local function post_buy(player, ex_name, item_name, wear_str, amount_str, rate_s | ||||
| 	local p_name = player:get_player_name() | ||||
|  | ||||
| 	if (item_name or "") == "" then | ||||
| 		return false, "You must input an item" | ||||
| 		return false, S("You must input an item") | ||||
| 	elseif not minetest.registered_items[item_name] then | ||||
| 		return false, "That item does not exist." | ||||
| 		return false, S("That item does not exist.") | ||||
| 	end | ||||
|  | ||||
| 	local wear_level = wear_levels[wear_str] | ||||
| 	if not wear_level then | ||||
| 		return false, "Invalid wear." | ||||
| 		return false, S("Invalid wear.") | ||||
| 	end | ||||
|  | ||||
| 	local amount = tonumber(amount_str) | ||||
| 	local rate   = tonumber(rate_str) | ||||
|  | ||||
| 	if not amount or not is_integer(amount) or amount < 1 then | ||||
| 		return false, "Invalid amount." | ||||
| 		return false, S("Invalid amount.") | ||||
| 	elseif not rate or not is_integer(rate) or rate < 1 then | ||||
| 		return false, "Invalid rate." | ||||
| 		return false, S("Invalid rate.") | ||||
| 	end | ||||
|  | ||||
| 	local p_inv = player:get_inventory() | ||||
| @@ -331,9 +358,9 @@ local function post_sell(player, ex_name, rate_str) | ||||
| 	local stack  = global_inv:get_stack("p_" .. p_name, 1) | ||||
|  | ||||
| 	if not stack or stack:is_empty() then | ||||
| 		return false, "You must input an item" | ||||
| 		return false, S("You must input an item") | ||||
| 	elseif not minetest.registered_items[stack:get_name()] then | ||||
| 		return false, "That item does not exist." | ||||
| 		return false, S("That item does not exist.") | ||||
| 	end | ||||
|  | ||||
| 	if stack.get_meta then | ||||
| @@ -341,16 +368,16 @@ local function post_sell(player, ex_name, rate_str) | ||||
| 		local def_meta = ItemStack(stack:get_name()):get_meta() | ||||
|  | ||||
| 		if not stack:get_meta():equals(def_meta) then | ||||
| 			return false, "Cannot sell an item with metadata." | ||||
| 			return false, S("Cannot sell an item with metadata.") | ||||
| 		end | ||||
| 	elseif (stack:get_metadata() or "") ~= "" then | ||||
| 		return false, "Cannot sell an item with metadata." | ||||
| 		return false, S("Cannot sell an item with metadata.") | ||||
| 	end | ||||
|  | ||||
| 	local rate = tonumber(rate_str) | ||||
|  | ||||
| 	if not rate or not is_integer(rate) or rate < 1 then | ||||
| 		return false, "Invalid rate." | ||||
| 		return false, S("Invalid rate.") | ||||
| 	end | ||||
|  | ||||
| 	local item_name = stack:get_name() | ||||
| @@ -380,6 +407,7 @@ local function handle_main(player, fields) | ||||
| 		"buy_wear", | ||||
| 		"buy_amount", | ||||
| 		"buy_price", | ||||
| 		"buy_filter", | ||||
| 		"sell_price" | ||||
| 	} | ||||
| 	for _,k in ipairs(copy_fields) do | ||||
| @@ -388,25 +416,30 @@ local function handle_main(player, fields) | ||||
| 		end | ||||
| 	end | ||||
|  | ||||
| 	if state.buy_pagemax == 0 then | ||||
| 		state.buy_pagemax = pagemax | ||||
| 	end | ||||
|  | ||||
| 	if fields.tab then | ||||
| 		state.tab = tonumber(fields.tab) or 1 | ||||
| 		show_main(p_name) | ||||
| 	end | ||||
|  | ||||
| 	if fields.buy_left then | ||||
| 		state.buy_page = (((state.buy_page or 1) + ((2*pagemax-1) - 1)) % pagemax) + 1 | ||||
| 		state.buy_page = (((state.buy_page or 1) + ((2*state.buy_pagemax-1) - 1)) % state.buy_pagemax) + 1 | ||||
| 		show_main(p_name) | ||||
| 	end | ||||
|  | ||||
| 	if fields.buy_right then | ||||
| 		state.buy_page = (((state.buy_page or 1) + ((2*pagemax-1) + 1)) % pagemax) + 1 | ||||
| 		state.buy_page = (((state.buy_page or 1) + ((2*state.buy_pagemax-1) + 1)) % state.buy_pagemax) + 1 | ||||
| 		show_main(p_name) | ||||
| 	end | ||||
|  | ||||
| 	local item_list = state.filtered_list or selectable_list | ||||
| 	for name in pairs(fields) do | ||||
| 		local index = tonumber(string.match(name, "select_([0-9]+)")) | ||||
| 		if index and index >= 1 and index < #selectable_list then | ||||
| 			state.buy_item = selectable_list[index] | ||||
| 		if index and index >= 1 and index <= #item_list then | ||||
| 			state.buy_item = item_list[index] | ||||
| 			show_main(p_name) | ||||
| 		end | ||||
| 	end | ||||
| @@ -425,6 +458,19 @@ local function handle_main(player, fields) | ||||
| 		end | ||||
| 	end | ||||
|  | ||||
| 	if fields.filter then | ||||
| 		state.filtered_list, state.buy_pagemax = filter_list(state.buy_filter) | ||||
| 		state.buy_page = 1 | ||||
| 		show_main(p_name) | ||||
| 	end | ||||
|  | ||||
| 	if fields.reset_filter then | ||||
| 		state.buy_filter = "" | ||||
| 		state.filtered_list, state.buy_pagemax = filter_list(nil) | ||||
| 		state.buy_page = 1 | ||||
| 		show_main(p_name) | ||||
| 	end | ||||
| 	 | ||||
| 	if fields.sell then | ||||
| 		local succ, err = post_sell(player, "", fields.sell_price) | ||||
| 		if succ then | ||||
|   | ||||
							
								
								
									
										80
									
								
								locale/global_exchange.fr.tr
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										80
									
								
								locale/global_exchange.fr.tr
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,80 @@ | ||||
| # textdomain:global_exchange | ||||
|  | ||||
| ### exchange.lua ### | ||||
| Database Busy.=BDD occupée. | ||||
| Programmer error.=Erreur du programmeur. | ||||
| Failed to log message.=Echec journalisation message. | ||||
| Account already exists.=Compte déjà existant. | ||||
| @1 does not have an account.=@1 n'a pas de compte. | ||||
| Non-integer credit delta=Delta de crédit non entier | ||||
| @1 does not have enough money.=@1 n'a pas assez d'argent. | ||||
| Non-integer credit amount=Montant de crédit non entier | ||||
| Failed to log sender message=Echec journalisation message de l'émetteur | ||||
| Failed to log receiver message=Echec journalisation message du récepteur | ||||
| Noninteger quantity=Quantité non entière | ||||
| Nonpositive quantity=Quantité non positive | ||||
| Noninteger rate=Taux non entier | ||||
| Nonpositive rate=Taux non positif | ||||
| Noninteger wear=Usure non entière | ||||
| Invalid wear=Usure invalide | ||||
| No such order.=Pas un tel ordre. | ||||
| Order does not exist.=L'ordre n'existe pas. | ||||
|  | ||||
| ### init.lua ### | ||||
| set a player's trading balance=définir le solde commercial d'un joueur | ||||
| Invalid parameters (see /help setbalance)=Paramètres invalides (voir /help setbalance) | ||||
|  | ||||
| ### atm.lua ### | ||||
| Cash withdrawal: (-@1)=Retrait d'espèces : (-@1) | ||||
| Invalid number ! Must be an Integer > 0=Nombre invalide ! Doit être un Entier > 0 | ||||
| You don't have an account.=Vous n'avez pas de compte. | ||||
| Balance: @1=Balance : @1 | ||||
| Desired amount:=Montant désiré : | ||||
| Get !=Obtenir ! | ||||
| Or deposit your coins to credit your account:=Ou deposez vos pièces pour créditer votre compte : | ||||
| Log Out=Sortir | ||||
| Balance: @1=Balance : @1 | ||||
| Send to:=Envoyer à : | ||||
| Amount=Montant | ||||
| Send=Envoie | ||||
| Back=Retour | ||||
| Invalid transfer amount.=Montant de transfert invalide. | ||||
| Cash deposit and withdrawal=Dépot et retrait d'espèces | ||||
| Account Info=Infos du compte | ||||
| Wire Monies=Virement bancaire | ||||
| Transaction Log=Journaux transactions | ||||
| ATM=Distributeur Automatique d'argent | ||||
| Cash deposit (+@1)=Dépot d'espèces (+@1) | ||||
|  | ||||
| ### exchange_machine.lua ### | ||||
| Wear=Usure | ||||
| Buy Vol=Qté achat | ||||
| Buy Max=Achat Max | ||||
| Sell Vol=Qté vente | ||||
| Sell Min=Vente Min | ||||
| Unknown Item=Item inconnue | ||||
| New (-0%)=Neuf (-0%) | ||||
| Good (-10%)=Bon (-10%) | ||||
| Worn (-50%)=Usé (-50%) | ||||
| Junk (-100%)=Indésirable (-100%) | ||||
| Poster=Émetteur | ||||
| Rate=Taux | ||||
| Quantity=Quantité | ||||
| Bid (ea.)=Offre | ||||
| Place Bid=Faire Offre | ||||
| Ask (ea.)=Demande | ||||
| Sell=Vendre | ||||
| Cancel Order=Annuler Ordre | ||||
| Market=Marché | ||||
| Buy=Acheter | ||||
| My Orders=Mes Ordres | ||||
| You must input an item=Vous devez saisir un élément | ||||
| That item does not exist.=Cet élément n'existe pas. | ||||
| Invalid wear.=Usure invalide. | ||||
| Invalid amount.=Montant invalide. | ||||
| Invalid rate.=Taux invalide. | ||||
| Cannot sell an item with metadata.=Ne peut vendre un item avec des métadonnées. | ||||
| Qty=Qté | ||||
| Filter=Filtre | ||||
| Search=Chercher | ||||
| Reset=Reset | ||||
		Reference in New Issue
	
	Block a user