diff --git a/modpol_minetest/api.lua b/modpol_minetest/api.lua index 800b8c5..b469924 100644 --- a/modpol_minetest/api.lua +++ b/modpol_minetest/api.lua @@ -10,31 +10,27 @@ local localdir = minetest.get_modpath("modpol") .. "/modpol_minetest" --Users -dofile (localdir .. "/overrides/users/users.lua") +dofile (localdir .. "/overrides/users.lua") --orgs ---dofile (localdir .. "/overrides/orgs/orgs.lua") +--dofile (localdir .. "/overrides/orgs.lua") --interactions -dofile (localdir .. "/overrides/interactions/interactions.lua") - --- messaging functions --- dofile (localdir .. "/overrides/processes/processes.lua") - +dofile (localdir .. "/overrides/interactions.lua") -- =================================================================== -- Minetest Chatcommands -- =================================================================== -dofile (localdir .. "/chatcommands/chatcommands.lua") +dofile (localdir .. "/chatcommands.lua") -- =================================================================== -- Minetest Specific code -- =================================================================== - --- orgs --- =================== - -dofile (localdir .. "/orgs/instance.lua") --add players to the instance when they join. \ No newline at end of file +--add members to the instance, if they are not already there. +minetest.register_on_joinplayer(function(player) + local p_name = player:get_player_name() + modpol.instance:add_member(p_name) +end) diff --git a/modpol_minetest/chatcommands/chatcommands.lua b/modpol_minetest/chatcommands/chatcommands.lua deleted file mode 100644 index 33c0ca6..0000000 --- a/modpol_minetest/chatcommands/chatcommands.lua +++ /dev/null @@ -1,108 +0,0 @@ --- =================================================================== --- Minetest commands --- =================================================================== - -command_list = {} -- user-facing table of commands - -local chat_table -- MT chat command definitions table -local regchat -- Chat-command registration function - -regchat = minetest.register_chatcommand - -regchat = function(name, command_table) - minetest.register_chatcommand(name, command_table) - table.insert(command_list, name) -end - --- =================================================================== --- /modpol --- Presents a menu of options to users -regchat( - "modpol", { - privs = {}, - func = function(user) - modpol.interactions.dashboard(user) - end, -}) - --- =================================================================== --- /reset --- For testing only --- Clears the system and recreates instance with all players -regchat( - "reset", { - privs = {}, - func = function(user) - modpol.orgs.reset(); - return true, "Reset orgs" - end, -}) - - - --- =================================================================== --- /addorg --- This code defines a chat command which creates a new --- "org". Presently, the command makes the user the sole member of the --- "org". - -regchat( - "addorg", { - privs = {} , - func = function (user, param) - local success, message = modpol.instance:add_org (param) - return true, message - end -}) - --- =================================================================== --- /listorgs --- In Minetest mode, this code defines a chat command which lists --- existing "orgs". --- The list shows one "org" per line in the following format: --- org_name (member, member, ...) - -regchat( - "listorgs", { - privs = {} , - func = function (user, param) - return true, "Orgs: " .. - table.concat(modpol.orgs.list_all(), ", ") - end -}) - --- =================================================================== --- /listplayers -regchat( - "listplayers", { - privs = {}, - func = function(user) - local result = table.concat(modpol.list_users(),", ") - return true, "All players: " .. result - end, -}) - --- =================================================================== --- /joinorg -regchat( - "joinorg", { - privs = {}, - func = function(user, param) - local org = modpol.orgs.get_org(param) - local success, result = org:add_member(user) - return true, result - end, -}) - - --- =================================================================== --- /pollself [question] --- asks the user a question specified in param -regchat( - "pollself", { - privs = {}, - func = function(user, param) - modpol.interactions.binary_poll_user(user, param) - return true, result - end, -}) diff --git a/modpol_minetest/orgs/instance.lua b/modpol_minetest/orgs/instance.lua deleted file mode 100644 index 667ad64..0000000 --- a/modpol_minetest/orgs/instance.lua +++ /dev/null @@ -1,6 +0,0 @@ ---add members to the instance, if they are not already there. - -minetest.register_on_joinplayer(function(player) - local p_name = player:get_player_name() - modpol.instance:add_member(p_name) -end) diff --git a/modpol_minetest/overrides/interactions/interactions.lua b/modpol_minetest/overrides/interactions/interactions.lua deleted file mode 100644 index 5057730..0000000 --- a/modpol_minetest/overrides/interactions/interactions.lua +++ /dev/null @@ -1,487 +0,0 @@ --- INTERACTIONS.LUA (for Minetest) - --- CONTEXTUAL STUFF --- ================ - --- _contexts to enable passing across formspecs --- https://rubenwardy.com/minetest_modding_book/en/players/formspecs.html#contexts - -local _contexts = {} -local function get_context(name) - local context = _contexts[name] or {} - _contexts[name] = context - return context -end -minetest.register_on_leaveplayer(function(player) - _contexts[player:get_player_name()] = nil -end) - --- UTILITIES --- ========= - --- Function: formspec_list --- for use generating option lists in formspecs from tables --- input: table of strings --- output: a formspec-ready list of the strings -local function formspec_list(array) - local escaped = {} - if not array then - return "" - end - for i = 1, #array do - escaped[i] = minetest.formspec_escape(array[i]) - end - return table.concat(escaped,",") -end - --- DASHBOARDS --- ========== - --- Function: modpol.interactions.dashboard(user) --- Params: user (string) --- Q: Should this return a menu of commands relevant to the specific user? --- Output: Displays a menu of commands to the user --- TODO currently a manually curated list---needs major improvement -function modpol.interactions.dashboard(user) - -- prepare data - -- to add: nested orgs map - local all_orgs = modpol.orgs.list_all() - local user_orgs = modpol.orgs.user_orgs(user) - local all_users = modpol.list_users() - -- set up formspec - local formspec = { - "formspec_version[4]", - "size[10,8]", - "label[0.5,0.5;MODPOL DASHBOARD]", - "label[0.5,2;All orgs:]", - "dropdown[2,1.5;5,0.8;all_orgs;"..formspec_list(all_orgs)..";;]", - "label[0.5,3;Your orgs:]", - "dropdown[2,2.5;5,0.8;user_orgs;"..formspec_list(user_orgs)..";;]", - "label[0.5,4;All users:]", - "dropdown[2,3.5;5,0.8;all_users;"..formspec_list(all_users)..";;]", - "button[0.5,7;1,0.8;test_poll;Test poll]", - "button[2,7;1,0.8;add_org;Add org]", - "button[3.5,7;1.5,0.8;remove_org;Remove org]", - "button[5.5,7;1.5,0.8;reset_orgs;Reset orgs]", - "button_exit[8.5,7;1,0.8;close;Close]", - } - local formspec_string = table.concat(formspec, "") - -- present to player - minetest.show_formspec(user, "modpol:dashboard", formspec_string) -end --- receive input -minetest.register_on_player_receive_fields(function (player, formname, fields) - if formname == "modpol:dashboard" then - local pname = player:get_player_name() - if nil then - -- buttons first - elseif fields.test_poll then - -- FOR TESTING PURPOSES ONLY - modpol.interactions.text_query( - pname,"Poll question:", - function(input) - modpol.interactions.binary_poll_user( - pname, input, - function(vote) - modpol.interactions.message( - pname, pname .. " voted " .. vote) - end) - end) - elseif fields.add_org then - modpol.interactions.add_org(pname, 1) - elseif fields.remove_org then - modpol.interactions.remove_org(pname) - elseif fields.reset_orgs then - modpol.orgs.reset() - modpol.instance:add_member(pname) - modpol.interactions.dashboard(pname) - - -- Put all dropdowns at the end - elseif fields.close then - minetest.close_formspec(pname, formname) - elseif fields.all_orgs or fields.user_orgs then - local org_name = fields.all_orgs or fields.user_orgs - modpol.interactions.org_dashboard(pname, org_name) - end - end -end) - - --- Function: modpol.interactions.org_dashboard --- Params: user (string), org_name (string) --- Output: Displays a menu of org-specific commands to the user -function modpol.interactions.org_dashboard(user, org_name) - -- prepare data - local org = modpol.orgs.get_org(org_name) - if not org then return nil end - local is_member = org:has_member(user) - local membership_toggle = function() - local toggle_code = "" - if is_member then - toggle_code = toggle_code - ..minetest.formspec_escape("leave")..";" - ..minetest.formspec_escape("Leave").."]" - else - toggle_code = toggle_code - ..minetest.formspec_escape("join")..";" - ..minetest.formspec_escape("Join").."]" - end - return toggle_code - end - -- identify parent - local parent = modpol.orgs.get_org(org.parent) - if parent then parent = parent.name - else parent = "none" end - -- prepare children menu - local children = {"View..."} - for k,v in ipairs(org.children) do - local this_child = modpol.orgs.get_org(v) - table.insert(children, this_child.name) - end - -- prepare policies menu - local policies = {"View..."} - for k,v in pairs(org.policies) do - table.insert(policies, k .. ": " .. - org.policies[k].process_type) - end - table.insert(policies, "Add policy") - -- prepare processes menu - local processes = {"View..."} - for k,v in ipairs(org.processes) do - local this_request = org.requests[v.request_id] - if type(this_request) == "table" then - local active = '' - if org.pending[user] then - if org.pending[user][v.id] then - active = '*' - end - end - local req_str = "[" .. v.id .. "] " .. - active .. this_request.type - if this_request.params[1] then - req_str = req_str .. ": " .. - table.concat(this_request.params, ", ") - end - table.insert(processes, req_str) - end - end - -- set player context - local user_context = {} - user_context["current_org"] = org_name - _contexts[user] = user_context - -- set up formspec - local formspec = { - "formspec_version[4]", - "size[10,8]", - "label[0.5,0.5;Org: ".. - minetest.formspec_escape(org_name).."]", - "label[0.5,1;Parent: "..parent.."]", - "button[8.5,0.5;1,0.8;"..membership_toggle(), - "label[0.5,2;Members:]", - "dropdown[2,1.5;5,0.8;user_orgs;"..formspec_list(org.members)..";;]", - "label[0.5,3;Children:]", - "dropdown[2,2.5;5,0.8;children;"..formspec_list(children)..";;]", - "label[0.5,4;Policies:]", - "dropdown[2,3.5;5,0.8;policies;"..formspec_list(policies)..";;]", - "label[0.5,5;Processes:]", - "dropdown[2,4.5;5,0.8;processes;"..formspec_list(processes)..";;]", - "button[0.5,7;1,0.8;test_poll;Test poll]", - "button[2,7;1,0.8;add_child;Add child]", - "button[3.5,7;1.5,0.8;remove_org;Remove org]", - "button[8.5,7;1,0.8;back;Back]", - } - local formspec_string = table.concat(formspec, "") - -- present to player - minetest.show_formspec(user, "modpol:org_dashboard", formspec_string) -end --- receive input -minetest.register_on_player_receive_fields(function (player, formname, fields) - if formname == "modpol:org_dashboard" then - local pname = player:get_player_name() - local org = modpol.orgs.get_org(_contexts[pname].current_org) - if nil then - elseif fields.join then - local new_request = { - user = pname, - type = "add_member", - params = {pname} - } - org:make_request(new_request) - modpol.interactions.org_dashboard(pname,org.name) - elseif fields.leave then - org:remove_member(pname) - modpol.interactions.dashboard(pname) - elseif fields.test_poll then - modpol.interactions.binary_poll_org( - pname, org.id, - function(input) - modpol.interactions.message_org( - pname, - org.id, - "New response: " .. input) - end) - elseif fields.add_child then - modpol.interactions.text_query( - pname, "Child org name:", - function(input) - local new_request = { - user = pname, - type = "add_org", - params = {input} - } - org:make_request(new_request) - modpol.interactions.message(pname,"requested") - modpol.interactions.org_dashboard( - pname,org.name) - end) - elseif fields.remove_org then - local new_request = { - user = pname, - type = "delete", - params = {} - } - org:make_request(new_request) - modpol.interactions.org_dashboard(pname,org.name) - elseif fields.back then - modpol.interactions.dashboard(pname) - - -- Put all dropdowns at the end - elseif fields.policies - and fields.policies ~= "View..." then - local policy - if fields.policies == "Add policy" then - policy = nil - elseif fields.policies == "View..." then - return - else - policy = string.match(fields.policies,"(%w+)%:") - end - modpol.interactions.policy_dashboard( - pname, org.id, policy) - elseif fields.processes - and fields.processes ~= "View..." then - local sel = string.match(fields.processes,"%[(%d)%]") - local process = org.processes[tonumber(sel)] - if process then - process:interact(pname) - end - elseif fields.children - and fields.children ~= "View..." then - local org_name = fields.children - modpol.interactions.org_dashboard(pname, org_name) - end - end -end) - - --- Function: modpol.interactions.policy_dashboard --- input: user (string), org_id (int), policy (string) --- output: opens a dashboard for viewing/editing policy details --- TODO -function modpol.interactions.policy_dashboard( - user, org_id, policy) - modpol.interactions.message( - user, - "Not yet implemented: " .. policy) -end - - --- BASIC INTERACTION FUNCTIONS --- =========================== - --- Function: modpol.interactions.message --- input: message (string) --- output -function modpol.interactions.message(user, message) - minetest.chat_send_player(user, message) -end - --- Function: modpol.interactions.text_query --- Overrides function at modpol/interactions.lua --- input: user (string), query (string), func (function) --- func input: user input (string) --- output: Applies "func" to user input -function modpol.interactions.text_query(user, query, func) - -- set up formspec - local formspec = { - "formspec_version[4]", - "size[10,4]", - "label[0.5,1;", minetest.formspec_escape(query), "]", - "field[0.5,1.25;9,0.8;input;;]", - "button[0.5,2.5;1,0.8;yes;OK]", - } - local formspec_string = table.concat(formspec, "") - -- present to players - minetest.show_formspec(user, "modpol:text_query", formspec_string) - -- put func in _contexts - if _contexts[user] == nil then _contexts[user] = {} end - _contexts[user]["text_query_func"] = func -end --- receive fields -minetest.register_on_player_receive_fields(function (player, formname, fields) - if formname == "modpol:text_query" then - local pname = player:get_player_name() - local input = fields.input - if not input then - -- no input, do nothing - else - local func = _contexts[pname]["text_query_func"] - if func then - func(input) - else - modpol.interactions.message(pname, "text_query: " .. input) - end - end - minetest.close_formspec(pname, formname) - end -end) - --- Function: dropdown_query --- input: user (string), label (string), options (table of strings), func (function) --- func input: choice (string) --- output: calls func on user choice -function modpol.interactions.dropdown_query(user, label, options, func) - -- set up formspec - local formspec = { - "formspec_version[4]", - "size[10,4]", - "label[0.5,1;"..minetest.formspec_escape(label).."]", - "dropdown[0.5,1.25;9,0.8;input;"..formspec_list(options)..";;]", - "button[0.5,2.5;1,0.8;cancel;Cancel]", - } - local formspec_string = table.concat(formspec, "") - -- present to players - minetest.show_formspec(user, "modpol:dropdown_query", formspec_string) - -- put func in _contexts - if _contexts[user] == nil then _contexts[user] = {} end - _contexts[user]["dropdown_query_func"] = func -end --- receive fields -minetest.register_on_player_receive_fields(function (player, formname, fields) - if formname == "modpol:dropdown_query" then - local pname = player:get_player_name() - if fields.cancel ~= "cancel" then - local choice = fields.input - local func = _contexts[pname]["dropdown_query_func"] - if not choice then - -- no choice, do nothing - elseif func then - func(choice) - else - modpol.interactions.message(pname, "dropdown_query: " .. choice) - end - end - minetest.close_formspec(pname, formname) - end -end) - - --- SECONDARY INTERACTIONS --- ====================== - --- Function: modpol.binary_poll_user(user, question, function) --- Overrides function at modpol/interactions.lua --- Params: user (string), question (string), func (function) --- func input: user input (string: y/n) --- Output: Applies "func" to user input -function modpol.interactions.binary_poll_user(user, question, func) - -- set up formspec - local formspec = { - "formspec_version[4]", - "size[5,3]", - "label[0.375,0.5;",minetest.formspec_escape(question), "]", - "button[1,1.5;1,0.8;yes;Yes]", - "button[2,1.5;1,0.8;no;No]", - --TKTK can we enable text wrapping? - --TKTK we could use scroll boxes to contain the text - } - local formspec_string = table.concat(formspec, "") - if _contexts[user] == nil then _contexts[user] = {} end - _contexts[user]["binary_poll_func"] = func - -- present to player - minetest.show_formspec(user, "modpol:binary_poll_user", formspec_string) -end -minetest.register_on_player_receive_fields(function (player, formname, fields) - local pname = player:get_player_name() - -- modpol:binary_poll - if formname == "modpol:binary_poll_user" then - local vote = nil - if fields.yes then vote = fields.yes - elseif fields.no then vote = fields.no - end - if vote then - modpol.interactions.message(pname, "Responded " .. vote) - local func = _contexts[pname]["binary_poll_func"] - if func then func(vote) end - end - minetest.close_formspec(pname, formname) - end -end) - --- COMPLEX INTERACTIONS --- ==================== - --- Function: modpol.interactions.message_org --- input: initiator (string), org_id (number), message (string) --- output: broadcasts message to all org members -function modpol.interactions.message_org(initiator, org_id, message) - local org = modpol.orgs.get_org(org_id) - local users = org:list_members() - for k,v in ipairs(users) do - modpol.interactions.message(v, message) - end -end - - --- Function: modpol.interactions.binary_poll_org --- input: initator (user string), org_id (number) --- output: gets question from initiator, asks all org members, broadcasts answers --- TODO for testing. This should be implemented as a request. -function modpol.interactions.binary_poll_org(initiator, org_id, func) - local org = modpol.orgs.get_org(org_id) - local users = org:list_members() - modpol.interactions.text_query( - initiator, "Yes/no poll question:", - function(input) - for k,v in ipairs(users) do - modpol.interactions.binary_poll_user(v, input, func) - end - end) -end - --- Function: modpol.interactions.add_org --- input: initator (user string), base_org_id (ID) --- output: interaction begins --- GODMODE -function modpol.interactions.add_org(user, base_org_id) - modpol.interactions.text_query( - user,"Org name:", - function(input) - local base_org = modpol.orgs.get_org(1) - local result = base_org:add_org(input, user) - local message = input .. " created" - modpol.interactions.message(user, message) - modpol.interactions.dashboard(user) - end) -end - --- Function: modpol.interactions.remove_org --- input: initator (user string) --- output: interaction begins --- GODMODE -function modpol.interactions.remove_org(user) - -- start formspec - local orgs_list = modpol.orgs.list_all() - local label = "Choose an org to remove:" - modpol.interactions.dropdown_query( - user, label, orgs_list, - function(input) - if input then - local target_org = modpol.orgs.get_org(input) - local result = target_org:delete() - local message = input .. " deleted" - modpol.interactions.message(user, message) - end - modpol.interactions.dashboard(user) - end) -end diff --git a/modpol_minetest/overrides/users/users.lua b/modpol_minetest/overrides/users/users.lua deleted file mode 100644 index 229ebfb..0000000 --- a/modpol_minetest/overrides/users/users.lua +++ /dev/null @@ -1,21 +0,0 @@ - --- =================================================================== --- Function: modpol.list_users(org) --- Overwrites function at /users.lua --- Params: --- if nil, lists instance members; if an org name, lists its members --- Output: a table with names of players currently in the game -modpol.list_users = function(org) - local users = {} - if (org == nil) then -- no specified org; all players - for _,player in ipairs(minetest.get_connected_players()) do - local name = player:get_player_name() - table.insert(users,name) - end - else -- if an org is specified - if (modpol.orgs[org] ~= nil) then -- org exists - users = modpol.orgs[org]["members"] - end - end - return users - end \ No newline at end of file