]> git.lizzy.rs Git - skycraft.git/blob - src/main/plots.lua
2d6c67e05d76d5fa84f5ec3c8dd28ca1a03905ea
[skycraft.git] / src / main / plots.lua
1 skycraft.savedata.plots = skycraft.savedata.plots or {}
2
3 skycraft.savedata.player_plotids = skycraft.savedata.player_plotids or {}
4
5 skycraft.savedata.pos_plotids = skycraft.savedata.pos_plotids or {}
6
7 skycraft.savedata.spiral = skycraft.savedata.spiral or {
8         x = 0,
9         y = 0,
10         d = 1,
11         m = 1,
12         s = true,
13 }
14
15 function skycraft.get_new_spiral_pos()
16         local sp = skycraft.savedata.spiral
17         local rpos = {x = sp.x, z = sp.y}
18         if sp.s then
19                 sp.x = sp.x + sp.d
20                 if not (2 * sp.x * sp.d < sp.m) then
21                         sp.s = false
22                 end
23         else
24                 sp.y = sp.y + sp.d
25                 if not (2 * sp.y * sp.d < sp.m) then
26                         sp.s = true
27                         sp.d = -1 * sp.d
28                         sp.m = sp.m + 1
29                 end
30         end
31         return rpos
32 end
33
34 function skycraft.get_plot_pos_string(pos)
35         return tostring(pos.x) .. "," .. tostring(pos.z)
36 end
37
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)))]]
40 end
41
42 function skycraft.get_plot_by_player(name)
43         return skycraft.savedata.plots[skycraft.savedata.player_plotids[name]]
44 end
45
46 function skycraft.claim_plot(name)
47         local plots = skycraft.savedata.plots
48         local plot = skycraft.get_new_spiral_pos()
49         plot.owner = name
50         plot.members = {}
51         plots[#plots + 1] = plot
52         skycraft.savedata.player_plotids[name] = #plots
53         skycraft.savedata.pos_plotids[skycraft.get_plot_pos_string(plot)] = #plots
54         return plot
55 end
56
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]"
68                 
69                 local n = 0
70                 for i, member in pairs(plot.members) do
71                         formspec = formspec
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]"
78                         n = i
79                 end
80                 formspec = formspec
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)
87         end,
88         help = function(name)
89                 local c = {
90                         {"", "Open the GUI"},
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)"},
97                 }
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")
100         end,
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"
109         end,
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"
118         end,
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, ", ")
124         end,
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(player)
134                 return true, "Warped to your home plot"
135         end
136 }
137
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)
148         end
149 }
150
151 minetest.register_chatcommand("p", plot_chatcommand_def)
152
153 minetest.register_chatcommand("plot", plot_chatcommand_def)
154
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()
158         local _, message
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)
162                 end
163         end
164         if fields.add_member and fields.add_member_input ~= "" then
165                 _, message = plot_commands.add_member(name, fields.add_member_input)
166         end
167         if not fields.close and not fields.quit then
168                 plot_commands.gui(name, message)
169         end
170 end)
171
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})
177         else
178                 return old_is_protected(pos, name)
179         end
180 end