326 lines
11 KiB
Lua

-- Debugging dialog for triggers. Shows a list of
-- all triggers.
if minetest.settings:get_bool("lzr_debug", false) == false then
-- Debug dialog is only available if debug setting is
-- enabled
return
end
local S = minetest.get_translator("lzr_triggers")
local FS = function(...) return minetest.formspec_escape(S(...)) end
local F = minetest.formspec_escape
local COLOR_CAPTION = "#FFFFFF"
local COLOR_NONTRIGGER = "#BBBBBB"
local COLOR_ERROR = "#e28e0f"
local COLOR_SENDER = "#39df3b"
local COLOR_RECEIVER = "#df3939"
local COLOR_SENDER_RECEIVER = "#e2c70f"
local IMAGE_ID_BLANK = 0
local IMAGE_ID_SENDER = 1
local IMAGE_ID_RECEIVER = 2
local IMAGE_ID_SENDER_RECEIVER = 3
local IMAGE_ID_BAD_TRIGGER = 4
local trigger_type_images = "0=blank.png^[resize:16x16,1=lzr_triggers_icon_sender.png^[resize:16x16,2=lzr_triggers_icon_receiver.png^[resize:16x16,3=lzr_triggers_icon_sender_receiver.png^[resize:16x16,4=lzr_triggers_icon_error.png^[resize:16x16"
local signal_type_images = ""
for s=0, lzr_triggers.MAX_SIGNAL_TYPE do
signal_type_images = signal_type_images .. s .. "=" .. lzr_triggers.SIGNAL_TYPE_ICONS[s]
signal_type_images = signal_type_images .. ","
end
signal_type_images = signal_type_images .. (lzr_triggers.MAX_SIGNAL_TYPE + 1) .. "=lzr_triggers_icon_unknown.png,"
signal_type_images = signal_type_images .. (lzr_triggers.MAX_SIGNAL_TYPE + 2) .. "=blank.png^[resize:16x16"
local receiver_type_images = ""
for r=0, lzr_triggers.MAX_RECEIVER_TYPE do
receiver_type_images = receiver_type_images .. r .. "=" .. lzr_triggers.RECEIVER_TYPE_ICONS[r]
receiver_type_images = receiver_type_images .. ","
end
receiver_type_images = receiver_type_images .. (lzr_triggers.MAX_RECEIVER_TYPE + 1) .. "=lzr_triggers_icon_unknown.png,"
receiver_type_images = receiver_type_images .. (lzr_triggers.MAX_RECEIVER_TYPE + 2) .. "=blank.png^[resize:16x16"
local SIGNAL_TYPE_IMAGE_ID_BLANK = lzr_triggers.MAX_SIGNAL_TYPE + 2
local RECEIVER_TYPE_IMAGE_ID_BLANK = lzr_triggers.MAX_RECEIVER_TYPE + 2
local last_trigger_list = nil
local last_signal_list = nil
local show_trigger_dialog = function(player, selected_trigger)
local form = "formspec_version[7]"..
"size[14,10]"..
"box[0,0;14,0.8;#00000080]"..
"label[0.4,0.4;"..FS("Triggers").."]"
local tstrs = {}
local triggers = lzr_triggers.get_triggers()
local row = 1
local selected_idx
last_trigger_list = { false }
local triggers_ok, _, bad_trigger_ids_list = lzr_triggers.check_triggers(false)
local bad_trigger_ids_keyed = {}
if not triggers_ok then
for i=1, #bad_trigger_ids_list do
bad_trigger_ids_keyed[bad_trigger_ids_list[i]] = true
end
end
for trigger_id, def in pairs(triggers) do
if trigger_id == selected_trigger then
selected_idx = row + 1
end
table.insert(last_trigger_list, trigger_id)
local cnt_receivers = #lzr_triggers.get_receivers(trigger_id)
local cnt_senders = #lzr_triggers.get_senders(trigger_id)
local tstr = ""
-- bad trigger (error)
if bad_trigger_ids_keyed[trigger_id] then
tstr = tstr .. COLOR_ERROR..","..IMAGE_ID_BAD_TRIGGER..","
-- neither sender nor receiver
elseif cnt_receivers == 0 and cnt_senders == 0 then
tstr = tstr .. COLOR_NONTRIGGER..","..IMAGE_ID_BLANK..","
-- sender
elseif cnt_receivers > 0 and cnt_senders == 0 then
tstr = tstr .. COLOR_SENDER..","..IMAGE_ID_SENDER..","
-- receiver
elseif cnt_receivers == 0 and cnt_senders > 0 then
tstr = tstr .. COLOR_RECEIVER..","..IMAGE_ID_RECEIVER..","
-- sender-receiver
else
tstr = tstr .. COLOR_SENDER_RECEIVER..","..IMAGE_ID_SENDER_RECEIVER..","
end
tstr = tstr .. F(trigger_id) .. ","
if def.location == "player" then
tstr = tstr .. FS("player")..","
local item = lzr_triggers.find_trigger_in_player_inventory(player, trigger_id)
if item then
tstr = tstr .. F(ItemStack(item:get_name()):get_short_description()) .. ","
else
-- not translated; "unknown" refers to the unknown item
tstr = tstr .. "unknown,"
end
elseif type(def.location) == "table" then
local pstr = minetest.pos_to_string(def.location)
if pstr == trigger_id then
-- If location is equal to the trigger_id,
-- this implies the node is still at the
-- initial position (since trigger_id is based
-- on the initial node position).
-- This is indicated by the word "start"
tstr = tstr .. FS("start")..","
else
tstr = tstr .. F(minetest.pos_to_string(def.location))..","
end
local node = minetest.get_node(def.location)
local ndesc = ItemStack(node.name):get_short_description()
if not ndesc or ndesc == "" then
ndesc = node.name
end
tstr = tstr .. F(ndesc) .. ","
else
tstr = tstr .. F(tostring(def.location))..","
-- not translated; "unknown" refers to the unknown item
tstr = tstr .. "unknown,"
end
tstr = tstr .. cnt_receivers..","
tstr = tstr .. cnt_senders..","
local signal_type = def.signal_type
if signal_type < 0 or signal_type > lzr_triggers.MAX_SIGNAL_TYPE then
signal_type = lzr_triggers.MAX_SIGNAL_TYPE+1
end
local signal_type_desc = lzr_triggers.SIGNAL_TYPE_NAMES_SHORT[def.signal_type] or def.signal_type
tstr = tstr .. signal_type..","..signal_type_desc..","
local receiver_type = def.receiver_type
if receiver_type < 0 or receiver_type > lzr_triggers.MAX_RECEIVER_TYPE then
receiver_type = lzr_triggers.MAX_RECEIVER_TYPE+1
end
local receiver_type_desc = lzr_triggers.RECEIVER_TYPE_NAMES_SHORT[def.receiver_type] or def.receiver_type
tstr = tstr .. receiver_type..","..receiver_type_desc
table.insert(tstrs, tstr)
row = row + 1
end
if not selected_idx then
selected_idx = 1
end
local triggers_str = table.concat(tstrs, ",")
local trigger_list_elem
if triggers_str == "" then
trigger_list_elem = "label[0.5,1.5;"..FS("No triggers.").."]"
else
-- Header
triggers_str = COLOR_CAPTION..","..
IMAGE_ID_BLANK..","..
--~ Trigger list header: Trigger identifier
FS("ID")..","..
--~ Trigger list header: Trigger location
FS("Location")..","..
--~ Trigger list header: Trigger node
FS("Node")..","..
--~ Trigger list header: Number of receivers
FS("#Recv.")..","..
--~ Trigger list header: Number of senders
FS("#Send.")..","..
SIGNAL_TYPE_IMAGE_ID_BLANK..","..
--~ Trigger list header: Signal type
FS("Sig. type")..","..
RECEIVER_TYPE_IMAGE_ID_BLANK..","..
--~ Trigger list header: Receiver type
FS("Recv. type")..","..
triggers_str
local C_HEAD = "#FFFF00"
local C_DEF = "#FFFFA0"
trigger_list_elem = "label[0.5,1.25;"..FS("Triggers:").."]" ..
-- Explain table columns
"image[12,1;0.5,0.5;lzr_triggers_icon_tooltip.png]"..
"tooltip[12,1;0.5,0.5;"..
minetest.colorize(C_HEAD, FS("Columns:")).."\n"..
FS("@1: Unique trigger identifier", minetest.colorize(C_DEF, S("ID"))).."\n"..
FS("@1: Current node location (start = initial position, player = in player inventory)", minetest.colorize(C_DEF, S("Location"))).."\n"..
FS("@1: Name of the node that triggers", minetest.colorize(C_DEF, S("Node"))).."\n"..
FS("@1: Number of receivers this trigger sends to", minetest.colorize(C_DEF, S("#Recv."))).."\n"..
FS("@1: Number of senders this trigger receives from", minetest.colorize(C_DEF, S("#Send."))).."\n"..
FS("@1: Signal type", minetest.colorize(C_DEF, S("Sig. type"))).."\n"..
FS("@1: Receiver type", minetest.colorize(C_DEF, S("Recv. type"))).."]"
-- Explain signal type and receiver type abbreviations
trigger_list_elem = trigger_list_elem ..
"image[12.75,1;0.5,0.5;lzr_triggers_icon_tooltip.png]"..
"tooltip[12.75,1;0.5,0.5;"..
minetest.colorize("#FFFF00", FS("Signal types:")).."\n"
for i=0, lzr_triggers.MAX_SIGNAL_TYPE do
trigger_list_elem = trigger_list_elem .. FS("@1: @2", minetest.colorize(C_DEF, lzr_triggers.SIGNAL_TYPE_NAMES_SHORT[i]), lzr_triggers.SIGNAL_TYPE_NAMES[i]) .. "\n"
end
trigger_list_elem = trigger_list_elem .. "\n"..minetest.colorize(C_HEAD, FS("Receiver types:")).."\n"
for i=0, lzr_triggers.MAX_RECEIVER_TYPE do
trigger_list_elem = trigger_list_elem .. FS("@1: @2", minetest.colorize(C_DEF, lzr_triggers.RECEIVER_TYPE_NAMES_SHORT[i]), lzr_triggers.RECEIVER_TYPE_NAMES[i])
if i < lzr_triggers.MAX_RECEIVER_TYPE then
trigger_list_elem = trigger_list_elem .. "\n"
end
end
trigger_list_elem = trigger_list_elem .. "]"
-- The table columns, in this order
-- row color, sender/receiver icon, trigger_id, location, node name, receiver count, sender count, signal type icon, signal type text, receiver type icon, receiver type text
trigger_list_elem = trigger_list_elem .. "tablecolumns[color;"..
"image,"..trigger_type_images..";"..
"text;text;text;text;text;"..
"image,"..signal_type_images..";"..
"text;"..
"image,"..receiver_type_images..";"..
"text]"..
"table[0.5,1.75;13,5;trigger_list;"..triggers_str..";"..selected_idx.."]"
end
form = form .. trigger_list_elem
-- List receivers and senders of selected trigger
if selected_trigger then
local receivers = lzr_triggers.get_receivers(selected_trigger)
local senders = lzr_triggers.get_senders(selected_trigger)
local info_str = ""
if #senders > 0 or #receivers > 0 then
last_signal_list = { false }
info_str = COLOR_CAPTION..","..
IMAGE_ID_BLANK..","..
--~ Trigger list header: Trigger type
FS("Type")..","..
--~ Trigger list header: Trigger identifier
FS("ID")..","
for r=1, #receivers do
info_str = info_str .. COLOR_RECEIVER..","..IMAGE_ID_RECEIVER..","..FS("Receiver")..","..F(receivers[r])
if r < #receivers or #senders > 0 then
info_str = info_str .. ","
end
table.insert(last_signal_list, receivers[r])
end
for s=1, #senders do
info_str = info_str .. COLOR_SENDER ..","..IMAGE_ID_SENDER ..","..FS("Sender")..","..F(senders[s])
if s < #senders then
info_str = info_str .. ","
end
table.insert(last_signal_list, senders[s])
end
else
last_signal_list = {}
--~ Shown when there are no triggers in a trigger list
info_str = COLOR_CAPTION..","..IMAGE_ID_BLANK..","..FS("None")..","
end
local info_elem = "label[0.5,7;"..FS("Signals of trigger @1:", selected_trigger).."]" ..
"tablecolumns[color;image,"..trigger_type_images..";text;text]"..
"table[0.5,7.25;13,2.25;signal_list;"..info_str..";1]"
form = form .. info_elem
end
minetest.show_formspec(player:get_player_name(), "lzr_triggers:triggers", form)
end
minetest.register_chatcommand("show_triggers", {
description = S("Show a list of all triggers"),
privs = { debug = true },
params = "",
func = function(name, param)
local player = minetest.get_player_by_name(name)
if not player then
return false, S("No player.")
end
show_trigger_dialog(player)
return true
end
})
minetest.register_on_player_receive_fields(function(player, formname, fields)
if formname ~= "lzr_triggers:triggers" then
last_trigger_list = nil
last_signal_list = nil
return
end
if fields.quit then
last_trigger_list = nil
last_signal_list = nil
return
end
if fields.trigger_list then
if not last_trigger_list then
return
end
local expl = minetest.explode_table_event(fields.trigger_list)
if expl.type == "DCL" or expl.type == "CHG" then
local trigger_id = last_trigger_list[expl.row]
if trigger_id then
show_trigger_dialog(player, trigger_id)
else
show_trigger_dialog(player)
end
end
end
if fields.signal_list then
if not last_signal_list then
return
end
local expl = minetest.explode_table_event(fields.signal_list)
if expl.type == "DCL" then
local trigger_id = last_signal_list[expl.row]
if trigger_id then
show_trigger_dialog(player, trigger_id)
end
end
end
end)