|
|
@@ -75,19 +75,52 @@ npc = minetest.registered_entities['mobs_npc:npc']
|
|
|
|
|
|
npc.on_rightclick = function(self, clicker)
|
|
|
|
|
|
+ local item = clicker:get_wielded_item()
|
|
|
+ local itemname = item:get_name()
|
|
|
+
|
|
|
-- Tame (and heal)
|
|
|
if mobs:feed_tame(self, clicker, 8, true, true) then return end
|
|
|
|
|
|
- --TODO: Heal with food groups
|
|
|
- -- food_bread = heals 5
|
|
|
- -- food_meat = heals 6
|
|
|
- -- food_egg_fried = heals 2
|
|
|
- -- food_apple = heals 2
|
|
|
+ --
|
|
|
+ -- Heal with food groups items
|
|
|
+ --TODO: There must be an easier way to know if items are food...
|
|
|
+ --TODO: This whole block should have it's own function. mobs_npc.npc_feed ?
|
|
|
+ local prop = self.object:get_properties()
|
|
|
+ -- Starts by checking if full health
|
|
|
+ if self.health < prop.hp_max then
|
|
|
+ local name = clicker:get_player_name()
|
|
|
+ -- food_bread = heals 5
|
|
|
+ local food = {
|
|
|
+ bread = 5,
|
|
|
+ meat = 6,
|
|
|
+ apple = 2,
|
|
|
+ egg_fried = 2,
|
|
|
+ mushroom = 1,
|
|
|
+ }
|
|
|
+ local itemdef = minetest.registered_items[itemname]
|
|
|
+ if itemdef and itemdef.groups then
|
|
|
+ for k,v in pairs(food) do
|
|
|
+ if itemdef.groups['food_'..k] then
|
|
|
+ -- increase health
|
|
|
+ self.health = math.min(self.health + v, prop.hp_max)
|
|
|
+ self.object:set_hp(self.health)
|
|
|
+ -- if not in creative then take item
|
|
|
+ if not mobs.is_creative(name) then
|
|
|
+ item:take_item()
|
|
|
+ clicker:set_wielded_item(item)
|
|
|
+ end
|
|
|
+ return
|
|
|
+ -- break
|
|
|
+ end
|
|
|
+ end
|
|
|
+ end
|
|
|
+ end
|
|
|
|
|
|
--
|
|
|
-- Capture
|
|
|
if mobs:capture_mob(self, clicker, nil, 5, 80, false, nil) then return end
|
|
|
- --TODO: Maybe don't continue if clicker is holding capture item but capture failed
|
|
|
+ -- Don't continue if clicker is holding capture item but capture failed
|
|
|
+ if itemname == "mobs:lasso" or itemname == "mobs:net" then return end
|
|
|
--
|
|
|
-- Protect
|
|
|
if mobs:protect(self, clicker) then return end
|
|
|
@@ -97,13 +130,13 @@ npc.on_rightclick = function(self, clicker)
|
|
|
if mobs_npc.drop_trade(self, clicker, mobs_npc.drop_trade_item, self.npc_drops or mobs_npc.npc_drops) then
|
|
|
return
|
|
|
end
|
|
|
+
|
|
|
--
|
|
|
-- Config
|
|
|
- local item = clicker:get_wielded_item()
|
|
|
- local name = clicker:get_player_name()
|
|
|
-- owner can right-click with stick to show control formspec
|
|
|
-- Use mobs_npc.config_item
|
|
|
--TODO: This whole block should have it's own function. mobs_npc.npc_control_form ?
|
|
|
+ local name = clicker:get_player_name()
|
|
|
if item:get_name() == mobs_npc.config_item and (self.owner == name or
|
|
|
minetest.check_player_privs(clicker, {protection_bypass = true}) )then
|
|
|
local formspec = mobs_npc.get_controls_formspec(name, self)
|
|
|
@@ -120,6 +153,7 @@ npc.on_rightclick = function(self, clicker)
|
|
|
|
|
|
-- show simple dialog if enabled or idle chatter
|
|
|
-- Why isn't mobs_npc.useDialogs a boolean ?
|
|
|
+ --TODO: check if item is lasso or net
|
|
|
--TODO: This whole block should have it's own function. mobs_npc.npc_dialog ?
|
|
|
if mobs_npc.get_npc_attention(self, clicker) then
|
|
|
if mobs_npc.useDialogs == "Y" and self.dialog then
|
|
|
@@ -132,55 +166,93 @@ npc.on_rightclick = function(self, clicker)
|
|
|
|
|
|
end
|
|
|
|
|
|
---TODO: save npc self into a protected block (bones ?).
|
|
|
---TODO: let player restore npc by clicking npc bones with a special item
|
|
|
- -- if self.owner and self.owner ~= "" then
|
|
|
- -- local node
|
|
|
- -- for i = 1, 5 do
|
|
|
- -- node = minetest.get_node(pos)
|
|
|
- -- if node.name ~= 'air' then pos.y = pos.y + 1
|
|
|
- -- else break
|
|
|
- -- end
|
|
|
- -- end
|
|
|
- -- minetest.set_node(pos, {name = "bones:bones"})
|
|
|
- -- local meta = minetest.get_meta(pos)
|
|
|
- -- meta:set_string("infotext", S("Npc's old bones (owned by @1)", self.owner))
|
|
|
- -- meta:set_string("owner", self.owner)
|
|
|
- -- --TODO:
|
|
|
- -- --- -- Save inventory
|
|
|
- -- --- -- Save job
|
|
|
- -- --- -- Save texture
|
|
|
- -- --- -- Save dialog
|
|
|
- -- --- -- ... can we save the whole serialized self ?
|
|
|
- -- end
|
|
|
|
|
|
|
|
|
- --- add special mob egg with all mob information
|
|
|
- -- local new_stack = ItemStack(self.name .. "_set")
|
|
|
-
|
|
|
- -- local data_str = minetest.serialize(clean_staticdata(self))
|
|
|
-
|
|
|
- -- new_stack:set_metadata(data_str)
|
|
|
-
|
|
|
- -- local inv = clicker:get_inventory()
|
|
|
+--
|
|
|
+-- Save npc self into a protected block upon death.
|
|
|
+--
|
|
|
|
|
|
- -- if inv:room_for_item("main", new_stack) then
|
|
|
- -- inv:add_item("main", new_stack)
|
|
|
- -- else
|
|
|
- -- minetest.add_item(clicker:get_pos(), new_stack)
|
|
|
- -- end
|
|
|
+--TODO: let player restore npc by clicking npc bones with a special item
|
|
|
+local npc_bones = modname .. ":npc_bones"
|
|
|
+minetest.register_node(npc_bones, {
|
|
|
+ description = S("Npc Bones"),
|
|
|
+ tiles = {"mobs_npc_workers_bones.png"},
|
|
|
+ is_ground_content = false,
|
|
|
+ groups = {not_in_creative_inventory = 1},
|
|
|
+ drawtype = "nodebox",
|
|
|
+ paramtype = "light",
|
|
|
+ node_box = {
|
|
|
+ type = "fixed",
|
|
|
+ fixed = {
|
|
|
+ {-0.3750, -0.5000, -0.3750, 0.3750, 0.2500, 0.3750}
|
|
|
+ }
|
|
|
+ },
|
|
|
+ on_punch = function(pos, node, puncher, pointed_thing)
|
|
|
+
|
|
|
+ -- Get node meta
|
|
|
+ local meta = minetest.get_meta(pos)
|
|
|
+
|
|
|
+ --TODO: Do we want to check if puncher is owner ? Maybe not
|
|
|
+ --TODO: Do we want the puncher to hold a specific item ? Probably
|
|
|
+
|
|
|
+ -- Get mob data
|
|
|
+ local mobname = meta:get('mobname')
|
|
|
+ if not mobname then return end -- sanity check
|
|
|
+ local data = meta:get('data')
|
|
|
+
|
|
|
+ -- Remove the old node
|
|
|
+ minetest.set_node(pos, {name = 'air'})
|
|
|
+
|
|
|
+ -- Re-spawn the npc
|
|
|
+ pos.y = pos.y + 1
|
|
|
+ local smob = minetest.add_entity(pos, mobname, data)
|
|
|
+
|
|
|
+ -- Get npc self
|
|
|
+ local ent = smob and smob:get_luaentity()
|
|
|
+ if not ent then return end -- sanity check
|
|
|
+
|
|
|
+ -- Mob was dead... set new health value
|
|
|
+ local prop = ent.object:get_properties()
|
|
|
+ local health = math.random(prop.hp_min or 15, prop.hp_max or 20)
|
|
|
+ ent.health = health
|
|
|
+ ent.old_health = health
|
|
|
+ end
|
|
|
+})
|
|
|
|
|
|
- -- self:mob_sound("default_place_node_hard")
|
|
|
|
|
|
- -- remove_mob(self, true)
|
|
|
+npc.on_die = function(self,pos)
|
|
|
|
|
|
+ -- Don't bother for wild NPCs
|
|
|
+ if not ( self.owner and self.owner ~= "" ) then return end
|
|
|
|
|
|
+ -- Remove the cause of death
|
|
|
+ if self.cause_of_death then
|
|
|
+ -- local puncher = self.cause_of_death.puncher
|
|
|
+ -- if puncher and type(puncher) == "userdata" then
|
|
|
+ self.cause_of_death = nil
|
|
|
+ -- end
|
|
|
+ end
|
|
|
|
|
|
+ -- Find ground
|
|
|
+ local node
|
|
|
+ pos.y = pos.y - 1
|
|
|
+ for i = 1, 6 do
|
|
|
+ node = minetest.get_node(pos)
|
|
|
+ if node.name ~= 'air' then pos.y = pos.y + 1
|
|
|
+ else break
|
|
|
+ end
|
|
|
+ end
|
|
|
+ -- Set bones
|
|
|
+ minetest.set_node(pos, {name = npc_bones})
|
|
|
+
|
|
|
+ -- Set node meta
|
|
|
+ local meta = minetest.get_meta(pos)
|
|
|
+ meta:set_string("infotext", S("Npc's old bones (owned by @1)", self.owner) ..
|
|
|
+ S("\nPunch to respawn"))
|
|
|
+ meta:set_string("owner", self.owner)
|
|
|
+ meta:set_string("data", self:get_staticdata())
|
|
|
+ meta:set_string("mobname", self.name)
|
|
|
+end
|
|
|
|
|
|
npc.on_spawn = function(self)
|
|
|
--TODO: look for preset jobs and pick one at random
|
|
|
@@ -216,8 +288,8 @@ end
|
|
|
|
|
|
if minetest.get_modpath('thelowerroad') then
|
|
|
|
|
|
- local axisx = tonumber(minetest.setting_get("thelowerroad.axisx")) or 100
|
|
|
- local sinfactor = tonumber(minetest.setting_get("thelowerroad.sinfactor")) or 62
|
|
|
+ local axisx = tonumber(minetest.settings:get("thelowerroad.axisx")) or 100
|
|
|
+ local sinfactor = tonumber(minetest.settings:get("thelowerroad.sinfactor")) or 62
|
|
|
local xmin = axisx - sinfactor
|
|
|
local xmax = axisx + sinfactor
|
|
|
|
|
|
@@ -313,6 +385,7 @@ function mobs_npc.default_npc_def()
|
|
|
on_rightclick = npc.on_rightclick,
|
|
|
on_spawn = npc.on_spawn,
|
|
|
do_custom = npc.do_custom,
|
|
|
+ on_die = npc.on_die,
|
|
|
}
|
|
|
|
|
|
end
|