Compare commits

...

6 Commits

9 changed files with 120 additions and 315 deletions

View File

@ -82,6 +82,8 @@ yl_speak_up.add_to_command_help_text = yl_speak_up.add_to_command_help_text..
-- dofile(modpath .. "add_generic_dialogs.lua")
-- -- handle on_player_receive_fields and showing of formspecs
-- dofile(modpath .. "show_fs.lua")
-- handle page changes and asking for saving when in edit mode:
dofile(modpath .. "show_fs_in_edit_mode.lua")
-- -- general decoration part for main formspec, trade window etc.
-- dofile(modpath .. "api/api_decorated.lua")
-- -- the formspec and input handling for the main dialog
@ -168,7 +170,7 @@ yl_speak_up.add_to_command_help_text = yl_speak_up.add_to_command_help_text..
-- GUI for adding/editing quests
dofile(modpath .. "fs/fs_manage_quests.lua")
-- -- GUI for adding/editing quest steps for the quests
-- dofile(modpath .. "api/api_quest_steps.lua")
dofile(modpath .. "api/api_quest_steps.lua")
dofile(modpath .. "fs/fs_manage_quest_steps.lua")
-- used by the above
dofile(modpath .. "fs/fs_add_quest_steps.lua")

View File

@ -0,0 +1,98 @@
-- when in edit mode: ask for saving dialogs when needed
local old_show_fs = yl_speak_up.show_fs
yl_speak_up.show_fs = function(player, fs_name, param)
if(not(player)) then
return
end
local pname = player:get_player_name()
if(not(yl_speak_up.speak_to[pname])) then
return
end
local last_fs = yl_speak_up.speak_to[pname].last_fs
-- show the save or discard changes dialog
if(fs_name and fs_name == "save_or_discard_changes") then
yl_speak_up.show_fs_ver(pname, "yl_speak_up:save_or_discard_changes",
yl_speak_up.get_fs_save_or_discard_changes(player, param))
return
-- the player either saved or discarded; we may proceed now
elseif(fs_name and fs_name == "proceed_after_save") then
fs_name = yl_speak_up.speak_to[pname].next_fs
param = yl_speak_up.speak_to[pname].next_fs_param
yl_speak_up.speak_to[pname].next_fs = nil
yl_speak_up.speak_to[pname].next_fs_param = nil
yl_speak_up.speak_to[pname].last_fs = fs_name
yl_speak_up.speak_to[pname].last_fs_param = param
if(not(fs_name) or fs_name == "quit") then
yl_speak_up.reset_vars_for_player(pname, false)
return
end
-- the player clicked on "back" in the above dialog
elseif(fs_name and fs_name == "show_last_fs") then
-- call the last formspec again - and with the same parameters
fs_name = yl_speak_up.speak_to[pname].last_fs
param = yl_speak_up.speak_to[pname].last_fs_param
-- do we need to check if there is something that needs saving?
elseif(fs_name
-- msg is just a loop for displaying (mostly error) messages
and fs_name ~= "msg"
and fs_name ~= "player_offers_item"
-- is the player editing the NPC? that is: might there be any changes?
and (yl_speak_up.edit_mode[pname] == yl_speak_up.speak_to[pname].n_id)) then
local last_fs = yl_speak_up.speak_to[pname].last_fs
local d_id = yl_speak_up.speak_to[pname].d_id
local o_id = yl_speak_up.speak_to[pname].o_id
-- only these two formspecs need to ask specificly if the data ought to be saved
if(last_fs == "talk" or last_fs == "edit_option_dialog" or fs_name == "quit") then
local last_param = yl_speak_up.speak_to[pname].last_fs_param
local show_save_fs = false
if(not(param)) then
param = {}
end
-- set the target dialog
yl_speak_up.speak_to[pname].target_dialog = param.d_id
-- if we are switching from one dialog to another: is it the same?
if(last_fs == "talk" and fs_name == last_fs
and param and param.d_id and param.d_id ~= d_id) then
-- diffrent parameters: save (if needed)
show_save_fs = true
elseif(fs_name == "talk" and param and param.do_save) then
-- player clicked on save button
show_save_fs = true
-- leaving a dialog: save!
elseif(last_fs == "talk" and fs_name ~= last_fs) then
show_save_fs = true
-- clicking on "save" in an edit option dialog: save!
elseif(last_fs == "edit_option_dialog" and fs_name == last_fs
and param and param.caller and param.caller == "save_option") then
show_save_fs = true
-- leaving editing an option: save!
elseif(last_fs == "edit_option_dialog" and fs_name ~= last_fs) then
show_save_fs = true
-- quitting: save!
elseif(fs_name == "quit") then
yl_speak_up.speak_to[pname].target_dialog = nil
show_save_fs = true
end
-- show the save or discard dialog
if(show_save_fs) then
yl_speak_up.speak_to[pname].next_fs = fs_name
yl_speak_up.speak_to[pname].next_fs_param = param
-- check first if it's necessary to ask for save or discard
yl_speak_up.input_save_or_discard_changes(player, "", {})
return
end
end
-- store the new formspec
yl_speak_up.speak_to[pname].last_fs = fs_name
-- and its parameter
yl_speak_up.speak_to[pname].last_fs_param = param
end
-- Note: fs_name and param *may* have been changed in edit_mode by the code above
old_show_fs(player, fs_name, param)
end

View File

@ -365,7 +365,7 @@ yl_speak_up.get_fs_trade_via_buy_button_wrapper = function(player, param)
if(not(param) and yl_speak_up.speak_to[pname]) then
param = yl_speak_up.speak_to[pname].trade_id
end
return yl_speak_up.get_trade_via_buy_button(player, param)
return yl_speak_up.get_fs_trade_via_buy_button(player, param)
end

View File

@ -236,8 +236,8 @@ yl_speak_up.reload = function(modpath, log_entry)
dofile(modpath .. "quest_api.lua")
-- -- GUI for adding/editing quests
-- TODO dofile(modpath .. "fs/fs_manage_quests.lua")
-- GUI for adding/editing quest steps for the quests
dofile(modpath .. "api/api_quest_steps.lua")
-- -- GUI for adding/editing quest steps for the quests
-- TODO dofile(modpath .. "api/api_quest_steps.lua")
-- TODO dofile(modpath .. "fs/fs_manage_quest_steps.lua")
-- -- used by the above
-- TODO dofile(modpath .. "fs/fs_add_quest_steps.lua")
@ -270,18 +270,6 @@ yl_speak_up.reload = function(modpath, log_entry)
-- only gets loaded if mobs_redo (mobs) exists as mod
dofile(modpath .. "interface_mobs_api.lua")
-- TODO: just temporal here; needed for debugging
-- TODO: see dummy_functions.lua for this! TODO
-- functions and overrides for edit mode
yl_speak_up.show_precondition = function(p, pname)
return "Only implemented in editor mod."
end
yl_speak_up.show_action = function(a, pname)
return "Only implemented in editor mod."
end
yl_speak_up.show_effect = function(r, pname)
return "Only implemented in editor mod."
end
dofile(modpath .. "editor/edit_mode.lua")
-- initialize and load all registered generic dialogs

View File

@ -1,4 +1,19 @@
-- full version found in fs_edit_preconditions.lua:
yl_speak_up.show_precondition = function(p, pname)
return "P: "..minetest.serialize(p or {}).."."
end
-- full version found in fs_edit_actions.lua:
yl_speak_up.show_action = function(a)
return "A: "..minetest.serialize(a or {}).."."
end
-- full version found in fs_edit_effects.lua:
yl_speak_up.show_effect = function(r, pname)
return "E: "..minetest.serialize(r or {}).."."
end
-- store which player is monitoring the NPC (for preconditions and
-- effects)

View File

@ -1,53 +0,0 @@
## Version
Current version: 202009231753
## Dependencies
- mobs_redo
## Optional dependencies
None so far, but there is a command in another package that let's you conveniently upload new skins
## Requirements
202009231753 for 5.3.0
## License
None yet. This may change in the future. Whoever has access to the repo can use it for their own purpose. Also, licensing of third party stuff is questionable at best, so I can't offer a proper license at the moment. I'm no lawyer
## Installation
Enter your mod repository, something like /home/yourname/games/minetest/mods/
`git clone https://gitea.your-land.de/your-land/yl_speak_up.git`
Look at the config.lua and alter the values as you like.
If you wish to to upload skins or textures on runtime, you need to create a second mod in the worldfolder and have worldedit installed.
## Support mod
To create this mod you need go to your world folder
Create a folder and name it yl_npc
Inside this folder create an empty init.lua file
Create a textures folder, where all the skins go that you upload after server start
How to actually upload a skin during runtime, see usage.md/Upload a skin
## Usage
See usage.md
## Storage
Dialogs are stored in JSON inside the world directory in the folder specified in yl_speak_up.path
## Bugs, suggestions, features & bugfixes
Report bugs here: https://gitea.your-land.de/your-land/yl_speak_up/issues

View File

@ -1,164 +0,0 @@
-- Important: This is only of relevance for the Server YourLand -
-- which was running an older version of this mod and nees
-- adjustments for the newer version.
--
-- And even on that server the file was relevant only once.
-- It is mainly included here as an example of how to iterate
-- over all existing NPC (at least those who have dialogs!).
---
-- Rename this file to
-- local_server_do_on_reload.lua
-- and execute
-- /npc_talk_migrate
-- in order to automaticly add the necessary privs for all existing old NPC.
--
-- NPC dialogs are checked and reported if broken.
yl_speak_up.migration_npc_needs_priv = function(n_id, pname, counter, priv_name)
if(counter < 1) then
return
end
-- does the NPC have the priv already?
if(yl_speak_up.npc_has_priv(n_id, priv_name, nil)) then
minetest.chat_send_player(pname, " OK: "..tostring(n_id).." has priv "..priv_name)
return
end
-- grant the NPC the priv
minetest.chat_send_player(pname, " GRANTING "..tostring(n_id).." priv "..priv_name)
if(not(yl_speak_up.npc_priv_table[n_id])) then
yl_speak_up.npc_priv_table[n_id] = {}
end
yl_speak_up.npc_priv_table[n_id][priv_name] = true
end
yl_speak_up.check_one_npc_for_migration = function(dialog, pname, n_id, fname)
minetest.chat_send_player(pname, " Checking NPC "..tostring(fname)..
" \""..tostring(dialog.n_npc or "- nameless -").."\"...")
-- nothing defined yet - nothing to repair
if(not(dialog.n_dialogs)) then
minetest.chat_send_player(pname, " NPC "..tostring(n_id).." has nothing to say.")
return
end
local c_effect_exec_lua = 0
local c_effect_give_item = 0
local c_effect_take_item = 0
local c_effect_move_player = 0
local c_precon_exec_lua = 0
-- iterate over all dialogs
for d_id, d in pairs(dialog.n_dialogs) do
if(d_id and d and d.d_options) then
-- iterate over all options
for o_id, o in pairs(d.d_options) do
if(o_id and o and o.o_results) then
local has_close_formspec = false
local dialog_results = {}
-- iterate over all results
for r_id, r in pairs(o.o_results) do
if(r.r_type == "dialog") then
table.insert(dialog_results, r_id)
elseif(r.r_type == "function") then
c_effect_exec_lua = c_effect_exec_lua + 1
-- if the formspec is closed, we need to use the
-- target dialog d_end
if(string.find(r.r_value , "minetest.close_formspec")) then
has_close_formspec = true
end
elseif(r.r_type == "move") then
c_effect_move_player = c_effect_move_player + 1
elseif(r.r_type == "give_item") then
c_effect_give_item = c_effect_give_item + 1
elseif(r.r_type == "take_item") then
c_effect_take_item = c_effect_take_item + 1
end
end
if(#dialog_results>1) then
local msg = "ERROR: Dialog "..
tostring(d_id)..", option "..tostring(o_id)..
", has multiple results of type dialog: "..
minetest.serialize(dialog_results)..". Please "..
"let someone with npc_master priv fix that first!"
yl_speak_up.log_change(pname, n_id, msg, "error")
if(pname) then
minetest.chat_send_player(pname, msg)
end
-- sometimes we need d_end because minetest.close_formspec in
-- an effect of type "function" is not enough
elseif(has_close_formspec) then
local found = false
local d_old = ""
for r_id, r in pairs(o.o_results) do
if(r.r_type == "dialog" and not(found)) then
d_old = r.r_value
r.r_value = "d_end"
found = true
end
end
-- if there is no dialog option yet: create one
if(not(found)) then
local future_r_id = yl_speak_up.add_new_result(
dialog, d_id, o_id)
o.o_results[future_r_id] = {
r_id = future_r_id,
r_type = "dialog",
r_value = "d_end"}
end
if(d_old ~= "d_end") then
yl_speak_up.save_dialog(n_id, dialog)
local msg = "ERROR: Dialog "..
tostring(d_id)..", option "..tostring(o_id)..
", uses minetest.close_formspec in its "..
"lua code but "..tostring(d_old)..
" instead of d_end as target dialog. Fixing."
minetest.chat_send_player(pname, msg)
end
end
end
if(o_id and o and o.o_prerequisites) then
for p_id, p in pairs(o.o_prerequisites) do
if(p.p_type == "function") then
c_precon_exec_lua = c_precon_exec_lua + 1
end
end
end
end
end
end
yl_speak_up.migration_npc_needs_priv(n_id, pname, c_effect_exec_lua, "effect_exec_lua")
yl_speak_up.migration_npc_needs_priv(n_id, pname, c_effect_give_item, "effect_give_item")
yl_speak_up.migration_npc_needs_priv(n_id, pname, c_effect_take_item, "effect_take_item")
yl_speak_up.migration_npc_needs_priv(n_id, pname, c_effect_move_player, "effect_move_player")
yl_speak_up.migration_npc_needs_priv(n_id, pname, c_precon_exec_lua, "precon_exec_lua")
end
yl_speak_up.check_all_npc_for_migration = function(pname)
local path = yl_speak_up.worldpath..yl_speak_up.path.."/"
local file_names = minetest.get_dir_list(path, false)
minetest.chat_send_player(pname, "There are "..tostring(#file_names).." NPCs with stored dialogs "..
"in folder "..path..".")
for i, fname in ipairs(file_names) do
local file, err = io.open(path..fname, "r")
io.input(file)
local content = io.read()
local dialog = minetest.parse_json(content)
io.close(file)
if type(dialog) ~= "table" then
dialog = {}
end
yl_speak_up.check_one_npc_for_migration(dialog, pname, string.sub(fname, 0, -6), fname)
end
minetest.chat_send_player(pname, "Done with checking all NPC files for migration.")
-- store the changed privs
yl_speak_up.npc_privs_store()
return true
end
minetest.register_chatcommand( 'npc_talk_migrate', {
description = "Checks NPC from old yl_speak_up for migration to new version of the mod.",
privs = {npc_master = true},
func = function(pname, param)
return yl_speak_up.check_all_npc_for_migration(pname)
end
})

View File

@ -61,86 +61,6 @@ yl_speak_up.show_fs = function(player, fs_name, param)
return
end
local last_fs = yl_speak_up.speak_to[pname].last_fs
if(false) then
-- the player either saved or discarded; we may proceed now
elseif(fs_name and fs_name == "proceed_after_save") then
fs_name = yl_speak_up.speak_to[pname].next_fs
param = yl_speak_up.speak_to[pname].next_fs_param
yl_speak_up.speak_to[pname].next_fs = nil
yl_speak_up.speak_to[pname].next_fs_param = nil
yl_speak_up.speak_to[pname].last_fs = fs_name
yl_speak_up.speak_to[pname].last_fs_param = param
if(not(fs_name) or fs_name == "quit") then
yl_speak_up.reset_vars_for_player(pname, false)
return
end
-- the player clicked on "back" in the above dialog
elseif(fs_name and fs_name == "show_last_fs") then
-- call the last formspec again - and with the same parameters
fs_name = yl_speak_up.speak_to[pname].last_fs
param = yl_speak_up.speak_to[pname].last_fs_param
-- do we need to check if there is something that needs saving?
elseif(fs_name
-- msg is just a loop for displaying (mostly error) messages
and fs_name ~= "msg"
and fs_name ~= "player_offers_item"
-- is the player editing the NPC? that is: might there be any changes?
and yl_speak_up.edit_mode
and (yl_speak_up.edit_mode[pname] == yl_speak_up.speak_to[pname].n_id)) then
local last_fs = yl_speak_up.speak_to[pname].last_fs
local d_id = yl_speak_up.speak_to[pname].d_id
local o_id = yl_speak_up.speak_to[pname].o_id
-- only these two formspecs need to ask specificly if the data ought to be saved
if(last_fs == "talk" or last_fs == "edit_option_dialog" or fs_name == "quit") then
local last_param = yl_speak_up.speak_to[pname].last_fs_param
local show_save_fs = false
if(not(param)) then
param = {}
end
-- set the target dialog
yl_speak_up.speak_to[pname].target_dialog = param.d_id
-- if we are switching from one dialog to another: is it the same?
if(last_fs == "talk" and fs_name == last_fs
and param and param.d_id and param.d_id ~= d_id) then
-- diffrent parameters: save (if needed)
show_save_fs = true
elseif(fs_name == "talk" and param and param.do_save) then
-- player clicked on save button
show_save_fs = true
-- leaving a dialog: save!
elseif(last_fs == "talk" and fs_name ~= last_fs) then
show_save_fs = true
-- clicking on "save" in an edit option dialog: save!
elseif(last_fs == "edit_option_dialog" and fs_name == last_fs
and param and param.caller and param.caller == "save_option") then
show_save_fs = true
-- leaving editing an option: save!
elseif(last_fs == "edit_option_dialog" and fs_name ~= last_fs) then
show_save_fs = true
-- quitting: save!
elseif(fs_name == "quit") then
yl_speak_up.speak_to[pname].target_dialog = nil
show_save_fs = true
end
-- show the save or discard dialog
if(show_save_fs) then
yl_speak_up.speak_to[pname].next_fs = fs_name
yl_speak_up.speak_to[pname].next_fs_param = param
-- check first if it's necessary to ask for save or discard
yl_speak_up.input_save_or_discard_changes(player, "", {})
return
end
end
-- store the new formspec
yl_speak_up.speak_to[pname].last_fs = fs_name
-- and its parameter
yl_speak_up.speak_to[pname].last_fs_param = param
end
-- abort talk if we hit d_end
if(fs_name == "talk" and param and param.d_id and param.d_id == "d_end") then
yl_speak_up.stop_talking(pname)
@ -153,11 +73,10 @@ yl_speak_up.show_fs = function(player, fs_name, param)
fun(player, param),
yl_speak_up.registered_forms_force_fs_ver[fs_name])
return true
end
-- this is here mostly to fascilitate debugging - so that really all calls to
-- minetest.show_formspec are routed through here
if(fs_name == "msg") then
elseif(fs_name == "msg") then
if(not(param)) then
param = {}
end