131 lines
4.4 KiB
Lua
131 lines
4.4 KiB
Lua
--- Server Shops Transaction Logic
|
|
--
|
|
-- @topic transaction.lua
|
|
|
|
local ss = server_shop
|
|
local S = core.get_translator(ss.modname)
|
|
|
|
local transaction = {}
|
|
|
|
function transaction.give_product(player, product)
|
|
if not player or not product then return end
|
|
local pinv = player:get_inventory()
|
|
if not pinv:room_for_item("main", product) then
|
|
core.chat_send_player(player:get_player_name(), S("WARNUNG: @1 @2 wurde auf den Boden fallen gelassen.", product:get_count(), product:get_description()))
|
|
core.item_drop(product, player, player:get_pos())
|
|
else
|
|
pinv:add_item("main", product)
|
|
end
|
|
end
|
|
|
|
function transaction.calculate_refund(total)
|
|
local currencies = ss.get_currencies()
|
|
local keys = {}; for k in pairs(currencies) do table.insert(keys, k) end
|
|
table.sort(keys, function(kL, kR) return currencies[kL] > currencies[kR] end)
|
|
local refund = {}; local remain = total
|
|
for _, k in ipairs(keys) do
|
|
local v = currencies[k]
|
|
if v > 0 then
|
|
local count = math.floor(remain / v)
|
|
if count > 0 then
|
|
local stack = ItemStack(k); stack:set_count(count); table.insert(refund, stack)
|
|
remain = remain - (count * v)
|
|
end
|
|
end
|
|
end
|
|
return refund, remain
|
|
end
|
|
|
|
function transaction.calculate_currency_value(stack)
|
|
local value = 0
|
|
for c, v in pairs(ss.get_currencies()) do
|
|
if stack:get_name() == c then
|
|
return stack:get_count() * v
|
|
end
|
|
end
|
|
return 0
|
|
end
|
|
|
|
function transaction.execute_purchase(pos, player, slot_index)
|
|
local pmeta = player:get_meta()
|
|
local player_inv = player:get_inventory()
|
|
local shop = ss.get_shop(pos)
|
|
|
|
if not shop then return end
|
|
|
|
local quantity = 1
|
|
|
|
-- KORREKTUR: Die fehlerhafte `slot_index - 1` Logik wurde entfernt.
|
|
-- Wir verwenden `slot_index` direkt, so wie es in der funktionierenden Version war.
|
|
local item_to_buy = shop.inv:get_stack("main", slot_index)
|
|
local price_per_item = shop.prices[slot_index]
|
|
|
|
if item_to_buy:is_empty() or not price_per_item or price_per_item <= 0 then
|
|
core.chat_send_player(player:get_player_name(), S("Dieser Artikel ist nicht verfügbar."))
|
|
return
|
|
end
|
|
|
|
if item_to_buy:get_count() < quantity then
|
|
core.chat_send_player(player:get_player_name(), S("Nicht genügend Artikel auf Lager."))
|
|
return
|
|
end
|
|
|
|
local purchase_stack = ItemStack(item_to_buy:get_name())
|
|
purchase_stack:set_count(quantity)
|
|
if not player_inv:room_for_item("main", purchase_stack) then
|
|
core.chat_send_player(player:get_player_name(), S("Nicht genügend Platz im Inventar."))
|
|
return
|
|
end
|
|
|
|
local total_cost_cents = price_per_item * quantity
|
|
local player_name = player:get_player_name()
|
|
local payment_method = pmeta:get_string(ss.modname..":payment_method")
|
|
|
|
if payment_method == "bank_accounts:debit_card" or payment_method == "bank_accounts:credit_card" then
|
|
local account_balance
|
|
if payment_method == "bank_accounts:debit_card" then
|
|
account_balance = bank_accounts.get_balance(player_name)
|
|
else -- credit_card
|
|
account_balance = bank_accounts.get_credit(player_name)
|
|
end
|
|
|
|
local total_cost_float = total_cost_cents / 100
|
|
|
|
if account_balance < total_cost_float then
|
|
core.chat_send_player(player_name, S("Dein Konto ist nicht ausreichend gedeckt."))
|
|
return
|
|
end
|
|
|
|
if payment_method == "bank_accounts:debit_card" then
|
|
bank_accounts.add_balance(player_name, -total_cost_float, "Shop-Kauf", shop.name, shop.owner)
|
|
else -- credit_card
|
|
bank_accounts.add_credit(player_name, -total_cost_float, "Shop-Kauf", shop.name, shop.owner)
|
|
end
|
|
|
|
else
|
|
local credit = pmeta:get_int(ss.modname .. ":session_credit") or 0
|
|
if credit < total_cost_cents then
|
|
local needed = string.format("%.2f", (total_cost_cents - credit) / 100)
|
|
core.chat_send_player(player_name, S("Du hast nicht genug Geld eingezahlt. (Es fehlen @1)", needed .. " " .. ss.currency_suffix))
|
|
return
|
|
end
|
|
pmeta:set_int(ss.modname .. ":session_credit", credit - total_cost_cents)
|
|
end
|
|
|
|
local shop_meta = core.get_meta(pos)
|
|
local current_reserve = shop_meta:get_int("cash_reserve")
|
|
shop_meta:set_int("cash_reserve", current_reserve + total_cost_cents)
|
|
|
|
item_to_buy:set_count(item_to_buy:get_count() - quantity)
|
|
-- KORREKTUR: `set_stack` verwendet ebenfalls den direkten `slot_index`.
|
|
shop.inv:set_stack("main", slot_index, item_to_buy)
|
|
|
|
transaction.give_product(player, purchase_stack)
|
|
|
|
local cost_str = string.format("%.2f", total_cost_cents / 100)
|
|
core.chat_send_player(player_name, S("Du hast @1 @2 für @3 gekauft.", quantity, item_to_buy:get_description(), cost_str .. " " .. ss.currency_suffix))
|
|
|
|
ss.update_infotext(pos)
|
|
end
|
|
|
|
return transaction
|