API for regitering messages and fixes to idler spawning
parent
b58cd80e8d
commit
25dec928ca
3
init.lua
3
init.lua
|
@ -8,6 +8,9 @@ local modpath = minetest.get_modpath(modname)
|
||||||
local S = minetest.get_translator('mobs')
|
local S = minetest.get_translator('mobs')
|
||||||
mobs.translator = S
|
mobs.translator = S
|
||||||
|
|
||||||
|
-- Define log level
|
||||||
|
mobs.vlog = "info"
|
||||||
|
|
||||||
-- Load support for documentation
|
-- Load support for documentation
|
||||||
mobs.textstrings = {}
|
mobs.textstrings = {}
|
||||||
mobs.textstrings.longdesc = {}
|
mobs.textstrings.longdesc = {}
|
||||||
|
|
87
mobs_api.lua
87
mobs_api.lua
|
@ -7,10 +7,11 @@ local S = mobs.translator
|
||||||
|
|
||||||
local modname = minetest.get_current_modname()
|
local modname = minetest.get_current_modname()
|
||||||
local modpath = minetest.get_modpath(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 then mobs.npcs = {} end
|
||||||
if not mobs.npcs.messages then mobs.npcs.messages = {} 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
|
-- turn towards the player and stand
|
||||||
|
@ -41,6 +42,18 @@ mobs.npcs.turn_to_player = function( self, player )
|
||||||
end
|
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)
|
mobs.npcs.get_textures_array = function(prefix,modfrom)
|
||||||
|
|
||||||
local n = 0
|
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)
|
-- 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
|
if not (LANG and (LANG ~= "")) then LANG = "en" end
|
||||||
LANG = LANG:sub(1, 2)
|
LANG = LANG:sub(1, 2)
|
||||||
|
|
||||||
|
|
||||||
-- Reused from mod random_messages
|
-- Reused from mod random_messages
|
||||||
mobs.npcs.messages.get_list = function()
|
mobs.npcs.messages.get_list_from_file = function(basename)
|
||||||
local default_messages_file_name = "mobs_npc_dialog"
|
if not basename then return end
|
||||||
local line_number = 1
|
local line_number = 1
|
||||||
|
local messages = {}
|
||||||
|
|
||||||
-- Look into the world folder first
|
-- 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 it fails, try looking elswhere
|
||||||
if not input then
|
if not input then
|
||||||
|
|
||||||
-- Localized default file in the mod folder
|
-- Localized default file in the mod folder
|
||||||
local default_input = io.open(minetest.get_modpath(modname)..'/'..default_messages_file_name..'.'..LANG..'.txt',"r")
|
local default_input = io.open(minetest.get_modpath(modname)..'/'..basename..'.'..LANG..'.txt',"r")
|
||||||
local output = io.open(minetest.get_worldpath()..'/'..default_messages_file_name..'.txt',"w")
|
local output = io.open(minetest.get_worldpath()..'/'..basename..'.txt',"w")
|
||||||
if not default_input then
|
if not default_input then
|
||||||
-- localised file not found, look for a generic default file in the mod folder
|
-- 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
|
end
|
||||||
|
|
||||||
if not default_input then
|
if not default_input then
|
||||||
-- Now we're out of options, blame the admin
|
-- 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("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("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
|
else
|
||||||
-- or write default_input content in worldpath message file
|
-- 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")
|
local content = default_input:read("*all")
|
||||||
output:write(content)
|
output:write(content)
|
||||||
end
|
end
|
||||||
io.close(output)
|
io.close(output)
|
||||||
|
|
||||||
if default_input then io.close(default_input) end
|
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
|
end
|
||||||
|
|
||||||
-- we should have input by now, so lets read it
|
-- we should have input by now, so lets read it
|
||||||
for line in input:lines() do
|
for line in input:lines() do
|
||||||
mobs.npcs.messages.default[line_number] = line
|
messages[line_number] = line
|
||||||
line_number = line_number + 1
|
line_number = line_number + 1
|
||||||
end
|
end
|
||||||
-- close it
|
-- close it
|
||||||
io.close(input)
|
io.close(input)
|
||||||
|
return messages
|
||||||
end
|
end
|
||||||
|
|
||||||
-- Fill messages array when server start.
|
-- 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 )
|
function table.count( t )
|
||||||
|
@ -177,17 +223,10 @@ function table.random( t )
|
||||||
end
|
end
|
||||||
|
|
||||||
mobs.npcs.messages.get_random = function()
|
mobs.npcs.messages.get_random = function()
|
||||||
return table.random(mobs.npcs.messages.default)
|
return table.random(mobs.npcs.messages.random)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
mobs.npcs.messages.get_random_from_string = function(str)
|
mobs.npcs.messages.get_random_from_string = function(str)
|
||||||
if not str then str = '' end
|
arr = string.lines_to_table(str)
|
||||||
local arr = {}
|
return table.random(arr)
|
||||||
local n = 1
|
|
||||||
for line in str:gmatch("[^\r\n]+") do
|
|
||||||
arr[n] = line
|
|
||||||
n = n + 1
|
|
||||||
end
|
|
||||||
return table.random(arr)
|
|
||||||
end
|
end
|
||||||
|
|
|
@ -0,0 +1,2 @@
|
||||||
|
Bonjour.
|
||||||
|
Etc.
|
|
@ -5,7 +5,7 @@
|
||||||
-- Translator
|
-- Translator
|
||||||
local S = mobs.translator
|
local S = mobs.translator
|
||||||
|
|
||||||
local vlog = "action" --"info"
|
local vlog = mobs.vlog or "action" --"info"
|
||||||
-- Mod related infos
|
-- Mod related infos
|
||||||
local modname = minetest.get_current_modname()
|
local modname = minetest.get_current_modname()
|
||||||
local modpath = minetest.get_modpath(modname)
|
local modpath = minetest.get_modpath(modname)
|
||||||
|
@ -422,25 +422,24 @@ end
|
||||||
--
|
--
|
||||||
-- Register Npc
|
-- Register Npc
|
||||||
--
|
--
|
||||||
-- Basic npc don'ts fight
|
|
||||||
-- mob_def.runaway = true
|
|
||||||
mob_def.walk_chance = 0
|
mob_def.walk_chance = 0
|
||||||
mob_def.jump = false
|
mob_def.jump = false
|
||||||
mob_def.do_custom = function(self, dtime)
|
mob_def.do_custom = function(self, dtime)
|
||||||
|
-- Get mob pos
|
||||||
|
local pos = self.object:get_pos()
|
||||||
|
|
||||||
-- print(dump(dtime))
|
-- Make sure that it is still on the spawner (or at least 'in' it, or 'above' it)
|
||||||
|
for i=-1,1 do
|
||||||
-- local spawner_pos = self._spawner_pos
|
local spos = { x= pos.x, y= pos.y + i, z= pos.z, }
|
||||||
-- if not spawner_pos then self.object:remove()
|
if ( minetest.get_node(spos).name == spawner_id ) then
|
||||||
-- else
|
-- Stop function when spawner is found
|
||||||
local pos = self.object:get_pos()
|
return false
|
||||||
pos.y = pos.y - 1
|
end
|
||||||
-- if ( spawner_pos ~= pos ) or ( minetest.get_node(pos).name ~= spawner_id ) then
|
end
|
||||||
if ( minetest.get_node(pos).name ~= spawner_id ) then
|
-- Remove mob if it is away from spawner
|
||||||
self.object:remove()
|
self.object:remove()
|
||||||
end
|
return false
|
||||||
-- end
|
|
||||||
return false
|
|
||||||
end
|
end
|
||||||
--~ mob_def.on_spawn = function(self,pos)
|
--~ mob_def.on_spawn = function(self,pos)
|
||||||
--~ local data =
|
--~ local data =
|
||||||
|
@ -461,7 +460,7 @@ minetest.register_node(spawner_id, {
|
||||||
sounds = default.node_sound_stone_defaults(),
|
sounds = default.node_sound_stone_defaults(),
|
||||||
node_box = {
|
node_box = {
|
||||||
type = "fixed",
|
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)
|
on_construct = function(pos)
|
||||||
-- minetest.get_node_timer(pos):start(20)
|
-- minetest.get_node_timer(pos):start(20)
|
||||||
|
|
40
readme.md
40
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
|
# Mobs NPC
|
||||||
-[-] 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 )
|
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
|
-[ ] Zombie workers
|
||||||
|
|
||||||
___________________________________________________
|
___________________________________________________
|
||||||
|
|
Loading…
Reference in New Issue