From 25dec928ca64f6574dd534609b9a1e725e4d70ff Mon Sep 17 00:00:00 2001 From: xisd Date: Mon, 13 Jan 2020 20:27:16 +0100 Subject: [PATCH] API for regitering messages and fixes to idler spawning --- init.lua | 3 ++ mobs_api.lua | 87 +++++++++++++++++++++++++++++----------- mobs_npc_messages.fr.txt | 2 + npc_custom.lua | 33 ++++++++------- readme.md | 40 ++++++++++++++++-- 5 files changed, 121 insertions(+), 44 deletions(-) create mode 100755 mobs_npc_messages.fr.txt diff --git a/init.lua b/init.lua index fcc83d6..c01e262 100755 --- a/init.lua +++ b/init.lua @@ -8,6 +8,9 @@ local modpath = minetest.get_modpath(modname) local S = minetest.get_translator('mobs') mobs.translator = S +-- Define log level +mobs.vlog = "info" + -- Load support for documentation mobs.textstrings = {} mobs.textstrings.longdesc = {} diff --git a/mobs_api.lua b/mobs_api.lua index c3930fe..884ebe4 100755 --- a/mobs_api.lua +++ b/mobs_api.lua @@ -7,10 +7,11 @@ local S = mobs.translator local modname = minetest.get_current_modname() local modpath = minetest.get_modpath(modname) +local vlog = mobs.vlog or "action" --"info" if not mobs.npcs then mobs.npcs = {} end if not mobs.npcs.messages then mobs.npcs.messages = {} end -if not mobs.npcs.messages.default then mobs.npcs.messages.default = {} end +if not mobs.npcs.messages.random then mobs.npcs.messages.random = {} end --------------------------------------------------------------------------------------------- -- turn towards the player and stand @@ -41,6 +42,18 @@ mobs.npcs.turn_to_player = function( self, player ) end +string.lines_to_table = function(s) + if not s then s = '' end + local t = {} + local n = 1 + for line in s:gmatch("[^\r\n]+") do + t[n] = line + n = n + 1 + end + return t +end + + mobs.npcs.get_textures_array = function(prefix,modfrom) local n = 0 @@ -104,6 +117,27 @@ end +-- Register messages +-- Input must be either a string or a table of indexed values +-- Non-indexed values in tables will be ignored +mobs.npcs.messages.register_random = function(var) + local t + if type(var) == "table" then + t = var + elseif type(var) == "string" then + t = string.lines_to_table(var) + else + return false + end + local glob = mobs.npcs.messages.random + for _,v in ipairs(t) do + glob[#glob+1]= v + end + mobs.npcs.messages.random = glob + return true +end + + -- Define langage (code from intllib mod) @@ -112,53 +146,65 @@ if not (LANG and (LANG ~= "")) then LANG = os.getenv("LANG") end if not (LANG and (LANG ~= "")) then LANG = "en" end LANG = LANG:sub(1, 2) - -- Reused from mod random_messages -mobs.npcs.messages.get_list = function() - local default_messages_file_name = "mobs_npc_dialog" +mobs.npcs.messages.get_list_from_file = function(basename) + if not basename then return end local line_number = 1 - + local messages = {} + -- Look into the world folder first - local input = io.open(minetest.get_worldpath()..'/'..default_messages_file_name..'.txt',"r") + local input = io.open(minetest.get_worldpath()..'/'..basename..'.txt',"r") -- If it fails, try looking elswhere if not input then -- Localized default file in the mod folder - local default_input = io.open(minetest.get_modpath(modname)..'/'..default_messages_file_name..'.'..LANG..'.txt',"r") - local output = io.open(minetest.get_worldpath()..'/'..default_messages_file_name..'.txt',"w") + local default_input = io.open(minetest.get_modpath(modname)..'/'..basename..'.'..LANG..'.txt',"r") + local output = io.open(minetest.get_worldpath()..'/'..basename..'.txt',"w") if not default_input then -- localised file not found, look for a generic default file in the mod folder - default_input = io.open(minetest.get_modpath(modname)..'/'..default_messages_file_name..'.txt',"r") + default_input = io.open(minetest.get_modpath(modname)..'/'..basename..'.txt',"r") end if not default_input then -- Now we're out of options, blame the admin - output:write("Blame the server admin! He/She has probably not edited the random messages yet.\n") - output:write("Tell your dumb admin that this line is in (worldpath)/random_messages \n") + -- output:write("Blame the server admin! He/She has probably not edited the random messages yet.\n") + -- output:write("Tell your dumb admin that this line is in (worldpath)/random_messages \n") + -- As fun a the above would be, using default files or leaving this the output empty is now more convenient + minetest.log(vlog, '['..modname..'] '..'No input message file found for "'..basename.. '"... ignoring. Place a file named '.. basename .. '.txt' .. ' in world directory to add messages to the random messages list.' ) + else -- or write default_input content in worldpath message file + minetest.log(vlog, '['..modname..'] '..'No input message file found for "'..basename.. '"... updating world folder data' ) local content = default_input:read("*all") output:write(content) end io.close(output) if default_input then io.close(default_input) end - input = io.open(minetest.get_worldpath()..'/'..default_messages_file_name..'.txt',"r") + input = io.open(minetest.get_worldpath()..'/'..basename..'.txt',"r") end -- we should have input by now, so lets read it for line in input:lines() do - mobs.npcs.messages.default[line_number] = line + messages[line_number] = line line_number = line_number + 1 end -- close it io.close(input) + return messages end -- Fill messages array when server start. -mobs.npcs.messages.get_list() +local default_messages_file_name = "mobs_npc_messages" + +local messages_default = mobs.npcs.messages.get_list_from_file("mobs_npc_messages") +local messages_extra = mobs.npcs.messages.get_list_from_file("mobs_npc_messages_extra") + +mobs.npcs.messages.register_random(messages_default) +mobs.npcs.messages.register_random(messages_extra) + function table.count( t ) @@ -177,17 +223,10 @@ function table.random( t ) end mobs.npcs.messages.get_random = function() - return table.random(mobs.npcs.messages.default) + return table.random(mobs.npcs.messages.random) end - mobs.npcs.messages.get_random_from_string = function(str) - if not str then str = '' end - local arr = {} - local n = 1 - for line in str:gmatch("[^\r\n]+") do - arr[n] = line - n = n + 1 - end - return table.random(arr) + arr = string.lines_to_table(str) + return table.random(arr) end diff --git a/mobs_npc_messages.fr.txt b/mobs_npc_messages.fr.txt new file mode 100755 index 0000000..ccae6a7 --- /dev/null +++ b/mobs_npc_messages.fr.txt @@ -0,0 +1,2 @@ +Bonjour. +Etc. diff --git a/npc_custom.lua b/npc_custom.lua index d56e576..7e2a9e4 100755 --- a/npc_custom.lua +++ b/npc_custom.lua @@ -5,7 +5,7 @@ -- Translator local S = mobs.translator -local vlog = "action" --"info" +local vlog = mobs.vlog or "action" --"info" -- Mod related infos local modname = minetest.get_current_modname() local modpath = minetest.get_modpath(modname) @@ -422,25 +422,24 @@ end -- -- Register Npc -- --- Basic npc don'ts fight --- mob_def.runaway = true + mob_def.walk_chance = 0 mob_def.jump = false mob_def.do_custom = function(self, dtime) + -- Get mob pos + local pos = self.object:get_pos() - -- print(dump(dtime)) - - -- local spawner_pos = self._spawner_pos - -- if not spawner_pos then self.object:remove() - -- else - local pos = self.object:get_pos() - pos.y = pos.y - 1 - -- if ( spawner_pos ~= pos ) or ( minetest.get_node(pos).name ~= spawner_id ) then - if ( minetest.get_node(pos).name ~= spawner_id ) then - self.object:remove() - end - -- end - return false + -- Make sure that it is still on the spawner (or at least 'in' it, or 'above' it) + for i=-1,1 do + local spos = { x= pos.x, y= pos.y + i, z= pos.z, } + if ( minetest.get_node(spos).name == spawner_id ) then + -- Stop function when spawner is found + return false + end + end + -- Remove mob if it is away from spawner + self.object:remove() + return false end --~ mob_def.on_spawn = function(self,pos) --~ local data = @@ -461,7 +460,7 @@ minetest.register_node(spawner_id, { sounds = default.node_sound_stone_defaults(), node_box = { type = "fixed", - fixed = {-0.5, -0.48, -0.5, 0.3, -0.5, 0.3}, + fixed = {-0.5, -0.48, -0.5, 0.5, -0.5, 0.5}, }, on_construct = function(pos) -- minetest.get_node_timer(pos):start(20) diff --git a/readme.md b/readme.md index 24daedc..77a10ba 100755 --- a/readme.md +++ b/readme.md @@ -9,9 +9,43 @@ also it will have to be renamed to avec confusion with other mods -- --[x] Basic npc : wanders and say random things --[-] Special placeable npc with customisable interactions - ( with this one I hope to make it easy for any player to populate their constructions with interesting encounters, maybe even create some basic quests ) +# Mobs NPC + +This mod adds some NPCs + +Basic NPCS +-------------------------------- + +Those are aimed to make exploring more interesting. + +-[x] They spawn on grass or forest soil +-[x] They wander around and say random things when right-clicked +-[ ] They turn to monster when killed at night + + +Custom NPCs (aka idlers) +-------------------------------- + +Those are aimed to make it easy for any player to populate their constructions with interesting encounters, maybe even create some basic quests. + +-[x] Discret spawner block configurable with right-click +-[x] Re-spawn on right-click on the spawner +-[x] Easy to configure interface +-[x] Customisable nametag, look and infotext +-[ ] Player defined idle action : stand, sit, lay +-[-] Customisable actions + -[x] Can say random things from default list + -[x] Can say random things or from a custom list defined by player + -[ ] Can ask for items + -[ ] Can ask questions + -[ ] Can give item + -[ ] Can heal + -[ ] Can trade + +Planned features +-------------------------------- + +-[ ] Villagers (spawn near beds and stick around) -[ ] Zombie workers ___________________________________________________