1 skycraft.savedata.plots = skycraft.savedata.plots or {}
3 skycraft.savedata.player_plotids = skycraft.savedata.player_plotids or {}
5 skycraft.savedata.pos_plotids = skycraft.savedata.pos_plotids or {}
7 skycraft.savedata.spiral = skycraft.savedata.spiral or {
15 function skycraft.get_new_spiral_pos()
16 local sp = skycraft.savedata.spiral
17 local rpos = {x = sp.x, z = sp.y}
20 if not (2 * sp.x * sp.d < sp.m) then
25 if not (2 * sp.y * sp.d < sp.m) then
34 function skycraft.get_plot_pos_string(pos)
35 return tostring(pos.x) .. "," .. tostring(pos.z)
38 function skycraft.get_plot_at_pos(pos)
39 return skycraft.savedata.plots[skycraft.savedata.pos_plotids[skycraft.get_plot_pos_string(vector.floor(vector.divide(pos, 62)))]]
42 function skycraft.get_plot_by_player(name)
43 return skycraft.savedata.plots[skycraft.savedata.player_plotids[name]]
46 function skycraft.claim_plot(name)
47 local plots = skycraft.savedata.plots
48 local plot = skycraft.get_new_spiral_pos()
51 plots[#plots + 1] = plot
52 skycraft.savedata.player_plotids[name] = #plots
53 skycraft.savedata.pos_plotids[skycraft.get_plot_pos_string(plot)] = #plots
57 local plot_commands = {
58 gui = function(name, message)
59 message = message or ""
60 local plot = skycraft.get_plot_by_player(name)
61 if not plot then return false, "You don't have a plot yet" end
62 local esc = minetest.formspec_escape
63 local formspec = "size[8,10]"
64 .. "label[2.5,0;" .. esc("-- Plot interface --") .. "]"
65 .. "label[0,1;" .. esc(message or "") .. "]"
66 .. "label[0,2;" .. esc("Members:") .. "]"
67 .. "button_exit[2.5,9.2;3,0.5;close;" .. esc("Close") .. "]"
68 .. "field_close_on_enter[add_member_input;false]"
71 for i, member in pairs(plot.members) do
73 .. "button[" .. (n % 4 * 2)
74 .. "," .. math.floor(n / 4 + 3)
75 .. ";1.5,.5;;" .. esc(member) .. "]"
76 .. "button[" .. (n % 4 * 2 + 1.25) .. ","
77 .. math.floor(n / 4 + 3)
78 .. ";.75,.5;remove_member_" .. tostring(i) .. ";X]"
82 .. "field[" .. (n % 4 * 2 + 1 / 3) .. ","
83 .. (math.floor(n / 4 + 3) + 1 / 3 - 0.02)
84 .. ";1.433,.5;add_member_input;;]"
85 .."button[" .. (n % 4 * 2 + 1.25) .. ","
86 .. math.floor(n / 4 + 3) .. ";.75,.5;add_member;+]"
87 minetest.show_formspec(name, "skycraft:plot_gui", formspec)
92 {"gui", "Open the GUI"},
93 {"help", "Show this help"},
94 {"add_member <member>", "Add a player to your plot's members (Grant him/her permission to build on your island)"},
95 {"remove_member <member>", "Remove a player from your plot's members (Revoke him/her permission to build on your island)"},
96 {"list_members <member>", "List the members of your plot"},
97 {"home", "Warp to your home plot (Only works if you aren't there already)"},
99 for k, v in pairs(c) do c[k] = minetest.colorize("#FFF83D", "/plot " .. v[1]) .. ": " .. v[2] end
100 return true, table.concat(c, "\n")
102 add_member = function(name, member)
103 if not member then return false, "Usage: /plot add_member <member>" end
104 local plot = skycraft.get_plot_by_player(name)
105 if not plot then return false, "You don't have a plot yet" end
106 local index = table.indexof(plot.members, member)
107 if index ~= -1 then return false, member .. " is already a member of your plot" end
108 table.insert(plot.members, member)
109 return true, member .. " added to plot members"
111 remove_member = function(name, member)
112 if not member then return false, "Usage: /plot remove_member <member>" end
113 local plot = skycraft.get_plot_by_player(name)
114 if not plot then return false, "You don't have a plot yet" end
115 local index = table.indexof(plot.members, member)
116 if index == -1 then return false, member .. " isn't a member of your plot" end
117 table.remove(plot.members, index)
118 return true, member .. " removed from plot members"
120 list_members = function(name, member)
121 local plot = skycraft.get_plot_by_player(name)
122 if not plot then return false, "You don't have a plot yet" end
123 if #plot.members == 0 then return true, "You plot has no members" end
124 return true, "Plot members: " .. table.concat(plot.members, ", ")
126 home = function(name)
127 local player = minetest.get_player_by_name(name)
128 if not player then return false, "You have to be online to use this command" end
129 local pos = player:get_pos()
130 if pos.y > 5000 then return false, "You are not on the Skyblock map. Use /skyblock to get there" end
131 if pos.y < -100 then return false, "You can only use this command in the Overworld" end
132 local plot = skycraft.get_plot_at_pos(pos)
133 if plot and plot.owner == name then return false, "You are already on your home plot" end
134 skycraft.spawn_player(player)
135 return true, "Warped to your home plot"
139 local plot_chatcommand_def = {
140 description = "Manage your plot. See /plot help for help",
141 param = "[<command> [...]]",
142 privs = {skycraft = true},
143 func = function(name, param)
144 local cmd = param:split(" ")[1] or "gui"
145 local cmd_param = param:split(" ")[2]
146 local cmd_func = plot_commands[cmd]
147 if not cmd_func then return false, "Invalid command /plot " .. param .. ". See /plot help for help" end
148 return cmd_func(name, cmd_param)
152 minetest.register_chatcommand("p", plot_chatcommand_def)
154 minetest.register_chatcommand("plot", plot_chatcommand_def)
156 minetest.register_on_player_receive_fields(function(player, formname, fields)
157 if formname ~= "skycraft:plot_gui" then return end
158 local name = player:get_player_name()
160 for i, member in pairs(skycraft.get_plot_by_player(name).members) do
161 if fields["remove_member_" .. tostring(i)] then
162 _, message = plot_commands.remove_member(name, member)
165 if fields.add_member and fields.add_member_input ~= "" then
166 _, message = plot_commands.add_member(name, fields.add_member_input)
168 if not fields.close and not fields.quit then
169 plot_commands.gui(name, message)
173 local old_is_protected = minetest.is_protected
174 function minetest.is_protected(pos, name)
175 local plot = skycraft.get_plot_at_pos(pos) or {members = {}}
176 if pos.y > 5000 or (pos.y < 1000 and pos.y > -100) or (pos.y > 1000 and plot.owner ~= name and table.indexof(plot.members, name) == -1) then
177 return not minetest.check_player_privs(name, {protection_bypass = true})
179 return old_is_protected(pos, name)