forked from Sokomine/yl_speak_up
implemented put_into_block_inv and take_from_block_inv
This commit is contained in:
parent
09521172ac
commit
e61baf7ab5
10
README.md
10
README.md
@ -214,3 +214,13 @@ but offer the same options/answers as the dialog normally would.
|
||||
Alternate texts can be converted to normal dialogs, and normal dialogs can
|
||||
vice versa be converted to alternate texts if only one option/answer points
|
||||
to them.
|
||||
|
||||
Configuration
|
||||
=============
|
||||
Please make sure that the tables
|
||||
yl_speak_up.blacklist_effect_on_block_<type> with <type>:
|
||||
<interact|place|dig|punch|right_click|put|take>
|
||||
contain all the blocks which do not allow the NPCs this kind of
|
||||
interaction.
|
||||
You may i.e. set the put and take tables for blocks that do extensive
|
||||
checks on the player object which the NPC simply can't provide.
|
||||
|
15
config.lua
15
config.lua
@ -1,3 +1,15 @@
|
||||
-- Note: This config file is not intended to be edited directly.
|
||||
-- Like all my mods, it foremost provides an interface/api so
|
||||
-- that another mod (i.e. a server specific one written by you)
|
||||
-- can call functions here and do the settings.
|
||||
--
|
||||
-- That way you can update this mod easily and keep your settings
|
||||
-- in a seperate mod and even override functions there if you
|
||||
-- want.
|
||||
--
|
||||
-- So please use a seperate config mod!
|
||||
|
||||
|
||||
-- Do the NPCs talk right after they spawned?
|
||||
|
||||
yl_speak_up.talk_after_spawn = true
|
||||
@ -56,6 +68,9 @@ yl_speak_up.blacklist_effect_on_block_place = {}
|
||||
yl_speak_up.blacklist_effect_on_block_dig = {}
|
||||
yl_speak_up.blacklist_effect_on_block_punch = {}
|
||||
yl_speak_up.blacklist_effect_on_block_right_click = {}
|
||||
-- taking something out of the inventory of a block or putting something in
|
||||
yl_speak_up.blacklist_effect_on_block_put = {}
|
||||
yl_speak_up.blacklist_effect_on_block_take = {}
|
||||
|
||||
-- If some items are for some reasons not at all acceptable as quest items,
|
||||
-- blacklist them here. The data structure is the same as for the tables above.
|
||||
|
@ -131,6 +131,8 @@ yl_speak_up.check_blacklisted = function(how, node_name, node_there)
|
||||
or (how == "dig" and yl_speak_up.blacklist_effect_on_block_dig[ node_there ])
|
||||
or (how == "punch" and yl_speak_up.blacklist_effect_on_block_punch[ node_there ])
|
||||
or (how == "right-click" and yl_speak_up.blacklist_effect_on_block_right_click[ node_there])
|
||||
or (how == "put" and yl_speak_up.blacklist_effect_on_block_right_click[ node_there])
|
||||
or (how == "take" and yl_speak_up.blacklist_effect_on_block_right_click[ node_there])
|
||||
end
|
||||
|
||||
-- returns a human-readable text as description of the effects
|
||||
@ -347,7 +349,129 @@ yl_speak_up.execute_effect = function(player, n_id, o_id, r)
|
||||
return true
|
||||
elseif(r.r_type == "put_into_block_inv"
|
||||
or r.r_type == "take_from_block_inv") then
|
||||
-- TODO: implement
|
||||
-- get the inventory of the block
|
||||
if(not(r.r_pos) or type(r.r_pos) ~= "table"
|
||||
or not(r.r_pos.x) or not(r.r_pos.y) or not(r.r_pos.z)) then
|
||||
-- position not found?
|
||||
yl_speak_up.debug_msg(player, n_id, o_id, tostring(r.r_id).." "..
|
||||
r.r_type..": No or incorrect position given: "..
|
||||
minetest.serialize(r.rp_pos)..".")
|
||||
return false
|
||||
end
|
||||
local meta = minetest.get_meta(r.r_pos)
|
||||
if(not(meta)) then
|
||||
yl_speak_up.debug_msg(player, n_id, o_id, tostring(r.r_id).." "..
|
||||
r.r_type..": Failed to get metadata at "..
|
||||
minetest.serialize(r.rp_pos)..".")
|
||||
return false
|
||||
end
|
||||
local inv = meta:get_inventory()
|
||||
if(not(inv)) then
|
||||
yl_speak_up.debug_msg(player, n_id, o_id, tostring(r.r_id).." "..
|
||||
r.r_type..": Failed to get inventory at "..
|
||||
minetest.serialize(r.rp_pos)..".")
|
||||
return false
|
||||
end
|
||||
local inv_name = r.r_inv_list_name
|
||||
-- get the inventory of the npc
|
||||
local npc_inv = minetest.get_inventory({type="detached",
|
||||
name="yl_speak_up_npc_"..tostring(n_id)})
|
||||
local npc_inv_name = "npc_main"
|
||||
-- for easier checking
|
||||
local how_to_interact = "take"
|
||||
if(r.r_type and r.r_type == "put_into_block_inv") then
|
||||
how_to_interact = "put"
|
||||
end
|
||||
local stack = ItemStack(r.r_itemstack)
|
||||
-- is there enough room for the item?
|
||||
if(how_to_interact == "put"
|
||||
and not(inv:room_for_item(inv_name, stack))) then
|
||||
yl_speak_up.debug_msg(player, n_id, o_id, tostring(r.r_id).." "..
|
||||
r.r_type..": No room for \""..
|
||||
minetest.serialize(r.r_itemstack).."\""..
|
||||
" in node at "..
|
||||
minetest.serialize(r.r_pos)..", inv list \""..
|
||||
minetest.serialize(inv_name).."\".")
|
||||
return false
|
||||
elseif(how_to_interact == "take"
|
||||
and not(npc_inv:room_for_item("npc_main", stack))) then
|
||||
yl_speak_up.debug_msg(player, n_id, o_id, tostring(r.r_id).." "..
|
||||
r.r_type..": NPC has no room for \""..
|
||||
minetest.serialize(r.r_itemstack).."\".")
|
||||
return false
|
||||
end
|
||||
-- does the item exist?
|
||||
if(how_to_interact == "put"
|
||||
and not(npc_inv:contains_item(npc_inv_name, stack, false))) then
|
||||
yl_speak_up.debug_msg(player, n_id, o_id, tostring(r.r_id).." "..
|
||||
r.r_type..": NPC does not have \""..
|
||||
minetest.serialize(r.r_itemstack).."\".")
|
||||
return false
|
||||
elseif(how_to_interact == "take"
|
||||
and not(inv:contains_item(inv_name, stack, false))) then
|
||||
yl_speak_up.debug_msg(player, n_id, o_id, tostring(r.r_id).." "..
|
||||
r.r_type..": Block at "..minetest.serialize(r.r_pos)..
|
||||
" does not contain \""..tostring(r.r_itemstack).."\" in list \""..
|
||||
tostring(r.r_inv_list).."\".")
|
||||
return false
|
||||
end
|
||||
-- check the blacklist
|
||||
local node = minetest.get_node(r.r_pos)
|
||||
if(not(node) or not(node.name)) then
|
||||
yl_speak_up.debug_msg(player, n_id, o_id, tostring(r.r_id).." "..
|
||||
r.r_type..": No node found at "..minetest.serialize(r.r_pos)..".")
|
||||
return false
|
||||
end
|
||||
-- do not interact with nodes on the blacklist
|
||||
if(yl_speak_up.check_blacklisted(how_to_interact, node.name, node.name)) then
|
||||
yl_speak_up.debug_msg(player, n_id, o_id, tostring(r.r_id).." "..
|
||||
r.r_type..": Blocks of type \""..tostring(node.name).."\" do not allow "..
|
||||
"interaction of type \""..tostring(r.r_value).."\" for NPC.")
|
||||
return false
|
||||
end
|
||||
-- construct a fake player
|
||||
local owner_name = yl_speak_up.npc_owner[ n_id ]
|
||||
if(not(owner_name) or owner_name == "") then
|
||||
yl_speak_up.debug_msg(player, n_id, o_id, tostring(r.r_id).." "..
|
||||
r.r_type..": NPC does not have an owner. Aborting.")
|
||||
return false
|
||||
end
|
||||
-- act in the name of the owner when accessing inventories
|
||||
local fake_player = {
|
||||
get_player_name = function() return owner_name end,
|
||||
is_player = function() return true end,
|
||||
is_fake_player = true,
|
||||
get_wielded_item = function(self, item)
|
||||
if(self._inventory and def.wield_list) then
|
||||
return self._inventory:get_stack(def.wield_list, self._wield_index)
|
||||
end
|
||||
return ItemStack(self._wielded_item)
|
||||
end,
|
||||
}
|
||||
-- TODO: get the fake player from pipeworks?
|
||||
local def = minetest.registered_nodes[ node.name ]
|
||||
if(def and def[ "allow_metadata_inventory_"..how_to_interact ]) then
|
||||
local res = def[ "allow_metadata_inventory_"..how_to_interact ](
|
||||
r.r_pos, inv_name, 1,
|
||||
ItemStack(r.r_itemstack),
|
||||
fake_player)
|
||||
if(not(res) or res < ItemStack(r.r_itemstack):get_count()) then
|
||||
yl_speak_up.debug_msg(player, n_id, o_id, tostring(r.r_id).." "..
|
||||
r.r_type..": allow_metadata_inventory_"..tostring(how_to_interact)..
|
||||
" forbits interaction at "..minetest.serialize(r.r_pos)..".")
|
||||
return false
|
||||
end
|
||||
end
|
||||
-- all ok so far; we can proceed
|
||||
if(how_to_interact == "put") then
|
||||
local r1 = npc_inv:remove_item(npc_inv_name, stack)
|
||||
local r2 = inv:add_item(inv_name, r1)
|
||||
return true
|
||||
elseif(how_to_interact == "take") then
|
||||
local r1 = inv:remove_item(inv_name, stack)
|
||||
local r2 = npc_inv:add_item(npc_inv_name, r1)
|
||||
return true
|
||||
end
|
||||
return false
|
||||
elseif(r.r_type == "dialog"
|
||||
or r.r_type == "on_failure") then
|
||||
|
Loading…
Reference in New Issue
Block a user