Adding and fixing basic modules for renaming, removing, and adding orgs

This commit is contained in:
Nathan Schneider 2021-12-19 16:00:26 -07:00
parent d4599e9bbe
commit 53d2a25f42
15 changed files with 371 additions and 130 deletions

View File

@ -10,7 +10,9 @@ For background information, documentation, and the project roadmap, see [the wik
To use this in Minetest, simply install it in your `mods/` or `worldmods/` folder. Minetest will load `init.lua`. To use this in Minetest, simply install it in your `mods/` or `worldmods/` folder. Minetest will load `init.lua`.
In the game, open the Modular Politics interface with the command `/modpol`. In the game, open the Modular Politics dashboard with the command `/mp`.
For testing purposes, players with the `privs` privilege (generally admins) can use the `/mp` command, which resets all the orgs and opens a dashboard.
## Standalone Version on the Command Line ## Standalone Version on the Command Line

View File

@ -11,9 +11,12 @@ dofile (localdir .. "/interactions/interactions.lua")
--modules --modules
--TODO make this automatic and directory-based --TODO make this automatic and directory-based
dofile (localdir .. "/modules/add_child_org.lua") dofile (localdir .. "/modules/add_child_org_consent.lua")
dofile (localdir .. "/modules/consent.lua") dofile (localdir .. "/modules/consent.lua")
dofile (localdir .. "/modules/join_org_consent.lua") dofile (localdir .. "/modules/join_org_consent.lua")
dofile (localdir .. "/modules/leave_org.lua") dofile (localdir .. "/modules/leave_org.lua")
dofile (localdir .. "/modules/remove_child_consent.lua")
dofile (localdir .. "/modules/remove_member_consent.lua")
dofile (localdir .. "/modules/remove_org_consent.lua") dofile (localdir .. "/modules/remove_org_consent.lua")
dofile (localdir .. "/modules/remove_org.lua") dofile (localdir .. "/modules/remove_org.lua")
dofile (localdir .. "/modules/rename_org_consent.lua")

View File

@ -48,10 +48,10 @@ end
-- Function: modpol.interactions.org_dashboard -- Function: modpol.interactions.org_dashboard
-- Params: user (string), org_name (string) -- Params: user (string), org_string (string or id)
-- Output: Displays a menu of org-specific commands to the user -- Output: Displays a menu of org-specific commands to the user
function modpol.interactions.org_dashboard(user, org_name) function modpol.interactions.org_dashboard(user, org_string)
local org = modpol.orgs.get_org(org_name) local org = modpol.orgs.get_org(org_string)
if not org then return nil end if not org then return nil end
-- identify parent -- identify parent
@ -72,11 +72,13 @@ function modpol.interactions.org_dashboard(user, org_name)
-- list available modules -- list available modules
local org_modules = {} local org_modules = {}
for k,v in pairs(org.modules) do for k,v in pairs(org.modules) do
if not v.hide then
table.insert(org_modules, v.slug) table.insert(org_modules, v.slug)
end end
end
-- list pending actions -- list pending
local process_msg = #org.processes .. " total actions" local process_msg = #org.processes .. " total processes"
if org.pending[user] then if org.pending[user] then
process_msg = process_msg .. " (" .. #org.pending[user] .. " pending)" process_msg = process_msg .. " (" .. #org.pending[user] .. " pending)"
else else
@ -84,14 +86,14 @@ function modpol.interactions.org_dashboard(user, org_name)
end end
-- set up output -- set up output
print("Org: " .. org_name) print("Org: " .. org.name)
print("Parent: " .. parent) print("Parent: " .. parent)
print("Members: " .. table.concat(org.members, ", ")) print("Members: " .. table.concat(org.members, ", "))
print("Children: " .. table.concat(children, ", ")) print("Children: " .. table.concat(children, ", "))
print("Modules: " .. table.concat(org_modules, ", ")) print("Modules: " .. table.concat(org_modules, ", "))
print("Actions: " .. process_msg) print("Pending: " .. process_msg)
print() print()
print("Commands: (M)odules, (A)ctions") print("Commands: (M)odules, (P)ending")
local sel = io.read() local sel = io.read()
print() print()
@ -114,7 +116,7 @@ function modpol.interactions.org_dashboard(user, org_name)
elseif sel == 'a' or sel == 'A' then elseif sel == 'a' or sel == 'A' then
local processes = {} local processes = {}
print("All processes: (* indicates pending action)") print("All processes: (* indicates pending)")
for k,v in ipairs(org.processes) do for k,v in ipairs(org.processes) do
local active = '' local active = ''
if org.pending[user] then if org.pending[user] then
@ -135,7 +137,7 @@ function modpol.interactions.org_dashboard(user, org_name)
end end
else else
print("Command not found") print("Command not found")
modpol.interactions.org_dashboard(user, org_name) modpol.interactions.org_dashboard(user, org.name)
end end
end end

View File

@ -1,20 +1,21 @@
--- @module add_child_org --- @module add_child_org_consent
-- Adds a child org -- Adds a child org
-- Depends on `consent` -- Depends on `consent`
local add_child_org = { local add_child_org_consent = {
name = "Add child org", name = "Add child org (consent)",
slug = "add_child_org", slug = "add_child_org_consent",
desc = "Create a child org within the current one with consent" desc = "Create a child org in the current one with member consent"
} }
add_child_org.data = { add_child_org_consent.data = {
child_name = "" child_name = "",
result = nil
} }
add_child_org.config = { add_child_org_consent.config = {
} }
-- @function initiate -- @function initiate
function add_child_org:initiate(config, result) function add_child_org_consent:initiate(result)
modpol.interactions.text_query( modpol.interactions.text_query(
self.initiator,"Child org name: ", self.initiator,"Child org name: ",
function(input) function(input)
@ -22,8 +23,21 @@ function add_child_org:initiate(config, result)
modpol.interactions.message( modpol.interactions.message(
self.initiator, self.initiator,
"No name entered for child org") "No name entered for child org")
modpol.interactions.org_dashboard(
self.initiator, self.org.name)
self.org:delete_process(self.id) self.org:delete_process(self.id)
return end if result then result() end
return
elseif modpol.orgs.get_org(input) then
modpol.interactions.message(
self.initiator,
"Org name already in use")
modpol.interactions.org_dashboard(
self.initiator, self.org.name)
self.org:delete_process(self.id)
if result then result() end
return
end
self.data.child_name = input self.data.child_name = input
modpol.interactions.message( modpol.interactions.message(
self.initiator, self.initiator,
@ -47,14 +61,15 @@ function add_child_org:initiate(config, result)
) )
end end
function add_child_org:create_child_org() function add_child_org_consent:create_child_org()
self.org:add_org(self.data.child_name, self.initiator) self.org:add_org(self.data.child_name, self.initiator)
modpol.interactions.message_org( modpol.interactions.message_org(
self.initiator, self.initiator,
self.org.name, self.org.name,
"Child org created: "..self.data.child_name) "Child org created: "..self.data.child_name)
if self.data.result then self.data.result() end
self.org:delete_process(self.id) self.org:delete_process(self.id)
end end
--- (Required) Add to module table --- (Required) Add to module table
modpol.modules.add_child_org = add_child_org modpol.modules.add_child_org_consent = add_child_org_consent

View File

@ -2,9 +2,10 @@
-- A utility module for checking consent -- A utility module for checking consent
local consent = { local consent = {
name = "Consent", name = "Consent process utility",
slug = "consent", slug = "consent",
desc = "Other modules can use to implement consent based decision making", desc = "A module other modules use for consent decisions",
hide = true
} }
consent.data = { consent.data = {
@ -46,6 +47,8 @@ function consent:callback(member)
self.org:wipe_pending_actions(self.id) self.org:wipe_pending_actions(self.id)
self.org:delete_process(self.id) self.org:delete_process(self.id)
end end
modpol.interactions.org_dashboard(
member, self.org.name)
end end
) )
end end

View File

@ -3,18 +3,27 @@
-- Depends on the Consent module. -- Depends on the Consent module.
local join_org_consent = { local join_org_consent = {
name = "Join this org", name = "Join this org (consent)",
slug = "join_org_consent", slug = "join_org_consent",
desc = "Adds member with consent of all members." desc = "Adds member with consent of all members"
} }
join_org_consent.data = { join_org_consent.data = {
result = nil
} }
join_org_consent.config = { join_org_consent.config = {
} }
function join_org_consent:initiate(result) function join_org_consent:initiate(result)
if self.org:has_member(self.initiator) then
modpol.interactions.message(
self.initiator,
"You are already a member of this org")
if result then result() end
self.org:delete_process(self.id)
else
self.data.result = result
self.org:call_module( self.org:call_module(
"consent", "consent",
self.initiator, self.initiator,
@ -26,12 +35,17 @@ function join_org_consent:initiate(result)
self:complete() self:complete()
end end
) )
if result then result() end end
end end
function join_org_consent:complete() function join_org_consent:complete()
self.org:add_member(self.initiator) self.org:add_member(self.initiator)
print("Added " .. self.initiator .. " to the org.") modpol.interactions.message_org(
self.initiator,self.org.name,
"Consent reached: " .. self.initiator ..
" joined org " .. self.org.name)
if self.data.result then self.data.result() end
self.org:delete_process(self.id)
end end
modpol.modules.join_org_consent = join_org_consent modpol.modules.join_org_consent = join_org_consent

View File

@ -4,7 +4,7 @@
local leave_org = { local leave_org = {
name = "Leave org", name = "Leave org",
slug = "leave_org", slug = "leave_org",
desc = "Leave this org" desc = "Remove yourself from the current org"
} }
leave_org.data = { leave_org.data = {
@ -32,6 +32,7 @@ function leave_org:initiate(result)
"You have left org " .. self.org.name) "You have left org " .. self.org.name)
end end
if result then result() end if result then result() end
self.org:delete_process(self.id)
end end
--- (Required) Add to module table --- (Required) Add to module table

View File

@ -0,0 +1,71 @@
--- Remove child (consent)
-- A simple module that calls a consent process on an org to remove its child
-- Depends on the Consent module.
local remove_child_consent = {
name = "Remove child (consent)",
slug = "remove_child_consent",
desc = "Removes a child org if all members of this org consent."
}
remove_child_consent.data = {
result = nil,
child_to_remove = nil
}
remove_child_consent.config = {
}
function remove_child_consent:initiate(result)
local children = {}
for i,v in ipairs(self.org.children) do
local child = modpol.orgs.get_org(v)
if child then table.insert(children, child.name) end
end
-- Abort if no child orgs
if #children == 0 then
modpol.interactions.message(
self.initiator,
"Org has no children")
if result then result() end
self.org:delete_process(self.id)
else
self.data.result = result
modpol.interactions.dropdown_query(
self.initiator,
"Which child of org "..self.org.name..
" do you want to remove?",
children,
function(input)
self.data.child_to_remove = modpol.orgs.get_org(input)
self.org:call_module(
"consent",
self.initiator,
{
prompt = "Remove child org "..input.."?",
votes_required = #self.org.members
},
function()
self:complete()
end)
modpol.interactions.org_dashboard(
self.initiator, self.org.name)
end)
end
end
function remove_child_consent:complete()
modpol.interactions.message_org(
self.initiator, self.data.child_to_remove.id,
"Removing org " .. self.data.child_to_remove.name ..
" by parent org consent")
modpol.interactions.message_org(
self.initiator, self.org.id,
"Consent reached: removing org " ..
self.data.child_to_remove.name)
self.data.child_to_remove:delete()
if self.data.result then self.data.result() end
self.org:delete_process(self.id)
end
modpol.modules.remove_child_consent = remove_child_consent

View File

@ -0,0 +1,64 @@
--- remove_member_consent
-- @module remove_member_consent
local remove_member_consent = {
name = "Remove a member (consent)",
slug = "remove_member_consent",
desc = "Removes org member with consent of other members"
}
remove_member_consent.data = {
member_to_remove = "",
result = nil
}
remove_member_consent.config = {
}
function remove_member_consent:initiate(result)
-- Abort if in root org
if self.org == modpol.instance then
modpol.interactions.message(
self.initiator,
"Members cannot be removed from the root org")
if result then result() end
self.org:delete_process(self.id)
else -- proceed if not root
self.data.result = result
modpol.interactions.dropdown_query(
self.initiator,
"Which member of org "..self.org.name..
" do you want to remove?",
self.org.members,
function(input)
self.data.member_to_remove = input
self.org:call_module(
"consent",
self.initiator,
{
prompt = "Remove "..input..
" from org "..self.org.name.."?",
votes_required = #self.org.members - 1
},
function()
self:complete()
end)
modpol.interactions.org_dashboard(
self.initiator, self.org.name)
end)
end
end
function remove_member_consent:complete()
modpol.interactions.message_org(
self.initiator, self.org.id,
"Consent reached: removing "..
self.data.member_to_remove..
" from org "..self.org.name)
self.org:remove_member(self.data.member_to_remove)
self.org:delete_process(self.id)
if self.data.result then self.data.result() end
end
--- (Required) Add to module table
modpol.modules.remove_member_consent = remove_member_consent

View File

@ -18,7 +18,7 @@ function remove_org:initiate(result)
if self.org == modpol.instance then if self.org == modpol.instance then
modpol.interactions.message( modpol.interactions.message(
self.initiator, self.initiator,
"You cannot remove the root org") "Cannot remove the root org")
else else
modpol.interactions.message_org( modpol.interactions.message_org(
self.initiator,self.org.id, self.initiator,self.org.id,

View File

@ -3,18 +3,27 @@
-- Depends on the Consent module. -- Depends on the Consent module.
local remove_org_consent = { local remove_org_consent = {
name = "Remove this org", name = "Remove this org (consent)",
slug = "remove_org_consent", slug = "remove_org_consent",
desc = "Removes an org if all members consent." desc = "Removes an org if all members consent."
} }
remove_org_consent.data = { remove_org_consent.data = {
result = nil
} }
remove_org_consent.config = { remove_org_consent.config = {
} }
function remove_org_consent:initiate(result) function remove_org_consent:initiate(result)
if self.org == modpol.instance then
modpol.interactions.message(
self.initiator,
"Cannot remove root org")
if result then result() end
self.org:delete_process(self.id)
else
self.data.result = result
self.org:call_module( self.org:call_module(
"consent", "consent",
self.initiator, self.initiator,
@ -28,13 +37,15 @@ function remove_org_consent:initiate(result)
) )
modpol.interactions.org_dashboard( modpol.interactions.org_dashboard(
self.initiator, self.org.name) self.initiator, self.org.name)
if result then result() end end
end end
function remove_org_consent:complete() function remove_org_consent:complete()
modpol.interactions.message_org( modpol.interactions.message_org(
self.initiator, self.org.id, self.initiator, self.org.id,
"Removing org: " .. self.org.name) "Consent reached: removing org " .. self.org.name)
if self.data.result then self.data.result() end
self.org:delete_process(self.id)
self.org:delete() self.org:delete()
end end

View File

@ -0,0 +1,77 @@
--- Rename org (consent)
-- A simple module that calls a consent process on an org to rename it.
-- Depends on the Consent module.
local rename_org_consent = {
name = "Rename this org (consent)",
slug = "rename_org_consent",
desc = "Renames an org if all members consent."
}
rename_org_consent.data = {
result = nil,
new_name = nil
}
rename_org_consent.config = {
}
function rename_org_consent:initiate(result)
modpol.interactions.text_query(
self.initiator,"New org name: ",
function(input)
if input == "" then
modpol.interactions.message(
self.initiator,
"No name entered for child org")
modpol.interactions.org_dashboard(
self.initiator, self.org.name)
self.org:delete_process(self.id)
if result then result() end
return
elseif modpol.orgs.get_org(input) then
modpol.interactions.message(
self.initiator,
"Org name already in use")
modpol.interactions.org_dashboard(
self.initiator, self.org.name)
self.org:delete_process(self.id)
if result then result() end
return
end
self.data.new_name = input
modpol.interactions.message(
self.initiator,
"Proposed to change name of org " ..
self.org.name .. " to " .. input)
-- initiate consent process
self.org:call_module(
"consent",
self.initiator,
{
prompt = "Change name of org " ..
self.org.name .. " to " .. input .. "?",
votes_required = #self.org.members
},
function()
self:complete()
end
)
modpol.interactions.org_dashboard(
self.initiator, self.org.name)
end
)
end
function rename_org_consent:complete()
modpol.interactions.message_org(
self.initiator,
self.org.name,
"Changing name of org " .. self.org.name ..
" to " .. self.data.new_name)
self.org.name = self.data.new_name
if self.data.result then self.data.result() end
self.org:delete_process(self.id)
end
modpol.modules.rename_org_consent = rename_org_consent

View File

@ -1,20 +1,22 @@
--- module_template --- change_modules
-- @module module_template -- @module change_modules
--- (Required): data table containing name and description of the module --- (Required): data table containing name and description of the module
-- @field name "Human-readable name" -- @field name "Human-readable name"
-- @field slug "Same as module class name" -- @field slug "Same as module class name"
-- @field desc "Description of the module" -- @field desc "Description of the module"
local module_template = { -- @field hide "Whether this is a hidden utility module"
local change_modules = {
name = "Module Human-Readable Name", name = "Module Human-Readable Name",
slug = "template", slug = "template",
desc = "Description of the module" desc = "Description of the module",
hide = false;
} }
--- (Required) Data for module --- (Required) Data for module
-- Variables that module uses during the course of a process -- Variables that module uses during the course of a process
-- Can be blank -- Can be blank
module_template.data = { change_modules.data = {
} }
--- (Required): config for module --- (Required): config for module
@ -25,7 +27,7 @@ module_template.data = {
-- Default values set in config can be overridden -- Default values set in config can be overridden
-- @field field_1 ex: votes_required, default = 5 -- @field field_1 ex: votes_required, default = 5
-- @field field_2 ex: voting_type, default = "majority" -- @field field_2 ex: voting_type, default = "majority"
module_template.config = { change_modules.config = {
field_1 = 5 field_1 = 5
field_2 = "majority" field_2 = "majority"
} }
@ -37,12 +39,16 @@ module_template.config = {
-- <li><code>self.id</code> (the process id of the module instance)</li> -- <li><code>self.id</code> (the process id of the module instance)</li>
-- @param result (optional) Callback if this module is embedded in other modules -- @param result (optional) Callback if this module is embedded in other modules
-- @function initiate -- @function initiate
function module_template:initiate(result) function change_modules:initiate(result)
-- call interaction functions here! -- call interaction functions here!
-- call result function -- concluding functions:
-- call these wherever process might end;
-- may need to put result in self.data.result
-- if process ends in another function
if result then result() end if result then result() end
self.org:delete_process(self.id)
end end
--- (Required) Add to module table --- (Required) Add to module table
modpol.modules.module_template = module_template modpol.modules.change_modules = change_modules

View File

@ -15,10 +15,10 @@ regchat = function(name, command_table)
end end
-- =================================================================== -- ===================================================================
-- /modpol -- /mp
-- Presents a menu of options to users -- Presents a menu of options to users
regchat( regchat(
"modpol", { "mp", {
privs = {}, privs = {},
func = function(user) func = function(user)
modpol.interactions.dashboard(user) modpol.interactions.dashboard(user)
@ -26,14 +26,17 @@ regchat(
}) })
-- =================================================================== -- ===================================================================
-- /reset -- /mptest
-- For testing only -- For testing only, accessible to admin users
-- Clears the system and recreates instance with all players -- Clears the system and recreates instance with all players
-- opens dashboard too for fun.
regchat( regchat(
"reset", { "mptest", {
privs = {}, privs = {privs=true},
func = function(user) func = function(user)
modpol.orgs.reset(); modpol.orgs.reset()
modpol.instance:add_member(user)
modpol.interactions.dashboard(user)
return true, "Reset orgs" return true, "Reset orgs"
end, end,
}) })
@ -71,38 +74,3 @@ regchat(
end 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,
})

View File

@ -51,15 +51,15 @@ function modpol.interactions.dashboard(user)
-- set up formspec -- set up formspec
local formspec = { local formspec = {
"formspec_version[4]", "formspec_version[4]",
"size[10,8]", "size[10,6]",
"label[0.5,0.5;MODPOL DASHBOARD]", "label[0.5,0.5;M O D U L A R P O L I T I C S]",
"label[0.5,2;All orgs:]", "label[0.5,2;All orgs:]",
"dropdown[2,1.5;5,0.8;all_orgs;"..formspec_list(all_orgs)..";;]", "dropdown[2,1.5;5,0.8;all_orgs;"..formspec_list(all_orgs)..";;]",
"label[0.5,3;Your orgs:]", "label[0.5,3;Your orgs:]",
"dropdown[2,2.5;5,0.8;user_orgs;"..formspec_list(user_orgs)..";;]", "dropdown[2,2.5;5,0.8;user_orgs;"..formspec_list(user_orgs)..";;]",
"label[0.5,4;All users:]", "label[0.5,4;All users:]",
"dropdown[2,3.5;5,0.8;all_users;"..formspec_list(all_users)..";;]", "dropdown[2,3.5;5,0.8;all_users;"..formspec_list(all_users)..";;]",
"button_exit[8.5,7;1,0.8;close;Close]", "button_exit[8.5,5;1,0.8;close;Close]",
} }
local formspec_string = table.concat(formspec, "") local formspec_string = table.concat(formspec, "")
-- present to player -- present to player
@ -85,11 +85,11 @@ end)
-- Function: modpol.interactions.org_dashboard -- Function: modpol.interactions.org_dashboard
-- Params: user (string), org_name (string) -- Params: user (string), org_string (string or num)
-- Output: Displays a menu of org-specific commands to the user -- Output: Displays a menu of org-specific commands to the user
function modpol.interactions.org_dashboard(user, org_name) function modpol.interactions.org_dashboard(user, org_string)
-- prepare data -- prepare data
local org = modpol.orgs.get_org(org_name) local org = modpol.orgs.get_org(org_string)
if not org then return nil end if not org then return nil end
local function membership_toggle(org_display) local function membership_toggle(org_display)
@ -98,9 +98,8 @@ function modpol.interactions.org_dashboard(user, org_name)
if current_org:has_member(user) then if current_org:has_member(user) then
return " (member)" return " (member)"
end end
else
return ""
end end
return ""
end end
-- identify parent -- identify parent
@ -119,32 +118,36 @@ function modpol.interactions.org_dashboard(user, org_name)
local modules = {"View..."} local modules = {"View..."}
if org.modules then if org.modules then
for k,v in pairs(org.modules) do for k,v in pairs(org.modules) do
table.insert(modules, v.slug) if not v.hide then -- hide utility modules
local module_entry = v.name..
" ["..v.slug.."]"
table.insert(modules, module_entry)
end
end end
end end
-- prepare actions menu -- prepare pending menu
local actions = {"View..."} local pending = {"View..."}
local num_actions = 0 local num_pending = 0
if org.pending[user] then if org.pending[user] then
for k,v in pairs(org.pending[user]) do for k,v in pairs(org.pending[user]) do
local action_string = "[" .. k .. "] " .. local pending_string = org.processes[k].name
org.processes[k].name .." ["..k.."]"
table.insert(actions, action_string) table.insert(pending, pending_string)
num_actions = num_actions + 1 num_pending = num_pending + 1
end end
end end
-- set player context -- set player context
local user_context = {} local user_context = {}
user_context["current_org"] = org_name user_context["current_org"] = org.name
_contexts[user] = user_context _contexts[user] = user_context
-- set up formspec -- set up formspec
local formspec = { local formspec = {
"formspec_version[4]", "formspec_version[4]",
"size[10,8]", "size[10,8]",
"label[0.5,0.5;Org: ".. "label[0.5,0.5;Org: "..
minetest.formspec_escape(org_name)..membership_toggle(org_name).."]", minetest.formspec_escape(org.name)..membership_toggle(org.name).."]",
"label[0.5,1;Parent: "..parent..membership_toggle(parent).."]", "label[0.5,1;Parent: "..parent..membership_toggle(parent).."]",
"label[0.5,2;Members:]", "label[0.5,2;Members:]",
"dropdown[2,1.5;5,0.8;user_orgs;"..formspec_list(org.members)..";;]", "dropdown[2,1.5;5,0.8;user_orgs;"..formspec_list(org.members)..";;]",
@ -152,8 +155,8 @@ function modpol.interactions.org_dashboard(user, org_name)
"dropdown[2,2.5;5,0.8;children;"..formspec_list(children)..";;]", "dropdown[2,2.5;5,0.8;children;"..formspec_list(children)..";;]",
"label[0.5,4;Modules:]", "label[0.5,4;Modules:]",
"dropdown[2,3.5;5,0.8;modules;"..formspec_list(modules)..";;]", "dropdown[2,3.5;5,0.8;modules;"..formspec_list(modules)..";;]",
"label[0.5,5;Actions ("..num_actions.."):]", "label[0.5,5;Pending ("..num_pending.."):]",
"dropdown[2,4.5;5,0.8;actions;"..formspec_list(actions)..";;]", "dropdown[2,4.5;5,0.8;pending;"..formspec_list(pending)..";;]",
"button[8.5,7;1,0.8;back;Back]", "button[8.5,7;1,0.8;back;Back]",
} }
local formspec_string = table.concat(formspec, "") local formspec_string = table.concat(formspec, "")
@ -179,7 +182,8 @@ minetest.register_on_player_receive_fields(function (player, formname, fields)
-- Receiving modules -- Receiving modules
elseif fields.modules elseif fields.modules
and fields.modules ~= "View..." then and fields.modules ~= "View..." then
local module = fields.modules local module = string.match(
fields.modules,"%[(.*)%]")
modpol.interactions.binary_poll_user( modpol.interactions.binary_poll_user(
pname, pname,
modpol.modules[module].name.."\n".. modpol.modules[module].name.."\n"..
@ -191,12 +195,12 @@ minetest.register_on_player_receive_fields(function (player, formname, fields)
end end
end) end)
-- Receiving actions -- Receiving pending
elseif fields.actions elseif fields.pending
and fields.actions ~= "View..." then and fields.pending ~= "View..." then
local action = string.match( local pending = string.match(
fields.actions,"%[(%d)%]") fields.pending,"%[(%d)%]")
local process = org.processes[tonumber(action)] local process = org.processes[tonumber(pending)]
if process then if process then
org:interact(process.id, pname) org:interact(process.id, pname)
end end