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 local esc = minetest.formspec_escape
62 local formspec = "size[8,10]"
63 .. "label[2.5,0;" .. esc("-- Plot interface --") .. "]"
64 .. "label[0,1;" .. esc(message or "") .. "]"
65 .. "label[0,2;" .. esc("Members:") .. "]"
66 .. "button_exit[2.5,9.2;3,0.5;close;" .. esc("Close") .. "]"
67 .. "field_close_on_enter[add_member_input;false]"
70 for i, member in pairs(plot.members) do
72 .. "button[" .. (n % 4 * 2)
73 .. "," .. math.floor(n / 4 + 3)
74 .. ";1.5,.5;;" .. esc(member) .. "]"
75 .. "button[" .. (n % 4 * 2 + 1.25) .. ","
76 .. math.floor(n / 4 + 3)
77 .. ";.75,.5;remove_member_" .. tostring(i) .. ";X]"
81 .. "field[" .. (n % 4 * 2 + 1 / 3) .. ","
82 .. (math.floor(n / 4 + 3) + 1 / 3 - 0.02)
83 .. ";1.433,.5;add_member_input;;]"
84 .."button[" .. (n % 4 * 2 + 1.25) .. ","
85 .. math.floor(n / 4 + 3) .. ";.75,.5;add_member;+]"
86 minetest.show_formspec(name, "skycraft:plot_gui", formspec)
91 {"gui", "Open the GUI"},
92 {"help", "Show this help"},
93 {"add_member <member>", "Add a player to your plot's members (Grant him/her permission to build on your island)"},
94 {"remove_member <member>", "Remove a player from your plot's members (Revoke him/her permission to build on your island)"},
95 {"list_members <member>", "List the members of your plot"},
96 {"home", "Warp to your home plot (Only works if you aren't there already)"},
98 for k, v in pairs(c) do c[k] = minetest.colorize("#FFF83D", "/plot " .. v[1]) .. ": " .. v[2] end
99 return true, table.concat(c, "\n")
101 add_member = function(name, member)
102 if not member then return false, "Usage: /plot add_member <member>" end
103 local plot = skycraft.get_plot_by_player(name)
104 if not plot then return false, "You don't have a plot yet" end
105 local index = table.indexof(plot.members, member)
106 if index ~= -1 then return false, member .. " is already a member of your plot" end
107 table.insert(plot.members, member)
108 return true, member .. " added to plot members"
110 remove_member = function(name, member)
111 if not member then return false, "Usage: /plot remove_member <member>" end
112 local plot = skycraft.get_plot_by_player(name)
113 if not plot then return false, "You don't have a plot yet" end
114 local index = table.indexof(plot.members, member)
115 if index == -1 then return false, member .. " isn't a member of your plot" end
116 table.remove(plot.members, index)
117 return true, member .. " removed from plot members"
119 list_members = function(name, member)
120 local plot = skycraft.get_plot_by_player(name)
121 if not plot then return false, "You don't have a plot yet" end
122 if #plot.members == 0 then return true, "You plot has no members" end
123 return true, "Plot members: " .. table.concat(plot.members, ", ")
125 home = function(name)
126 local player = minetest.get_player_by_name(name)
127 if not player then return false, "You have to be online to use this command" end
128 local pos = player:get_pos()
129 if pos.y > 5000 then return false, "You are not on the Skyblock map. Use /skyblock to get there" end
130 if pos.y < -100 then return false, "You can only use this command in the Overworld" end
131 local plot = skycraft.get_plot_at_pos(pos)
132 if plot and plot.owner == name then return false, "You are already on your home plot" end
133 skycraft.spawn_player(name)
134 return true, "Warped to your home plot"
138 local plot_chatcommand_def = {
139 description = "Manage your plot. See /plot help for help",
140 param = "[<command> [...]]",
141 privs = {skycraft = true},
142 func = function(name, param)
143 local cmd = param:split(" ")[1] or "gui"
144 local cmd_param = param:split(" ")[2]
145 local cmd_func = plot_commands[cmd]
146 if not cmd_func then return false, "Invalid command /plot " .. param .. ". See /plot help for help" end
147 return cmd_func(name, cmd_param)
151 minetest.register_chatcommand("p", plot_chatcommand_def)
153 minetest.register_chatcommand("plot", plot_chatcommand_def)
155 minetest.register_on_player_receive_fields(function(player, formname, fields)
156 if formname ~= "skycraft:plot_gui" then return end
157 local name = player:get_player_name()
159 for i, member in pairs(skycraft.get_plot_by_player(name).members) do
160 if fields["remove_member_" .. tostring(i)] then
161 _, message = plot_commands.remove_member(name, member)
164 if fields.add_member and fields.add_member_input ~= "" then
165 _, message = plot_commands.add_member(name, fields.add_member_input)
167 if not fields.close and not fields.quit then
168 plot_commands.gui(name, message)
172 local old_is_protected = minetest.is_protected
173 function minetest.is_protected(pos, name)
174 local plot = skycraft.get_plot_at_pos(pos) or {members = {}}
175 if pos.y > 5000 or (pos.y < 1000 and pos.y > -100) or plot.owner ~= name and table.indexof(plot.members, name) == -1 then
176 return not minetest.check_player_privs(name, {protection_bypass = true})
178 return old_is_protected(pos, name)