first commit

This commit is contained in:
xisd 2019-05-02 09:01:47 +02:00
commit bef622640c
254 changed files with 1099 additions and 0 deletions

4
depends.txt Normal file
View File

@ -0,0 +1,4 @@
default
mobs
mobs_creatures?
treasurer?

72
init.lua Normal file
View File

@ -0,0 +1,72 @@
--
local modname = minetest.get_current_modname()
local modpath = minetest.get_modpath(modname)
-- Load support for intllib.
local S, NS = dofile(modpath.."/intllib.lua")
mobs.intllib = S
mobs.textstrings = {}
mobs.textstrings.longdesc = {}
mobs.textstrings.usagehelp = {}
-- General functions, items, nodes
--dofile(modpath .. "/mobs_textstrings.lua")
dofile(modpath .. "/mobs_api.lua")
dofile(modpath .. "/mobs_definitions.lua")
--dofile(modpath .. "/mobs_craftitems.lua")
--
-- NPCs
--
dofile(modpath .. "/npc_lambda.lua")
dofile(modpath .. "/npc_custom.lua")
--dofile(modpath .. "/npc_trader.lua")
--dofile(modpath .. "/npc_soldier.lua")
--dofile(modpath .. "/npc_monk.lua")
--
-- Map generation
--
--dofile(modpath .. "/mobs_mapgen.lua")
--
-- Compatibility
--
--dofile(modpath .. "/lucky_block.lua")
--
-- Notification
--
minetest.register_abm({
label = "Bed npc spawning",
nodenames = {"default:bed"},
-- neighbors = {"default:water_source", "default:water_flowing"},
interval = 150, -- Operation interval in seconds
chance = 1, -- Chance of trigger per-node per-interval is 1.0 / this
-- catch_up = true, -- If true, catch-up behaviour is enabled --[[
--~ ^ The chance value is temporarily reduced when returning to
--~ an area to simulate time lost by the area being unattended.
--~ ^ Note chance value can often be reduced to 1 ]]
action = function(pos, node, active_object_count, active_object_count_wider)
local meta = minetest.get_meta(pos)
local spawn = meta:get_string("spawn")
if not spawn then return end
spawn_pos = math.random()
end,
})
print ("[MOD] Mobs Redo 'mobs_bundle_npc' loaded")

44
intllib.lua Executable file
View File

@ -0,0 +1,44 @@
-- Fallback functions for when `intllib` is not installed.
-- Code released under Unlicense <http://unlicense.org>.
-- Get the latest version of this file at:
-- https://raw.githubusercontent.com/minetest-mods/intllib/master/lib/intllib.lua
local function format(str, ...)
local args = { ... }
local function repl(escape, open, num, close)
if escape == "" then
local replacement = tostring(args[tonumber(num)])
if open == "" then
replacement = replacement..close
end
return replacement
else
return "@"..open..num..close
end
end
return (str:gsub("(@?)@(%(?)(%d+)(%)?)", repl))
end
local gettext, ngettext
if minetest.get_modpath("intllib") then
if intllib.make_gettext_pair then
-- New method using gettext.
gettext, ngettext = intllib.make_gettext_pair()
else
-- Old method using text files.
gettext = intllib.Getter()
end
end
-- Fill in missing functions.
gettext = gettext or function(msgid, ...)
return format(msgid, ...)
end
ngettext = ngettext or function(msgid, msgid_plural, n, ...)
return format(n==1 and msgid or msgid_plural, ...)
end
return gettext, ngettext

164
mobs_api.lua Normal file
View File

@ -0,0 +1,164 @@
--
-- This file adds function to complete the mobs_redo api
--
local S = mobs.intllib
local modname = minetest.get_current_modname()
local modpath = minetest.get_modpath(modname)
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
---------------------------------------------------------------------------------------------
-- turn towards the player and stand
-- (based on function from mobf_trader)
---------------------------------------------------------------------------------------------
function get_face_direction(v1, v2)
if v1 and v2 then
if v1.x and v2.x and v1.z and v2.z then
local dx = v1.x - v2.x
local dz = v2.z - v1.z
return math.atan2(dx, dz)
end
end
end
mobs.npcs.turn_to_player = function( self, player )
-- Stand sill and pretend to listen
self.timer = 0
self.object:setvelocity({x = 0, y = 0, z = 0})
self.state = "stand"
mobs:set_animation(self, "stand")
-- Turn to player
if( self.object and self.object.setyaw ) then
self.object:setyaw( get_face_direction( self.object:getpos(), player:getpos() ));
end
end
mobs.npcs.get_textures_array = function(prefix,modfrom)
local n = 0
local tn, tf, fp
local tx = {}
while true do
tn = prefix .. n .. ".png"
tf = minetest.get_modpath(modname) .. "/textures/".. tn
fp = io.open(tf)
if not fp then break end
fp:close()
tx[#tx+1]={tn}
n = n + 1
end
if #tx > 0 then return tx end
end
mobs.npcs.get_mobname = function(self,generic)
local mobname = generic or 'npc'
if self and self._mobname and self._mobname ~= '' then
return self._mobname
end
return mobname
end
mobs.npcs.send_chat_message = function(playername,msg,mobname)
if not mobname then mobname = 'npc' end
return minetest.chat_send_player(playername,'<'..mobname..'> '..msg)
end
-- Define langage (code from intllib mod)
local LANG = minetest.settings:get("language")
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"
local line_number = 1
-- Look into the world folder first
local input = io.open(minetest.get_worldpath()..'/'..default_messages_file_name..'.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")
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")
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")
else
-- or write default_input content in worldpath message file
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")
end
-- we should have input by now, so lets read it
for line in input:lines() do
mobs.npcs.messages.default[line_number] = line
line_number = line_number + 1
end
-- close it
io.close(input)
end
-- Fill messages array when server start.
mobs.npcs.messages.get_list()
function table.count( t )
local i = 0
for k in pairs( t ) do i = i + 1 end
return i
end
function table.random( t )
local rk = math.random( 1, table.count( t ) )
local i = 1
for k, v in pairs( t ) do
if ( i == rk ) then return v, k end
i = i + 1
end
end
mobs.npcs.messages.get_random = function()
return table.random(mobs.npcs.messages.default)
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)
end

8
mobs_craftitems.lua Normal file
View File

@ -0,0 +1,8 @@
--
-- This file register nodes and items needed by this mod
--
local S = mobs.intllib
local modname = minetest.get_current_modname()
local modpath = minetest.get_modpath(modname)

95
mobs_definitions.lua Normal file
View File

@ -0,0 +1,95 @@
--
-- This file contains base définition used to most npcs
--
local S = mobs.intllib
local modname = minetest.get_current_modname()
local modpath = minetest.get_modpath(modname)
if not mobs.npcs then mobs.npcs = {} end
mobs.npcs.base_def = {
type = "npc",
visual = "mesh",
mesh = "character.b3d",
textures = {
{"character.png"},
},
collisionbox = {-0.25, -1, -0.3, 0.25, 0.75, 0.3},
animation = {
speed_normal = 15, speed_run = 25,
stand_start = 0, stand_end = 79,
sit_start = 81, sit_end = 160,
lay_start = 162, lay_end = 166,
-- death = {start = 162, stop = 166, speed = 28, loop = false, duration = 2.12},
-- death_start = 162, death_end = 166,
walk_start = 168, walk_end = 188,
mine_start = 189, mine_end = 198,
attack_start = 200, attack_end = 119, -- walk_mine
run_start = 221, run_end = 241
},
makes_footstep_sound = true,
--~ sounds = {
--~ -- random = "mobs_zombie.1",
--~ -- war_cry = "mobs_zombie.3",
--~ -- attack = "mobs_zombie.2",
--~ -- damage = "mobs_zombie_hit",
--~ -- death = "mobs_zombie_death",
--~ },
hp_min = 12,
hp_max = 35,
armor = 200,
knock_back = 1,
lava_damage = 10,
damage = 4,
reach = 1,
attack_type = "dogfight",
group_attack = true,
view_range = 10,
walk_chance = 75,
walk_velocity = 1,
run_velocity = 2,
step_height = 0.6,
fear_height = 3,
jump = true,
jump_height = 1.1,
--~ drops = {
--~ {name = "mobs:rotten_flesh", chance = 6, min = 1, max = 3,}
--~ },
lifetimer = 180, -- 3 minutes
shoot_interval = 135, -- (lifetimer - (lifetimer / 4)), borrowed for do_custom time
on_rightclick = function(self, clicker)
-- Look at the player
mobs.npcs.turn_to_player( self, clicker )
-- Say something
local mobname = mobs.npcs.get_mobname(self)
local clickername = clicker:get_player_name()
local msg = mobs.npcs.messages.get_random()
mobs.npcs.send_chat_message(clickername,msg,mobname)
end
}
local spawn_on = {"default:dirt_with_grass", "default:dirt_with_rainforest_litter",
"default:dirt_with_coniferous_litter", "ethereal:bamboo_dirt"}
-- local spawn_on = {"group:soil"}
mobs.npcs.base_spawndef = {
nodes = spawn_on,
neighbors = {"air"},
min_light = 2,
max_light = 10,
interval = 250,
chance = 20000,
active_object_count = 2,
min_height = 0,
max_height = 50,
day_toggle = true,
}

2
mobs_npc_dialog.fr.txt Normal file
View File

@ -0,0 +1,2 @@
Bonjour.
Etc.

BIN
models/character.b3d Executable file

Binary file not shown.

617
npc_custom.lua Normal file
View File

@ -0,0 +1,617 @@
-- Basic NPC
--
-- Intllib
local S = mobs.intllib
local vlog = "action" --"info"
-- Mod related infos
local modname = minetest.get_current_modname()
local modpath = minetest.get_modpath(modname)
local mob_name = "npc_idler"
local icprefix=modname..'_icon_'
mobs.npcs.mob_data = {}
local function find_in_array(needle,stack)
if needle and stack then
for k,v in ipairs(stack) do
if v == needle then
return k
end
end
end
return nil
end
local function get_mob_data(pos)
local key = minetest.pos_to_string(pos)
return mobs.npcs.mob_data[key]
end
local function set_mob_data(pos,data)
local key = minetest.pos_to_string(pos)
mobs.npcs.mob_data[key] = data
end
mobs.npcs.interactions = {
default = {
icon = icprefix..'chat_random.png',
desc = S("Say one of the default random chat message strings"),
on_rightclick = function(self,player,data)
local mobname = mobs.npcs.get_mobname(self)
-- Say something
local playername = player:get_player_name()
local msg = mobs.npcs.messages.get_random()
mobs.npcs.send_chat_message(playername,msg,mobname)
end,
},
say = {
icon = icprefix..'chat.png',
desc = S("Say one of the line below as a chat message"),
formfields = {
{'textarea','message','',3},
},
on_rightclick = function(self, player,data)
local str = S('Hello world')
if not data then data = {} end
if data.action and data.action.message then
str = data.action.message
end
local mobname = mobs.npcs.get_mobname(self)
-- Say something
local playername = player:get_player_name()
local msg = mobs.npcs.messages.get_random_from_string(str)
mobs.npcs.send_chat_message(playername,msg,mobname)
end,
},
dialog = {
icon = icprefix..'dialog.png',
desc = S("Open a dialog menu with a text and a choice of answers"),
disabled = true,
},
ai = {
icon = icprefix..'ai.png',
desc = S("Try to mimic an intercation with the player"),
disabled = true,
},
craft = {
icon = icprefix..'crafter.png',
desc = S("Open a special inventory where the player can give item and received some transformed output"),
disabled = true,
},
heal = {
icon = icprefix..'healer.png',
desc = S("Heal the player"),
disabled = true,
},
give = {
icon = icprefix..'giver.png',
desc = S("Give something to the player"),
disabled = true,
},
alert_owner = {
icon = icprefix..'giver.png',
desc = S("Send an alert to the owner (allowing)"),
hidden = true,
},
}
--
-- Specific mob informations
--
local mob_id = modname..':'..mob_name
local spawner_id = modname..':'..mob_name..'_spawner'
-- Get base defintion
local mob_def = mobs.npcs.base_def
mob_def._spawner_pos = nil
local textures_string
-- Get textures
local textures = mobs.npcs.get_textures_array("character_lambda_",modname)
if textures then
mob_def.textures = textures
-- textures_string =
-- print(dump(textures_string))
-- print(dump(minetest.registered_entities[mob_id].textures))
end
--# Set specific interactions (say something)
mob_def.on_rightclick = function(self, clicker)
--# Look at the player
mobs.npcs.turn_to_player( self, clicker )
local spawner_pos = self._spawner_pos
if spawner_pos then
--# Do custom action
local data = get_mob_data(spawner_pos) or {}
if data.action and data.action.id then
local id = data.action.id
local ref = mobs.npcs.interactions
if ref[id] and ref[id].on_rightclick then
return ref[id].on_rightclick(self, clicker, data)
end
end
end
--# Or at least say something
local mobname = mobs.npcs.get_mobname(self)
local clickername = clicker:get_player_name()
local msg = mobs.npcs.messages.get_random()
mobs.npcs.send_chat_message(clickername,msg,mobname)
end
--
-- Register Spawn condition and egg
--
-- More usable texture array
local ta = {}
for k,v in ipairs(mob_def.textures) do
ta[k] = v[1]
end
local function get_npc_formspec(pos,n)
local spos = pos.x .. "," .. pos.y .. "," .. pos.z
local ww=8 -- window width
local wh=9 -- window height
local fw=4 -- field_width
local iy=0.5 -- index y
-- Texture list as a sring
local ts = table.concat(ta,',')
local data = get_mob_data(pos) or {}
if data.last_tab then n = data.last_tab end
if not n then n = 1 end
local n = tonumber(n)
minetest.log(vlog, '['..modname..'] '..'Showing formspec '..n)
-- print(dump(data))
local ti = 1
-- Get texture index
if data.textures then ti = find_in_array(data.textures[1],ta) or 1 end
local forms = {}
-- Not empty data values
local dv = {
nametag = data.nametag or '',
nametag_color = data.nametag_color or '',
infotext = data.infotext or '',
texture = ts or '',
wield_item = data.wield_item or '',
nametag = data.nametag or '',
}
forms[1] =
-- 'label[0,'.. iy - 0.5 ..';'..S('-- Menu de configuration --')..']' ..
-- 'container[0,0]'..
-- tooltip[<gui_element_name>;<tooltip_text>;<bgcolor>;<fontcolor>]
'field[0.3,'.. iy+1 ..';'..fw..',0.3;nametag;'..S('Nom')..';'..dv.nametag..']' ..
-- 'textarea[0.3,'.. iy+1.6 ..';'..fw..',1.6;infotext;'..S('InfoText')..';'..dv.infotext..']'..
-- 'field[0.3,'.. iy+2.5 ..';'..fw..',0.5;nametag_color;'..S('Nametag Color')..';#61ff0170]' ..
-- 'label[0,'.. iy+1.5 ..';'..S('Nametag Color')..']' ..
-- 'dropdown[0,'.. iy+2 ..';'..fw..';nametag_color;<item 1>,<item 2>,<item n>;1]' ..
'label[0,'.. iy+3 ..';'..S('Texture')..']' ..
'dropdown[0,'.. iy+3.5 ..';'..fw..';texture;'..dv.texture..';'..ti..']' ..
-- 'field[0.3,'.. iy+5 ..';'..fw..',0.3;wield_item;'..S('wield_item')..';'..dv.wield_item..']' ..
--~ 'button[0.1,2;2,1;form01;'..S('Look')..']' ..
--~ 'button[0.1,3;2,1;form01;'..S('Actions')..']' ..
-- 'button[0,'.. iy+5 ..';'..fw..',0.5;action;'..S('configurer les interactions')..']' ..
'button_exit['.. ww - 1 ..','.. wh - 1 ..';1,1;ok;ok]'..
''
forms[2] =
default.gui_slots ..
"list[nodemeta:" .. spos .. ";main;0,0.3;8,4;]" ..
"list[current_player;main;0,4.85;8,1;]" ..
"list[current_player;main;0,6.08;8,3;8]" ..
"listring[nodemeta:" .. spos .. ";main]" ..
"listring[current_player;main]" ..
default.get_hotbar_bg(0,4.85) ..
''
-- local action_buttons=''
-- local l = 0.1
-- for k,v in pairs(mobs.npcs.interactions) do
-- action_buttons = action_buttons..'image_button['..l..',0;1,1;'..v.icon..';'..k..';]'
-- l = l + 1
-- end
local acts={}
for k,v in pairs(mobs.npcs.interactions) do
if not ( v.disabled or v.hidden ) then
acts[#acts+1] = k
end
end
local action = data.action or {}
if not data.action then data.action = {} end
action.id = data.action.id or "default"
action.desc = mobs.npcs.interactions[action.id].desc
local actstr=table.concat(acts,',')
local ai = find_in_array(action.id,acts) or 1
local actionf = ''
local ayi = iy+2
if mobs.npcs.interactions[action.id] and mobs.npcs.interactions[action.id].formfields then
for _,v in ipairs(mobs.npcs.interactions[action.id].formfields) do
if v[1] == 'label' then
actionf = actionf .. 'label[0,'.. ayi ..';'..v[2]..']'
ayi = ayi + 1
elseif v[1] == 'textarea' then
local aname = v[2]
local dstr = action[aname] or 'Foo'
actionf = actionf .. 'textarea[0.3,'.. ayi ..';'..fw..','..v[4]..';action_'..v[2]..';'..v[3]..';'..dstr..']'
ayi = ayi + v[4] + 0.1
end
end
end
forms[3] =
'label[0,'.. iy-0.5 ..';'..S('When a player interact with this character :')..']' ..
'dropdown[0,'.. iy+0.5 ..';'..fw..';action_id;'..actstr..';'..ai..']' ..
'label[0,'.. iy+1.5 ..';'..action.desc..']' ..
actionf..
-- textlist[<X>,<Y>;<W>,<H>;<name>;<listelem 1>,<listelem 2>,...,<listelem n>;<selected idx>;<transparent>]
-- 'textlist[0,0;'..ww - 3*(ww/4)..','.. wh-1 ..';stagelist;action_1,stage_2,stage_3;1;false]'..
-- 'container['..ww - 3*(ww/4)..',0]'..
-- image_button[<X>,<Y>;<W>,<H>;<texture name>;<name>;<label>]
-- 'image_button[0.1,0;1,1;'..icprefix..'chat.png^'..icprefix..'selected.png'..';act1;]'..
-- action_buttons ..
-- 'container_end[]'..
-- 'button[0,'.. wh-1 ..';1,1;add_stage;+]'..
-- 'button[1,'.. wh-1 ..';1,1;help_stage;?]'..
'button_exit['.. ww - 1 ..','.. wh - 1 ..';1,1;ok;ok]'..
''
forms[4] =
'textarea[0.3,'.. iy+1.6 ..';'..fw..',1.6;infotext;'..S('InfoText')..';'..dv.infotext..']'..
''
local content = forms[n] or ''
local formspec =
'size['..ww..','..wh..']' ..
-- default.gui_bg ..
-- default.gui_bg_img ..
'field[-1,-1;0,0.5;key;;'..minetest.pos_to_string(pos)..']' ..
'tabheader[0,'.. iy - 0.5 ..';tab;Apparence,Inventaire,Action,Misc;'.. n..';false;false]'..
content..
-- tabheader[<X>,<Y>;<name>;<caption 1>,<caption 2>,...,<caption n>;<current_tab>;<transparent>;<draw_border>]
--~ default.get_hotbar_bg(0,4.85)
--~ button[<X>,<Y>;<W>,<H>;<name>;<label>]
--~ field[<X>,<Y>;<W>,<H>;<name>;<label>;<default>]
--~ textarea[<X>,<Y>;<W>,<H>;<name>;<label>;<default>]
--~ label[<X>,<Y>;<label>]
--~ dropdown[<X>,<Y>;<W>;<name>;<item 1>,<item 2>, ...,<item n>;<selected idx>]
-- 'button_exit['.. ww - 1 ..',0;1,1;close;x]'..
''
return formspec
end
-- Function to initialize spawner : add entity and update metadata
-- Call after place node and on rightclick
mobs.npcs.update_cmob_properties = function(pos, player, mob)
minetest.log(vlog, '['..modname..'] '..'Updating mob properties from data at '..minetest.pos_to_string(pos))
local data = get_mob_data(pos) or {}
if not mob and data.obj then mob = data.obj end
local self
if mob then self = mob:get_luaentity() end
if not self then return false end
minetest.log(vlog, '['..modname..'] '..'Mob entity exist')
-- print(dump(data))
-- Set owner
-- TODO: check that node is the correct node
local player_name = player:get_player_name()
-- Set node meta
local meta = minetest.get_meta(pos)
local owner_name = data.owner or player_name
meta:set_string("owner", owner_name)
-- Set mob properties
-- print(dump(self))
if data.nametag then
mob:set_nametag_attributes({
color = data.nametag_color or 'green',
text = data.nametag,
})
end
mob:set_properties({
infotext = data.infotext or nil,
owner = owner_name,
textures = data.textures or self.textures,
infotext = data.infotext or self.infotext,
wield_item = data.wield_item or self.wield_item,
visual_size = data.visual_size or self.visual_size,
})
self._mobname = data.nametag or nil
self._owner = owner_name
self._spawner_pos = pos
data.obj = mob
-- Register to global table
set_mob_data(pos,data)
end
mobs.npcs.update_cmob_data = function(pos)
minetest.log(vlog, '['..modname..'] '..'Updating mob data from current properties at '..minetest.pos_to_string(pos))
local data = get_mob_data(pos)
if data and data.obj then
minetest.log(vlog, '['..modname..'] '..'Mob data exist')
local self = data.obj:get_luaentity()
-- If self is nil, the mob isn't there anymore...
if not self then return false end
minetest.log(vlog, '['..modname..'] '..'Mob entity too')
local prop = data.obj:get_properties() or {}
-- print(dump(prop))
data.nametag = prop.nametag or nil
data.nametag_color = prop.nametag_color or 'green'
data.owner = prop.owner
data.textures = prop.textures or self.textures
data.infotext = prop.infotext or nil
data.spawner_pos = pos
data.wield_item = prop.wield_item or nil
data.visual_size = prop.visual_size or nil
end
set_mob_data(pos,data)
return data
end
mobs.npcs.add_cmob = function(pos, player, _)
-- Place mob
local above = { x=pos.x, y=pos.y+1, z=pos.z }
local mob = minetest.add_entity(above, modname..':'..mob_name,minetest.write_json({_spawner_pos = pos}))
mobs.npcs.update_cmob_properties(pos, player, mob)
mobs.npcs.update_cmob_data(pos)
-- Get Data
--~ local data = {}
--~ data.nametag = meta:get_string('npc_nametag')
--~ data.nametag_color = meta:get_string('npc_nametag_color')
-- Apply it to the mob
--~ local self = mob:get_luaentity()
--~ mob:set_properties({
--~ owner = owner,
--~ _spawner_pos = pos,
--~ })
--~ if data.nametag then
--~ if not data.nametag_color then data.nametag_color = 'green' end
--~ mob:set_nametag_attributes({
--~ color = data.nametag_color,
--~ text = data.nametag,
--~ })
--~ end
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)
-- 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
end
--~ mob_def.on_spawn = function(self,pos)
--~ local data =
--~ end
mobs:register_mob(mob_id, mob_def)
-- This one doesn't spawn naturally, instead it spawn
minetest.register_node(spawner_id, {
description = 'Place this to spawn a configurable npc',
drawtype = "nodebox",
tiles = {"default_stone_block.png"},
paramtype = "light",
paramtype2 = "facedir",
is_ground_content = false,
groups = {oddly_breakable_by_hand = 2},
sounds = default.node_sound_stone_defaults(),
node_box = {
type = "fixed",
fixed = {-0.5, -0.48, -0.5, 0.5, -0.5, 0.5},
},
on_construct = function(pos)
-- minetest.get_node_timer(pos):start(20)
local meta = minetest.get_meta(pos)
-- meta:set_string("infotext", "Chest")
local inv = meta:get_inventory()
inv:set_size("main", 8*3)
end,
after_place_node = mobs.npcs.add_cmob,
--~ after_dig_node = function(pos, node, metadata, digger)
--~ mobs.npcs.remove_custom_mob(pos, placer)
--~ end,
can_dig = function(pos,player)
local meta = minetest.get_meta(pos);
local inv = meta:get_inventory()
return inv:is_empty("main") and
default.can_interact_with_node(player, pos)
end,
on_rightclick = function(pos, node, clicker, itemstack, pointed_thing)
-- --
-- Check that the npc is still there
-- --
local data = mobs.npcs.update_cmob_data(pos)
local meta = minetest.get_meta(pos)
local owner = meta:get_string('owner')
-- Re-call the after_place_node function if needed
if not ( data and data.obj ) then
-- Get infos about the owner
local powner = minetest.get_player_by_name(owner)
if not powner then powner = clicker end
-- Call the function
--~ local spw_init = minetest.registered_nodes[node.name].after_place_node
--~ if spw_init and player then
--~ spw_init(pos, player, itemstack)
--~ end
mobs.npcs.add_cmob(pos, powner, itemstack)
end
-- --
-- Stop there if not allowed to interact
-- --
if not default.can_interact_with_node(clicker, pos) then
return itemstack
end
-- Show customisation form
-- minetest.show_formspec(playername, formname, formspec)
local tab = 1
if data and data.last_tab then
tab = data.last_tab
end
minetest.after(0.2,
minetest.show_formspec,
clicker:get_player_name(),
modname..':'..mob_name..'_form0'..tab,
get_npc_formspec(pos,tab))
end,
-- on_receive_fields = function(pos, formname, fields, sender)
-- end
})
-- Register egg
mobs:register_egg(mob_id, "npc", "character_lambda_inv.png", 0)
--~ mobs:doc_identifier_compat(mob_id, longdesc, usagehelp)
mobs:alias_mob("mobs:"..mob_name, mob_id) -- compatibility
local on_receive_fields = function(player, formname, fields)
local playername = player:get_player_name()
if not string.match(formname, modname..':'..mob_name..'_form0%d') then
return false
end
-- print('-------- FIELDS ------------')
-- print(dump(fields))
local pos
if fields.key then
pos = minetest.string_to_pos(fields.key)
end
if not pos then return false end
local data = get_mob_data(pos) or {}
-- Update data without overrinding it
if fields.texture then data.textures = { fields.texture } end
if fields.action_id then
-- if fields.action_id and (( not data.action ) or ( fields.action_id ~= data.action.id )) then
data.action = data.action or {}
data.action.id = fields.action_id
data.action.message = fields.action_message or data.action.message
-- data.action = mobs.npcs.interactions[fields.action_id]
-- for k,v in pairs(fields) do
-- for l in string.gmatch(k,"action_(%w+)") do
-- print(dump('action :'))
-- print(dump(l))
-- data.action[l] = v
-- end
-- end
end
local fk = {
'nametag','nametag_color','allowed','infotext','wield_item',
}
for _,v in ipairs(fk) do
if fields[v] then data[v] = fields[v] end
end
data.last_tab = fields.tab or data.last_tab
-- data.visual_size = {x = 1, y = 1.1}
-- print('-------- DATA ------------')
-- print(dump(data))
set_mob_data(pos,data)
mobs.npcs.update_cmob_properties(pos,player, data.obj)
local tb = data.last_tab
if ( fields.tab or fields.action_id ) and not fields.quit then
minetest.after(0.2,
minetest.show_formspec,
playername,
modname..':'..mob_name..'_form0'..tb,
get_npc_formspec(pos,tb))
end
end
minetest.register_on_player_receive_fields(on_receive_fields)

61
npc_lambda.lua Normal file
View File

@ -0,0 +1,61 @@
-- Basic NPC
--
-- Intllib
local S = mobs.intllib
-- Mod related infos
local modname = minetest.get_current_modname()
local modpath = minetest.get_modpath(modname)
mob_name="npc"
--
-- Specific mob informations
--
local mob_id = modname..':'..mob_name
-- Get base defintion
local mob_def = mobs.npcs.base_def
-- Get textures
local textures = mobs.npcs.get_textures_array("character_lambda_",modname)
if textures then mob_def.textures = textures end
-- Set specific interactions (say something)
-- TO DO
-- Basic npc don't not fight
mob_def.runaway = true
--
-- Register Npc
--
mobs:register_mob(mob_id, mob_def)
--
-- Register Spawn condition and egg
--
-- Get base definition for spawn conditions
local mob_spawndef = mobs.npcs.base_spawndef
-- Add specific infos
mob_spawndef.name = mob_id
--~ mob_spawndef.node = {"group:soil"}
-- Regiser spawn
mobs:spawn(mob_spawndef)
-- Register egg
mobs:register_egg(mob_id, "npc", "character_lambda_inv.png", 0)
--~ mobs:doc_identifier_compat(mob_id, longdesc, usagehelp)
mobs:alias_mob("mobs:"..mob_name, mob_id) -- compatibility

17
readme.md Normal file
View File

@ -0,0 +1,17 @@
--
**Warning** : This mod is not finished and should be considered very unstable
also it will have to be renamed to avec confusion with other mods
This is adds some npcs for mobs_redo
Lots of textures, code and ideas are taken from various other mods
(Tell me if someone who should be credited isn't)
--
-[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 )
-[ ] Zombie workers
___________________________________________________

15
settingtypes.txt Normal file
View File

@ -0,0 +1,15 @@
# This file contains settings of mobs_bundle that can be changed in
# minetest.conf
# General
# Birds
mobs.animal_birds.enable_gulls bool true
mobs.animal_birds.enable_large_birds bool false
mobs.animal_birds.enable_large_birds bool true
# Fish
mobs.animal_fish.sprite_version bool false
# Zombies
mobs.monster_zombie.enable_mini_zombies bool false

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 320 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 903 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 842 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 342 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 643 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 415 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 876 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 374 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 758 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 879 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 362 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 951 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 313 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 271 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 223 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 329 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1021 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 329 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 555 B

BIN
textures/creatures_egg_sheep.png Executable file

Binary file not shown.

After

Width:  |  Height:  |  Size: 675 B

BIN
textures/mobs_npcs_icon_chat.png Executable file

Binary file not shown.

After

Width:  |  Height:  |  Size: 551 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 236 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 675 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 313 B

BIN
textures/mobs_npcs_icon_giver.png Executable file

Binary file not shown.

After

Width:  |  Height:  |  Size: 675 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 675 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 141 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 675 B

Binary file not shown.

Binary file not shown.

After

Width:  |  Height:  |  Size: 992 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 332 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 258 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1001 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 667 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 753 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 709 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.1 KiB

Some files were not shown because too many files have changed in this diff Show More