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
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
=========

View File

@ -27,6 +27,9 @@
-- on_failure:
-- 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
-- inventory actions are not supported as effects.
--
@ -152,6 +155,138 @@ yl_speak_up.show_effect = function(r)
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
yl_speak_up.input_fs_edit_effects = function(player, formname, fields)