added general handling of properties of npc

This commit is contained in:
Sokomine 2022-05-29 22:02:02 +02:00
parent b9827d848c
commit 299915708f
4 changed files with 180 additions and 3 deletions

View File

@ -16,6 +16,16 @@ yl_speak_up.input_fs_initial_config = function(player, formname, fields)
return
end
if(fields.edit_skin and fields.edit_skin ~= "") then
yl_speak_up.show_fs(player, "fashion")
return
end
if(fields.edit_properties and fields.edit_properties ~= "") then
yl_speak_up.show_fs(player, "properties")
return
end
if(not(fields.save_initial_config) or (fields and fields.exit)) then
-- is the player editing the npc? then leaving this config
-- dialog has to lead back to the talk dialog
@ -248,7 +258,7 @@ yl_speak_up.get_fs_initial_config = function(player, n_id, d_id, is_initial_conf
"longer be able to edit your NPC."
)
end
local formspec = "size[11,6.5]"..
local formspec = "size[11,8.0]"..
"label[0.2,0.5;"..tmp_text.."]"..
-- name of the npc
"label[0.2,1.65;Name:]"..
@ -265,9 +275,11 @@ yl_speak_up.get_fs_initial_config = function(player, n_id, d_id, is_initial_conf
"tooltip[n_owner;The owner of the NPC. This can only be changed\n"..
"if you have the npc_talk_master priv.;#FFFFFF;#000000]"..
may_be_edited_by..
"button[1.0,5.5;4,0.9;edit_skin;Edit Skin]"..
"button[6.0,5.5;4,0.9;edit_properties;Edit Properties]"..
-- save and exit buttons
"button_exit[3.2,5.5;2,0.9;save_initial_config;Save]"..
"button_exit[5.4,5.5;2,0.9;exit;Exit]"
"button[3.2,7.0;2,0.9;save_initial_config;Save]"..
"button_exit[5.4,7.0;2,0.9;exit;Exit]"
-- show the formspec to the player
return formspec
end

150
fs_properties.lua Normal file
View File

@ -0,0 +1,150 @@
-- Properties for NPC
--
-- This is used when an NPC doesn't have a specific dialog but still wants to
-- make use of a (or some) generic dialog(es)
-- helper function
yl_speak_up.get_npc_properties = function(pname)
if(not(pname) or not(yl_speak_up.speak_to[pname])) then
return
end
local obj = yl_speak_up.speak_to[pname].obj
if(not(obj)) then
return
end
local entity = obj:get_luaentity()
if(not(entity)) then
return
end
if(not(entity.yl_speak_up)) then
return
end
local properties = entity.yl_speak_up.properties
if(not(properties)) then
properties = {}
entity.yl_speak_up.properties = properties
end
local prop_names = {}
for k, v in pairs(properties) do
table.insert(prop_names, k)
end
table.sort(prop_names)
return {entity = entity, properties = properties, prop_names = prop_names}
end
yl_speak_up.input_properties = function(player, formname, fields)
local pname = player:get_player_name()
if(not(pname) or not(yl_speak_up.speak_to[pname])) then
return
end
local n_id = yl_speak_up.speak_to[pname].n_id
if(fields and fields.back and fields.back ~= "") then
yl_speak_up.show_fs(player, "initial_config",
{n_id = n_id, d_id = yl_speak_up.speak_to[pname].d_id, false})
return
end
local selected_row = nil
if(fields and fields.store_new_val and fields.store_new_val ~= "") then
local property_data = yl_speak_up.get_npc_properties(pname)
if(property_data and fields.prop_name and fields.prop_name ~= ""
and fields.prop_val and fields.prop_val ~= "") then
local name = fields.prop_name
local val = fields.prop_val
-- add the new property or change an existing one
property_data.properties[name] = val
-- store it
property_data.entity.yl_speak_up.properties = property_data.properties
end
elseif(fields and fields.delete_prop and fields.delete_prop ~= "") then
local property_data = yl_speak_up.get_npc_properties(pname)
if(property_data and fields.prop_name and fields.prop_name ~= "") then
local name = fields.prop_name
-- delete the old property
property_data.properties[name] = nil
-- store it
property_data.entity.yl_speak_up.properties = property_data.properties
end
elseif(fields and fields.table_of_properties) then
local selected = minetest.explode_table_event(fields.table_of_properties)
if(selected.type == "CHG" or selected.type == "DLC") then
selected_row = selected.row
end
end
yl_speak_up.show_fs(player, "properties", {selected = selected_row})
end
yl_speak_up.get_fs_properties = function(pname, selected)
if(not(pname)) then
return ""
end
local n_id = yl_speak_up.speak_to[pname].n_id
-- is the player editing this npc? if not: abort
if(not(yl_speak_up.edit_mode[pname])
or (yl_speak_up.edit_mode[pname] ~= n_id)) then
return ""
end
local property_data = yl_speak_up.get_npc_properties(pname)
if(not(property_data)) then
-- something went wrong - there really is nothing useful we can do
-- if the NPC we want to interact with doesn't exist or is broken
return
end
local s = ""
local anz_prop = #property_data.prop_names
for i, k in ipairs(property_data.prop_names) do
local v = property_data.properties[k]
s = s.."#BBBBFF,"..minetest.formspec_escape(k)..","..minetest.formspec_escape(v)..","
end
s = s.."#00FF00,add,Add a new property"
if(not(selected) or selected == "") then
selected = -1
end
local add_selected = "label[3.5,6.5;No property selected.]"
selected = tonumber(selected)
if(selected > anz_prop + 1 or selected < 1) then
selected = -1
elseif(selected > anz_prop) then
add_selected = "label[0.2,6.5;Add new property:]"..
"field[3.0,6.5;3.5,1.0;prop_name;;]"..
"label[6.5,6.5;with value:]"..
"field[8.2,6.5;4.5,1.0;prop_val;;]"..
"button[8.2,7.8;2.0,1.0;store_new_val;Store]"
else
local name = property_data.prop_names[selected]
local val = minetest.formspec_escape(property_data.properties[name])
name = minetest.formspec_escape(name)
add_selected = "label[0.2,6.5;Change property:]"..
"field[3.0,6.5;3.5,1.0;prop_name;;"..name.."]"..
"label[6.5,6.5;to value:]"..
"field[8.2,6.5;4.5,1.0;prop_val;;"..val.."]"..
"button[8.2,7.8;2.0,1.0;store_new_val;Store]"..
"button[10.4,7.8;2.0,1.0;delete_prop;Delete]"
end
if(selected < 1) then
selected = ""
end
local dialog = yl_speak_up.speak_to[pname].dialog
local npc_name = minetest.formspec_escape(dialog.n_npc or "- nameless -")
return "size[12.5,8.5]" ..
"label[2,0;Properties of "..npc_name.." (ID: "..tostring(n_id).."):]"..
"tablecolumns[color,span=1;text;text]"..
"table[0.2,0.5;12,4.0;table_of_properties;"..s..";"..tostring(selected).."]"..
"tooltip[0.2,0.5;12,4.0;"..
"Click on \"add\" to add a new property.\n"..
"Click on the name of a property to change or delete it.]"..
"label[2.0,4.5;"..
"Properties are important for NPC that want to make use of generic dialogs.\n"..
"Properties can be used to determine which generic dialog(s) shall apply to\n"..
"this particular NPC and how they shall be configured.]"..
"button[5.0,7.8;2.0,0.9;back;Back]"..
add_selected
end

View File

@ -92,6 +92,9 @@ dofile(modpath .. "quest_api.lua")
dofile(modpath .. "staff_based_editing.lua")
-- setting skin, wielded item etc.
dofile(modpath .. "fs_fashion.lua")
-- properties for NPC without specific dialogs that want to make use of
-- some generic dialogs
dofile(modpath .. "fs_properties.lua")
-- the main functionality of the mod
dofile(modpath .. "functions.lua")
-- a way of determining a node position

View File

@ -22,6 +22,10 @@ minetest.register_on_player_receive_fields( function(player, formname, fields)
elseif formname == "yl_speak_up:fashion" then
yl_speak_up.input_fashion(player, formname, fields)
return true
-- handled in fs_properties.lua
elseif formname == "yl_speak_up:properties" then
yl_speak_up.input_properties(player, formname, fields)
return true
-- handled in inventory.lua
elseif formname == "yl_speak_up:inventory" then
yl_speak_up.input_inventory(player, formname, fields)
@ -244,6 +248,14 @@ yl_speak_up.show_fs = function(player, fs_name, param)
yl_speak_up.show_fs_ver(pname, "yl_speak_up:fashion",
yl_speak_up.get_fs_fashion(pname))
elseif(fs_name == "properties") then
if(not(param)) then
param = {}
end
yl_speak_up.show_fs_ver(pname, "yl_speak_up:properties",
yl_speak_up.get_fs_properties(pname, param.selected),
1)
elseif(fs_name == "inventory") then
-- this is a very classical formspec; it works far better with OLD fs;
-- force formspec version 1