diff --git a/api_properties.lua b/api_properties.lua new file mode 100644 index 0000000..17fedca --- /dev/null +++ b/api_properties.lua @@ -0,0 +1,109 @@ +-- handle properties + +-- 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: +-- get one property value of the NPC +yl_speak_up.get_one_npc_property = function(pname, property_name) + if(not(pname)) then + return nil + end + -- get just the property data + return yl_speak_up.get_npc_properties(pname, false)[property_name] +end + + +-- helper function; +-- adds "normal" properties of the npc with a self. prefix as well +-- if long_version is not set, a table containing all properties is returned; +-- if long_version *is* set, a table containing the table above plus additional entries is returned +yl_speak_up.get_npc_properties_long_version = function(pname, long_version) + 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 + -- copy other property data that is stored under self.* over as well (like i.e. self.order for mobs_redo) + for k, v in pairs(entity) do + local t = type(v) + if(t == "string" or t == "number" or t == "boolean") then + properties["self."..tostring(k)] = tostring(v) + end + end + properties["self.name"] = tostring(entity.name) + if(not(long_version)) then + return properties + end + -- the long version contains additional information + local prop_names = {} + for k, v in pairs(properties) do + table.insert(prop_names, k) + end + table.sort(prop_names) + return {obj = obj, entity = entity, properties = properties, prop_names = prop_names} +end + + +-- most of the time we don't need object, entity or a list of the names of properties; +-- this returns just the properties themshelves +yl_speak_up.get_npc_properties = function(pname) + return yl_speak_up.get_npc_properties_long_version(pname, false) +end + + +yl_speak_up.set_npc_property = function(pname, property_name, property_value, reason) + if(not(pname) or not(property_name) or property_name == "") then + return "No player name or property name given. Cannot load property data." + end + -- here we want a table with additional information + local property_data = yl_speak_up.get_npc_properties_long_version(pname, true) + if(not(property_data)) then + return "Failed to load property data of NPC." + end + -- it is possible to react to property changes with special custom handlers + if(yl_speak_up.custom_property_handler[property_name]) then + -- the table contains the pointer to a fucntion + local fun = yl_speak_up.custom_property_handler[property_name] + -- call that function with the current values + return fun(pname, property_name, property_value, property_data) + end + -- properties of type self. are not set directly + if(string.sub(property_name, 1, 5) == "self.") then + return "Properties of the type \"self.\" cannot be modified." + end + -- properites starting with "server" can only be changed or added manually by + -- players with the npc_talk_admin priv + if(string.sub(property_name, 1, 6) == "server") then + if(not(reason) or reason ~= "manually" or not(pname) + or not(minetest.check_player_privs(pname, {npc_talk_admin=true}))) then + return "Properties starting with \"server\" can only be changed by players ".. + "who have the \"npc_talk_admin\" priv." + end + end + -- store it + if(property_data.entity) then + property_data.entity.yl_speak_up.properties[property_name] = property_value + local n_id = yl_speak_up.speak_to[pname].n_id + yl_speak_up.log_change(pname, n_id, "Property \""..tostring(property_name).. + "\" set to \""..tostring(property_value).."\".") + end + -- TODO: handle non-npc (blocks etc) + return "OK" +end + diff --git a/fs_properties.lua b/fs_properties.lua index ff2f133..3b663b8 100644 --- a/fs_properties.lua +++ b/fs_properties.lua @@ -1,110 +1,4 @@ --- 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: --- get one property value of the NPC -yl_speak_up.get_one_npc_property = function(pname, property_name) - if(not(pname)) then - return nil - end - -- get just the property data - return yl_speak_up.get_npc_properties(pname, false)[property_name] -end - - --- helper function; --- adds "normal" properties of the npc with a self. prefix as well --- if long_version is not set, a table containing all properties is returned; --- if long_version *is* set, a table containing the table above plus additional entries is returned -yl_speak_up.get_npc_properties_long_version = function(pname, long_version) - 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 - -- copy other property data that is stored under self.* over as well (like i.e. self.order for mobs_redo) - for k, v in pairs(entity) do - local t = type(v) - if(t == "string" or t == "number" or t == "boolean") then - properties["self."..tostring(k)] = tostring(v) - end - end - properties["self.name"] = tostring(entity.name) - if(not(long_version)) then - return properties - end - -- the long version contains additional information - local prop_names = {} - for k, v in pairs(properties) do - table.insert(prop_names, k) - end - table.sort(prop_names) - return {obj = obj, entity = entity, properties = properties, prop_names = prop_names} -end - - --- most of the time we don't need object, entity or a list of the names of properties; --- this returns just the properties themshelves -yl_speak_up.get_npc_properties = function(pname) - return yl_speak_up.get_npc_properties_long_version(pname, false) -end - - -yl_speak_up.set_npc_property = function(pname, property_name, property_value, reason) - if(not(pname) or not(property_name) or property_name == "") then - return "No player name or property name given. Cannot load property data." - end - -- here we want a table with additional information - local property_data = yl_speak_up.get_npc_properties_long_version(pname, true) - if(not(property_data)) then - return "Failed to load property data of NPC." - end - -- it is possible to react to property changes with special custom handlers - if(yl_speak_up.custom_property_handler[property_name]) then - -- the table contains the pointer to a fucntion - local fun = yl_speak_up.custom_property_handler[property_name] - -- call that function with the current values - return fun(pname, property_name, property_value, property_data) - end - -- properties of type self. are not set directly - if(string.sub(property_name, 1, 5) == "self.") then - return "Properties of the type \"self.\" cannot be modified." - end - -- properites starting with "server" can only be changed or added manually by - -- players with the npc_talk_admin priv - if(string.sub(property_name, 1, 6) == "server") then - if(not(reason) or reason ~= "manually" or not(pname) - or not(minetest.check_player_privs(pname, {npc_talk_admin=true}))) then - return "Properties starting with \"server\" can only be changed by players ".. - "who have the \"npc_talk_admin\" priv." - end - end - -- store it - if(property_data.entity) then - property_data.entity.yl_speak_up.properties[property_name] = property_value - local n_id = yl_speak_up.speak_to[pname].n_id - yl_speak_up.log_change(pname, n_id, "Property \""..tostring(property_name).. - "\" set to \""..tostring(property_value).."\".") - end - -- TODO: handle non-npc (blocks etc) - return "OK" -end - +-- allow owner to see and edit properties of the NPC yl_speak_up.input_properties = function(player, formname, fields) local pname = player:get_player_name() diff --git a/init.lua b/init.lua index 890fa8e..2179797 100644 --- a/init.lua +++ b/init.lua @@ -230,6 +230,7 @@ yl_speak_up.reload = function(modpath, log_entry) dofile(modpath .. "fs_fashion.lua") -- properties for NPC without specific dialogs that want to make use of -- some generic dialogs + dofile(modpath .. "api_properties.lua") dofile(modpath .. "fs_properties.lua") -- the main functionality of the mod dofile(modpath .. "functions.lua")