implemented some of the effects

This commit is contained in:
Sokomine 2021-06-10 23:15:28 +02:00
parent 773be49a4e
commit b684ec3307
2 changed files with 139 additions and 0 deletions

View File

@ -29,6 +29,10 @@ There are two ways:
NPC you want to change. This is much more powerful. Lua code can be NPC you want to change. This is much more powerful. Lua code can be
entered and later executed by the NPC. entered and later executed by the NPC.
Hint: The command "/npc_talk_debug <npc_id>" allows you to get debug
information regarding preconditions and effects. You can turn it
off with "/npc_talk_debug off". The NPC ID can be seen in the
setup dialog for preconditions and effects.
The privs The privs
========= =========

View File

@ -27,6 +27,9 @@
-- on_failure: -- on_failure:
-- r_value alternate target dialog if the action failed -- r_value alternate target dialog if the action failed
-- --
-- chat_all:
-- r_value chat message sent to all players
--
-- Unlike in preconditions, trade (the trade action already happened) and -- Unlike in preconditions, trade (the trade action already happened) and
-- inventory actions are not supported as effects. -- inventory actions are not supported as effects.
-- --
@ -152,6 +155,138 @@ yl_speak_up.show_effect = function(r)
end end
-- executes an effect/result r for the player and npc n_id;
-- returns true on success (relevant for on_failure)
-- TODO: in edit mode, nothing gets executed except perhaps dialog
yl_speak_up.execute_effect = function(player, n_id, o_id, r)
if(not(r.r_type) or r.r_type == "") then
-- nothing to do
return true
elseif(r.r_type == "auto" or r.r_type == "trade") then
-- these effects don't do anything
return true
elseif(r.r_type == "dialog") then
-- TODO: how to handle target dialog?
return true
elseif(r.r_type == "function") then
return yl_speak_up.eval_and_execute_function(player, r, "r_")
elseif(r.r_type == "give_item") then
if(not(v.r_value)) then
return false
end
local item = ItemStack(v.r_value)
if(not(minetest.registered_items[item:get_name()])) then
yl_speak_up.debug_msg(player, n_id, o_id, tostring(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).." "..
"give_item: "..tostring(item:get_name()).." failed.")
return false
end
return true
elseif(r.r_type == "take_item") then
if(not(v.r_value)) then
return false
end
local item = ItemStack(v.r_value)
if(not(minetest.registered_items[item:get_name()])) then
yl_speak_up.debug_msg(player, n_id, o_id, tostring(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).." "..
"take_item: "..tostring(item:get_name()).." failed.")
return false
end
return true
elseif(r.r_type == "move") then
-- TODO: copy/adjust effect "move"
-- "an internal state (i.e. of a quest)", -- 2
elseif(r.r_type == "state") then
-- TODO: implement effect "state"
-- "a block somewhere" -- 3
elseif(r.r_type == "block") then
-- TODO: implement effect "block"
-- ""NPC crafts soemthing", -- 4
elseif(r.r_type == "craft") then
if(not(r.r_craft_grid) or not(r.r_value)) then
return false
end
local input = {}
input.items = {}
-- multiple slots in the craft grid may contain the same item
local sum_up = {}
for i, v in ipairs(r.r_craft_grid) do
if(v and v ~= "") then
local stack = ItemStack(v)
-- store this for later crafting
input.items[ i ] = stack
local name = stack:get_name()
if(sum_up[ name ]) then
sum_up[ name ] = sum_up[ name ] + stack:get_count()
else
sum_up[ name ] = stack:get_count()
end
else
-- empty itemstack in this slot
input.items[ i ] = ItemStack("")
end
end
-- does the NPC have all these items in his inventory?
local npc_inv = minetest.get_inventory({type="detached",
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).." "..
"Crafting failed: NPC does not have "..tostring(k.." "..v))
return false
end
end
-- do these input items form a valid craft recipe?
input.method = "normal" -- normal crafting; no cooking or fuel or the like
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).." "..
"Crafting failed: No output for that recipe.")
return false
end
-- the craft receipe may have changed in the meantime and yield a diffrent result
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).." "..
"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).." "..
"Great: Crafting is possible!")
return true
-- "go to other dialog if the action (i.e. trade) failed", -- 5
elseif(r.r_type == "on_failure") then
-- TODO: implement effect on_failure
-- "send a chat message to all players", -- 6
elseif(r.r_type == "chat_all") then
local pname = player:get_player_name()
local dialog = yl_speak_up.speak_to[pname].dialog
local text = r.r_value
-- replace $NPC_NAME$, $OWNER_NAME$, $PLAYER_NAME$ etc.
text = yl_speak_up.replace_vars_in_text(text, dialog, pname)
minetest.chat_send_all(text)
-- sending a chat message always counts as successful
return true
end
-- fallback: unkown type
return false
end
-- these are only wrapper functions for those in fs_edit_general.lua -- these are only wrapper functions for those in fs_edit_general.lua
yl_speak_up.input_fs_edit_effects = function(player, formname, fields) yl_speak_up.input_fs_edit_effects = function(player, formname, fields)