init repo

This commit is contained in:
Rainer 2025-08-11 16:15:02 +02:00
commit 692f547daf
26 changed files with 1098 additions and 0 deletions

229
formspec.lua Normal file
View file

@ -0,0 +1,229 @@
--- Server Shops Formspec
--
-- @topic formspec
local ss = server_shop
local S = core.get_translator(ss.modname)
local transaction = dofile(ss.modpath .. "/transaction.lua")
ss.get_formspec = function(pos, player)
local shop = ss.get_shop(pos)
if not shop then
return "size[5,1]label[0,0;" .. S("Ungültiger Shop!") .. "]"
end
local pmeta = player:get_meta()
local is_owner = ss.is_shop_owner(pos, player) or ss.is_shop_admin(player)
local current_tab = pmeta:get_string(ss.modname .. ":tab")
if current_tab == "" and is_owner then current_tab = "inventory" end
local inv_size = shop.inv:get_size("main")
local fs_width = 14
local fs_height = 12.5 -- Angepasst für 20 slots
local pos_fs = pos.x .. "," .. pos.y .. "," .. pos.z
local formspec = "formspec_version[4]" .. "size[" .. fs_width .. "," .. fs_height .. "]" .. "label[0.5,0.4;" .. core.formspec_escape(shop.name) .. "]"
if is_owner then
formspec = formspec .. "tabheader[0.2,0;tabs;" .. S("Inventar & Preise") .. "," .. S("Einstellungen") .. "," .. S("Kundenansicht") .. ";" .. (current_tab == "inventory" and "1" or current_tab == "settings" and "2" or "3") .. ";true;true]"
if current_tab == "inventory" then
formspec = formspec .. "label[0.5,0.8;" .. S("Shop-Inventar") .. "]"
.. "list[nodemeta:"..pos_fs..";main;0.5,1.2;5,1;0]"
.. "list[nodemeta:"..pos_fs..";main;7.5,1.2;5,1;5]"
for i=1, 5 do
local x = 0.5 + (i-1) * 1.25; local price_int = shop.prices[i] or 0; local price_str = (price_int > 0) and string.format("%.2f", price_int / 100) or ""
formspec = formspec .. "field["..x..",2.3;1.0,1;price_"..i..";;"..price_str.."]"
end
for i=6, 10 do
local x = 7.5 + (i-6) * 1.25; local price_int = shop.prices[i] or 0; local price_str = (price_int > 0) and string.format("%.2f", price_int / 100) or ""
formspec = formspec .. "field["..x..",2.3;1.0,1;price_"..i..";;"..price_str.."]"
end
if inv_size > 10 then
formspec = formspec .. "list[nodemeta:"..pos_fs..";main;0.5,3.7;5,1;10]"
.. "list[nodemeta:"..pos_fs..";main;7.5,3.7;5,1;15]"
for i=11, 15 do
local x = 0.5 + (i-11) * 1.25; local price_int = shop.prices[i] or 0; local price_str = (price_int > 0) and string.format("%.2f", price_int / 100) or ""
formspec = formspec .. "field["..x..",4.8;1.0,1;price_"..i..";;"..price_str.."]"
end
for i=16, 20 do
local x = 7.5 + (i-16) * 1.25; local price_int = shop.prices[i] or 0; local price_str = (price_int > 0) and string.format("%.2f", price_int / 100) or ""
formspec = formspec .. "field["..x..",4.8;1.0,1;price_"..i..";;"..price_str.."]"
end
end
elseif current_tab == "settings" then
formspec = formspec .. "label[0.5,0.8;" .. S("Shop-Name") .. "]" .. "field[0.5,1.2;7,0.7;shop_name;;" .. shop.name .. "]"
end
end
if not is_owner or current_tab == "customer" then
formspec = formspec .. "label[0.5,0.8;"..S("Zum Kaufen auf einen Artikel klicken:").."]"
local inv_list = shop.inv:get_list("main")
for i=1, 10 do
local item = inv_list[i]
if not item:is_empty() and shop.prices[i] and shop.prices[i] > 0 then
local is_row_1 = (i <= 5); local x = (is_row_1 and 0.5 or 7.5) + ((is_row_1 and i-1 or i-6) * 1.25)
local y_image = 1.2; local y_price = y_image + 1.2; local y_currency = y_price + 0.3
local count = item:get_count(); local price_str = string.format("%.2f", shop.prices[i] / 100)
formspec = formspec .. "item_image_button["..x..","..y_image..";1,1;"..item:get_name()..";buy_slot_"..i..";]" .. "label["..x..","..y_image..";" .. count .. "]" .. "label["..x..","..y_price..";" .. price_str .. "]" .. "label["..x..","..y_currency..";" .. (ss.currency_suffix or "") .. "]"
end
end
if inv_size > 10 then
for i=11, 20 do
local item = inv_list[i]
if not item:is_empty() and shop.prices[i] and shop.prices[i] > 0 then
local is_row_1 = (i <= 15); local x = (is_row_1 and 0.5 or 7.5) + ((is_row_1 and i-11 or i-16) * 1.25)
local y_image = 3.7; local y_price = y_image + 1.2; local y_currency = y_price + 0.3
local count = item:get_count(); local price_str = string.format("%.2f", shop.prices[i] / 100)
formspec = formspec .. "item_image_button["..x..","..y_image..";1,1;"..item:get_name()..";buy_slot_"..i..";]" .. "label["..x..","..y_image..";" .. count .. "]" .. "label["..x..","..y_price..";" .. price_str .. "]" .. "label["..x..","..y_currency..";" .. (ss.currency_suffix or "") .. "]"
end
end
end
end
local player_inv_y = 7.5
formspec = formspec .. "label[0.5," .. (player_inv_y - 0.4) .. ";" .. S("Dein Inventar") .. "]" .. "list[current_player;main;0.5," .. player_inv_y .. ";8,4;]"
local right_col_x = 10.8
if is_owner then
if current_tab == "inventory" then
local cash_reserve_int = core.get_meta(pos):get_int("cash_reserve"); local cash_reserve_str = string.format("%.2f", cash_reserve_int / 100)
formspec = formspec .. "label["..right_col_x..", " .. (player_inv_y - 0.4) .. ";" .. S("Shop-Kasse:") .. "]"
.. "label["..right_col_x..", " .. player_inv_y .. ";" .. cash_reserve_str .. " " .. (ss.currency_suffix or "") .. "]"
.. "button["..right_col_x..", " .. (player_inv_y + 0.5) .. ";2.5,0.8;refund_reserve;"..S("Auszahlen").."]"
end
formspec = formspec .. "button["..right_col_x.."," .. (fs_height - 2) .. ";2.5,0.8;save_all;" .. S("Speichern") .. "]"
end
if not is_owner or (is_owner and current_tab == "customer") then
local payment_method = pmeta:get_string(ss.modname..":payment_method")
local credit_str = "0.00"
if bank_accounts and payment_method == "bank_accounts:debit_card" then
local balance = bank_accounts.get_balance(player:get_player_name())
credit_str = string.format("%.2f", balance)
elseif bank_accounts and payment_method == "bank_accounts:credit_card" then
local credit = bank_accounts.get_credit(player:get_player_name())
credit_str = string.format("%.2f", credit)
else
local session_credit_int = pmeta:get_int(ss.modname..":session_credit") or 0
credit_str = string.format("%.2f", session_credit_int / 100)
end
formspec = formspec .. "label["..right_col_x..", " .. (player_inv_y - 0.4) .. ";" .. S("Einzahlung (MG/Karte):") .. "]"
.. "list[detached:"..ss.modname..":customer_deposit;main;"..right_col_x..","..player_inv_y..";1,1;]"
.. "button["..right_col_x..",".. (player_inv_y + 1.2) ..";2.5,0.8;refund_session;"..S("Auszahlen").."]"
.. "label["..right_col_x + 1.2 ..",".. (player_inv_y + 0.2) ..";" .. S("Guthaben:") .. "]"
.. "label["..right_col_x + 1.2 ..",".. (player_inv_y + 0.6) ..";" .. credit_str .. " " .. (ss.currency_suffix or "") .. "]"
end
formspec = formspec .. "button_exit[" .. right_col_x .. "," .. (fs_height - 1) .. ";2.5,0.8;close;" .. S("Schließen") .. "]"
return formspec
end
ss.show_formspec = function(pos, player)
-- Die Reset-Logik wurde in node.lua -> on_rightclick verschoben
core.show_formspec(player:get_player_name(), ss.modname..":shop", ss.get_formspec(pos, player))
end
core.register_on_player_receive_fields(function(player, formname, fields)
if formname ~= ss.modname..":shop" then return end
if fields.quit then
local pmeta = player:get_meta()
local pos = core.deserialize(pmeta:get_string(ss.modname .. ":pos"))
if ss.refund_on_close and pos then
-- Gilt für jeden Spieler mit Guthaben, auch den Besitzer
local total = pmeta:get_int(ss.modname..":session_credit") or 0
if total > 0 then
local refund_stacks, remainder = transaction.calculate_refund(total)
for _, stack in ipairs(refund_stacks) do transaction.give_product(player, stack) end
pmeta:set_int(ss.modname..":session_credit", remainder)
end
local deposit_inv = core.get_inventory({type="detached", name=ss.modname..":customer_deposit"})
if deposit_inv then
local stack = deposit_inv:get_stack("main", 1)
if not stack:is_empty() and (stack:get_name() == "bank_accounts:debit_card" or stack:get_name() == "bank_accounts:credit_card") then
transaction.give_product(player, stack)
deposit_inv:set_stack("main", 1, nil)
pmeta:set_string(ss.modname..":payment_method", nil)
end
end
end
return
end
local pmeta = player:get_meta()
local pos = core.deserialize(pmeta:get_string(ss.modname .. ":pos"))
if not pos then return end
local is_owner = ss.is_shop_owner(pos, player) or ss.is_shop_admin(player)
-- KORREKTUR: inv_size wird jetzt nur einmal hier geholt, um für alle Schleifen gültig zu sein
local inv = core.get_meta(pos):get_inventory()
local inv_size = inv and inv:get_size("main") or 10
if is_owner and fields.tabs then
local new_tab = "inventory"; if fields.tabs == "2" then new_tab = "settings" elseif fields.tabs == "3" then new_tab = "customer" end
pmeta:set_string(ss.modname .. ":tab", new_tab)
end
for i = 1, inv_size do
if fields["buy_slot_"..i] then
transaction.execute_purchase(pos, player, i)
ss.show_formspec(pos, player)
return
end
end
if fields.refund_session then
local total = pmeta:get_int(ss.modname..":session_credit") or 0
if total > 0 then
local refund_stacks, remainder = transaction.calculate_refund(total);
for _, stack in ipairs(refund_stacks) do transaction.give_product(player, stack) end
pmeta:set_int(ss.modname..":session_credit", remainder)
end
end
if is_owner then
local shop_meta = core.get_meta(pos)
if fields.save_all then
local current_tab = pmeta:get_string(ss.modname .. ":tab") or "inventory"
if current_tab == "settings" then
if fields.shop_name then
shop_meta:set_string("name", fields.shop_name or "")
end
elseif current_tab == "inventory" then
local prices = core.deserialize(shop_meta:get_string("prices")) or {}
local inv_list = inv:get_list("main")
for i = 1, inv_size do
if not inv_list[i]:is_empty() then
if fields["price_"..i] then
local price_input = fields["price_"..i]
if price_input and price_input ~= "" then
local price_num = tonumber((price_input:gsub(",", ".")))
if price_num and price_num > 0 then
prices[i] = math.floor(price_num * 100 + 0.5)
end
end
end
else
prices[i] = nil
end
end
shop_meta:set_string("prices", core.serialize(prices))
end
ss.update_infotext(pos)
end
if fields.refund_reserve then
local total = shop_meta:get_int("cash_reserve")
if total > 0 then
local refund_stacks, remainder = transaction.calculate_refund(total)
for _, stack in ipairs(refund_stacks) do transaction.give_product(player, stack) end
shop_meta:set_int("cash_reserve", remainder)
end
end
end
ss.show_formspec(pos, player)
end)