implemented effects that are block- and crafting-related

This commit is contained in:
Sokomine 2021-06-12 00:17:51 +02:00
parent d21141ec1f
commit 003b322af3
2 changed files with 135 additions and 14 deletions

View File

@ -126,7 +126,7 @@ yl_speak_up.show_effect = function(r)
return "ERROR: r.r_pos is "..minetest.serialize(r.r_pos)
elseif(r.r_value == "place") then
return "Place \""..tostring(r.r_node).."\" with param2: "..tostring(r.r_param2)..
" at "..minetest.pos_to_string(p.p_pos).."."
" at "..minetest.pos_to_string(r.r_pos).."."
elseif(r.r_value == "dig") then
return "Dig the block at "..minetest.pos_to_string(r.r_pos).."."
elseif(r.r_value == "punch") then
@ -260,13 +260,13 @@ yl_speak_up.execute_effect = function(player, n_id, o_id, r)
end
local item = ItemStack(r.r_value)
if(not(minetest.registered_items[item:get_name()])) then
yl_speak_up.debug_msg(player, n_id, o_id, tostring(r_id).." "..
yl_speak_up.debug_msg(player, n_id, o_id, tostring(r.r_id).." "..
"give_item: "..tostring(item:get_name()).." unknown.")
return false
end
local r = player:get_inventory():add_item("main", item)
if(not(r)) then
yl_speak_up.debug_msg(player, n_id, o_id, tostring(r_id).." "..
yl_speak_up.debug_msg(player, n_id, o_id, tostring(r.r_id).." "..
"give_item: "..tostring(item:get_name()).." failed.")
return false
end
@ -278,13 +278,13 @@ yl_speak_up.execute_effect = function(player, n_id, o_id, r)
end
local item = ItemStack(r.r_value)
if(not(minetest.registered_items[item:get_name()])) then
yl_speak_up.debug_msg(player, n_id, o_id, tostring(r_id).." "..
yl_speak_up.debug_msg(player, n_id, o_id, tostring(r.r_id).." "..
"take_item: "..tostring(item:get_name()).." unknown.")
return false
end
local r = player:get_inventory():remove_item("main", item)
if(not(r)) then
yl_speak_up.debug_msg(player, n_id, o_id, tostring(r_id).." "..
yl_speak_up.debug_msg(player, n_id, o_id, tostring(r.r_id).." "..
"take_item: "..tostring(item:get_name()).." failed.")
return false
end
@ -363,9 +363,104 @@ yl_speak_up.execute_effect = function(player, n_id, o_id, r)
-- TODO: implement effect "state"
-- "a block somewhere" -- 3
elseif(r.r_type == "block") then
-- TODO: implement effect "block"
-- TODO: not sure if punching a block (as an npc) is possible without bugs
-- TODO: not sure if right-clicking a block (as an npc) is possible without bugs
-- is the position given correctly?
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
yl_speak_up.debug_msg(player, n_id, o_id, tostring(r.r_id).." "..
"block: Missing or wrong position given: "..
minetest.serialize(r.r_pos)..".")
return false
end
-- check protection (relevant for some actions): the *owner*
-- of the NPC needs to be able to build there
local is_protected = minetest.is_protected(r.r_pos, yl_speak_up.npc_owner[ n_id ] or "?")
-- human readable position; mostly for debug messages
local pos_str = tostring(minetest.pos_to_string(r.r_pos))
-- the area has to be loaded
local node = minetest.get_node_or_nil(r.r_pos)
if(not(node)) then
yl_speak_up.debug_msg(player, n_id, o_id, tostring(r.r_id).." "..
"block: Not loaded (nil) at pos "..pos_str..".")
return false
end
-- "If there is air: Place a block so that it looks like now.", -- 2
if(r.r_value and r.r_value == "place") then
if(is_protected) then
yl_speak_up.debug_msg(player, n_id, o_id, tostring(r.r_id).." "..
"block: place - "..pos_str.." is protected. Can't place.")
return false
end
if(not(node) or not(node.name) or node.name ~= "air") then
yl_speak_up.debug_msg(player, n_id, o_id, tostring(r.r_id).." "..
"block: place - there is already a block at pos "..pos_str..
". Can't place.")
return false
end
-- does the NPC have this block in his inventory? else he can't place it
local npc_inv = minetest.get_inventory({type="detached",
name="yl_speak_up_npc_"..tostring(n_id)})
if(not(npc_inv:contains_item("npc_main", tostring(r.r_node)))) then
yl_speak_up.debug_msg(player, n_id, o_id, tostring(r.r_id).." "..
"block: place - NPC does not have "..tostring(r.r_node)..
" in his inventory for placing at "..pos_str..".")
return false
end
-- TODO: switch to minetest.place_node in the future once the bug with placing
-- on an air node is fixed
-- actually place the node
minetest.set_node(r.r_pos, {name=r.r_node, param2=r.r_param2})
-- consume the item
npc_inv:remove_item("npc_main", tostring(r.r_node))
return true
-- "If there is a block: Dig it.", -- 3
elseif(r.r_value and r.r_value == "dig") then
if(is_protected) then
yl_speak_up.debug_msg(player, n_id, o_id, tostring(r.r_id).." "..
"block: place - "..pos_str.." is protected. Can't place.")
return false
end
if(not(node) or not(node.name) or node.name == "air"
or not(minetest.registered_items[ node.name ])) then
yl_speak_up.debug_msg(player, n_id, o_id, tostring(r.r_id).." "..
"block: dig - there is no block at pos "..pos_str..".")
return false
end
-- TODO: use dig_node once that can put the items in the inventory
-- local dig_res = minetest.dig_node(r.r_pos)
if(minetest.registered_items[ node.name ].can_dig
and not(minetest.registered_items[ node.name ].can_dig(r.r_pos))) then
yl_speak_up.debug_msg(player, n_id, o_id, tostring(r.r_id).." "..
"block: dig - Can't dig block at pos "..pos_str..".")
return false
end
-- actually remove the node
minetest.remove_node(r.r_pos)
-- get node drops when digging without a tool
local drop_list = minetest.get_node_drops(node, nil)
local npc_inv = minetest.get_inventory({type="detached",
name="yl_speak_up_npc_"..tostring(n_id)})
-- put the drops into the inventory of the NPC
for i, d in ipairs(drop_list) do
local rest = npc_inv:add_item("npc_main", ItemStack(d))
if(rest and not(rest:is_empty()) and rest:get_count()>0) then
yl_speak_up.debug_msg(player, n_id, o_id, tostring(r.r_id)..
" block: dig (info) - NPC had no room for item drop "..
rest:to_string().." from digging at "..pos_str..".")
end
end
yl_speak_up.debug_msg(player, n_id, o_id, tostring(r.r_id).." "..
"block: dig - success: "..tostring(dig_res).." at pos "..pos_str..".")
return true
-- "Punch the block.", -- 4
elseif(r.r_value and r.r_value == "punch") then
-- even air can be punched - even if that is pretty pointless
minetest.punch_node(r.r_pos)
return true
-- "Right-click the block.", -- 5
elseif(r.r_value and r.r_value == "right-click") then
-- TODO: not sure if right-clicking a block (as an npc) is possible without bugs
end
return false
-- ""NPC crafts soemthing", -- 4
elseif(r.r_type == "craft") then
if(not(r.r_craft_grid) or not(r.r_value)) then
@ -396,7 +491,7 @@ yl_speak_up.execute_effect = function(player, n_id, o_id, r)
name="yl_speak_up_npc_"..tostring(n_id)})
for k, v in pairs(sum_up) do
if(not(npc_inv:contains_item("npc_main", k.." "..v))) then
yl_speak_up.debug_msg(player, n_id, o_id, tostring(r_id).." "..
yl_speak_up.debug_msg(player, n_id, o_id, tostring(r.r_id).." "..
"Crafting failed: NPC does not have "..tostring(k.." "..v))
return false
end
@ -406,7 +501,7 @@ yl_speak_up.execute_effect = function(player, n_id, o_id, r)
input.width = 3
local output, decremented_input = minetest.get_craft_result(input)
if(output.item:is_empty()) then
yl_speak_up.debug_msg(player, n_id, o_id, tostring(r_id).." "..
yl_speak_up.debug_msg(player, n_id, o_id, tostring(r.r_id).." "..
"Crafting failed: No output for that recipe.")
return false
end
@ -414,13 +509,35 @@ yl_speak_up.execute_effect = function(player, n_id, o_id, r)
local expected_stack = ItemStack(r.r_value)
if(output.item:get_name() ~= expected_stack:get_name()
or output.item:get_count() ~= expected_stack:get_count()) then
yl_speak_up.debug_msg(player, n_id, o_id, tostring(r_id).." "..
yl_speak_up.debug_msg(player, n_id, o_id, tostring(r.r_id).." "..
"Crafting failed: Diffrent output: "..tostring(output.item:to_string()))
return false
end
-- TODO: actually consume the items required, return the ones in decremented_input
yl_speak_up.debug_msg(player, n_id, o_id, tostring(r_id).." "..
yl_speak_up.debug_msg(player, n_id, o_id, tostring(r.r_id).." "..
"Great: Crafting is possible!")
-- actually consume the items required, return the ones in decremented_input
for i, v in ipairs(r.r_craft_grid) do
if(v and v ~= "") then
npc_inv:remove_item("npc_main", ItemStack(v))
end
end
-- add the craft result
if(not(npc_inv:room_for_item("npc_main", output.item))) then
yl_speak_up.debug_msg(player, n_id, o_id, tostring(r.r_id).." "..
"No room for craft result "..output.item:to_string())
end
npc_inv:add_item("npc_main", output.item)
-- add the decremented_inputs
for k,v in pairs(decremented_input.items) do
if(k and not(v:is_empty())) then
if(not(npc_inv:room_for_item("npc_main", v))) then
yl_speak_up.debug_msg(player, n_id, o_id, tostring(r.r_id).." "..
"No room for craft decr. input "..v:to_string())
end
-- actually give the decremented input to the NPC
npc_inv:add_item("npc_main", v)
end
end
return true
-- "send a chat message to all players", -- 6
elseif(r.r_type == "chat_all") then

View File

@ -309,7 +309,11 @@ yl_speak_up.input_fs_edit_option_related = function(player, formname, fields,
-- for "node_is_air", there is no need to store node name and parameter
if(v[ id_prefix.."value" ]
and (v[ id_prefix.."value" ] == "node_is_like"
or v[ id_prefix.."value" ] == "node_is_diffrent_from")) then
or v[ id_prefix.."value" ] == "node_is_diffrent_from")
or v[ id_prefix.."value" ] == "place"
or v[ id_prefix.."value" ] == "dig"
or v[ id_prefix.."value" ] == "punch"
or v[ id_prefix.."value" ] == "right-click") then
v[ id_prefix.."node" ] = data.node_data.name
v[ id_prefix.."param2" ] = data.node_data.param2
end