]> git.lizzy.rs Git - elidragon.git/blob - skyblock.lua
Re-add set_skyblock_spawn command
[elidragon.git] / skyblock.lua
1 elidragon.skyblock = {} 
2
3 --helper functions
4
5 -- http://rosettacode.org/wiki/Spiral_matrix#Lua
6 av, sn = math.abs, function(s) return s~=0 and s/av(s) or 0 end
7 local function sindex(y, x)
8         if y == -x and y >= x then return (2*y+1)^2 end
9         local l = math.max(av(y), av(x))
10         return (2*l-1)^2+4*l+2*l*sn(x+y)+sn(y^2-x^2)*(l-(av(y)==l and sn(y)*x or sn(x)*y))
11 end
12 local function spiralt(side)
13         local ret, id, start, stop = {}, 0, math.floor((-side+1)/2), math.floor((side-1)/2)
14         for i = 1, side do
15                 for j = 1, side do
16                         local id = side^2 - sindex(stop - i + 1,start + j - 1)
17                         ret[id] = {x=i,z=j}
18                 end
19         end
20         return ret
21 end
22
23 local function ripairs(t)
24         local function ripairs_it(t,i)
25                 i=i-1
26                 local v=t[i]
27                 if v==nil then return v end
28                 return i,v
29         end
30         return ripairs_it, t, #t+1
31 end
32
33 -- start positions
34
35 function elidragon.skyblock.load_start_positions()
36         local file = io.open(minetest.get_worldpath() .. "/start_positions", "r")
37         if file then
38                 local start_positions = minetest.deserialize(file:read())
39                 file:close()
40                 return start_positions
41         end
42 end
43
44 function elidragon.skyblock.save_start_positions(start_positions)
45         local file = io.open(minetest.get_worldpath() .. "/start_positions", "w")
46         file:write(minetest.serialize(start_positions))
47         file:close()
48 end
49
50 function elidragon.skyblock.generate_start_positions()
51         local start_positions = {}
52         for _, v in ripairs(spiralt(1000)) do
53                 local pos = {x = v.x * 32, y = math.random(4 - 8, 4 + 8), z = v.z * 32}
54                 table.insert(start_positions, pos)
55         end
56         return start_positions
57 end
58
59 elidragon.skyblock.start_positions = elidragon.skyblock.load_start_positions() 
60
61 if not elidragon.skyblock.start_positions then
62         elidragon.skyblock.start_positions = elidragon.skyblock.generate_start_positions()
63         elidragon.skyblock.save_start_positions(elidragon.skyblock.start_positions)
64 end
65
66 elidragon.savedata.last_start_id = elidragon.savedata.last_start_id or 0
67
68 -- spawns
69
70 function elidragon.skyblock.get_spawn(player)
71         return minetest.string_to_pos(player:get_meta():get_string("elidragon:spawn"))
72 end
73
74 function elidragon.skyblock.set_spawn(player, pos)
75         player:get_meta():set_string("elidragon:spawn", minetest.pos_to_string(pos))
76 end
77
78 function elidragon.skyblock.spawn_player(player)
79         if not player then return end
80         local spawn = elidragon.skyblock.get_spawn(player) or elidragon.skyblock.new_spawn(player)
81         player:set_pos({x = spawn.x + 2, y = spawn.y + 2, z = spawn.z + 2})
82 end
83
84 function elidragon.skyblock.new_spawn(player)
85         local name = player:get_player_name()
86         local spawn
87         repeat
88                 elidragon.savedata.last_start_id = elidragon.savedata.last_start_id + 1
89                 spawn = elidragon.skyblock.start_positions[elidragon.savedata.last_start_id] 
90         until not minetest.is_protected(spawn, name)
91         elidragon.skyblock.set_spawn(player, spawn)     
92         local file = io.open(minetest.get_modpath("elidragon") .. "/schems/island.we", "r")
93         local schem = file:read()
94         file:close()
95         worldedit.deserialize(vector.add(spawn, {x = -3, y = -4, z = -3}), schem) 
96         return spawn
97 end
98
99 -- node
100
101 minetest.register_node("elidragon:skyblock", {
102         description = "Skyblock",
103         tiles = {"elidragon_quest.png"},
104         paramtype = "light",
105         light_source = 14,
106         groups = {crumbly=2, cracky=2},
107 })
108
109 minetest.register_alias("skyblock:quest", "elidragon:skyblock")
110
111 -- mapgen
112
113 minetest.register_on_mapgen_init(function(mgparams)
114         minetest.set_mapgen_params({mgname = "singlenode", water_level = -32000})
115 end)
116
117 -- respawn
118
119 minetest.register_on_respawnplayer(function(player)
120         elidragon.skyblock.spawn_player(player)
121         return true
122 end)
123
124 -- remove legacy cloud layer
125
126 minetest.register_lbm({
127         nodenames = {"default:cloud"},
128         name = "elidragon:remove_cloud_layer",
129         action = function(pos)
130                 if pos.y == -10 then
131                         minetest.set_node(pos, { name = "air"})
132                 end
133         end
134 })
135
136 -- remove inventory from quest block
137
138 minetest.register_lbm({
139         nodenames = {"elidragon:skyblock", "skyblock:quest"},
140         name = "elidragon:remove_inventory_from_quest_block",
141         action = function(pos)
142                 minetest.get_meta(pos):set_string("formspec", "")
143                 minetest.get_meta(pos):set_string("infotext", "")
144         end
145 })
146
147 -- ores
148
149 minetest.after(0, function()
150         default.cool_lava = function(pos, oldnode)
151                 local node
152                 if oldnode.name == "default:lava_source" then
153                         node = "default:obsidian"
154                 elseif math.random() < 0.0001 then
155                         node = "moreores:mineral_mithril"
156                 elseif math.random() < 0.0003 then
157                         node = "default:stone_with_diamond"
158                 elseif math.random() < 0.0005 then
159                         node = "default:stone_with_mese"
160                 elseif math.random() < 0.001 then
161                         node = "default:stone_with_gold"
162                 elseif math.random() < 0.001 then
163                         node = "technic:mineral_chromium"
164                 elseif math.random() < 0.001 then
165                         node = "technic:mineral_zinc"
166                 elseif math.random() < 0.0012 then
167                         node = "technic:mineral_uranium"
168                 elseif math.random() < 0.0015 then
169                         node = "default:stone_with_tin"
170                 elseif math.random() < 0.002 then
171                         node = "default:stone_with_copper"
172                 elseif math.random() < 0.0025 then
173                         node = "technic:mineral_sulfur"
174                 elseif math.random() < 0.0033 then
175                         node = "default:stone_with_iron"
176                 elseif math.random() < 0.004 then
177                         node = "moreores:mineral_silver"
178                 elseif math.random() < 0.0045 then
179                         node = "technic:mineral_lead"
180                 elseif math.random() < 0.005 then
181                         node = "default:stone_with_coal"
182                 else
183                         node = "default:stone"
184                 end
185                 minetest.set_node(pos, {name = node})
186                 minetest.sound_play("default_cool_lava", {pos = pos, max_hear_distance = 16, gain = 0.25}, true)
187         end
188 end)
189
190 -- saplings
191
192 minetest.after(0, function()
193         minetest.register_alias("default:pine_leaves", "default:pine_needles")
194         minetest.register_alias("default:pine_bush_leaves", "default:pine_bush_needles")
195         local trees = {"default:", "default:jungle", "default:pine_", "default:acacia_", "default:aspen_", "default:bush_", "default:blueberry_bush_", "default:acacia_bush_", "default:pine_bush_", "moretrees:apple_tree_", "moretrees:beech_", "moretrees:cedar_", "moretrees:date_palm_", "moretrees:fir_", "moretrees:oak_", "moretrees:palm_", "moretrees:poplar_", "moretrees:sequoia_", "moretrees:spruce_", "moretrees:willow_", }
196         for _, tree in pairs(trees) do
197                 local items = {}
198                 items[#items + 1] = {
199                         items = {tree .. "sapling"},
200                         rarity = 20,
201                 }
202                 for _, stree in pairs(trees) do
203                         if stree ~= tree then
204                                 items[#items + 1] = {
205                                         items = {stree .. "sapling"},
206                                         rarity = 10000,
207                                 }
208                         end
209                 end
210                 items[#items + 1] = {
211                         items = {tree .. "leaves"},
212                 }
213                 minetest.registered_nodes[tree .. "leaves"].drop = {max_items = 1, items = items}
214         end
215 end)
216
217 -- flowers
218
219 minetest.register_abm({
220         nodenames = {"default:dirt_with_grass"},
221         interval = 300,
222         chance = 100,
223         action = function(pos, node)
224                 pos.y = pos.y + 1
225                 local light = minetest.get_node_light(pos) or 0
226                 if minetest.get_node(pos).name == "air" and light > 12 and not minetest.find_node_near(pos, 2, {"group:flora"}) then
227                         local flowers = {"default:junglegrass", "default:grass_1", "flowers:dandelion_white", "flowers:dandelion_yellow", "flowers:geranium", "flowers:rose", "flowers:tulip", "flowers:tulip_black", "flowers:viola", "flowers:chrysanthemum_green"}
228                         minetest.set_node(pos, {name = flowers[math.random(#flowers)]})
229                 end
230         end
231 })
232
233 -- recipes
234
235 minetest.register_craft({
236         output = "default:desert_sand",
237         recipe = {
238                 {"default:sand"},
239                 {"default:gravel"},
240         }
241 })
242
243 minetest.register_craft({
244         output = "default:desert_stone",
245         recipe = {
246                 {"default:desert_sand", "default:desert_sand", "default:desert_sand"},
247                 {"default:desert_sand", "default:desert_sand", "default:desert_sand"},
248                 {"default:desert_sand", "default:desert_sand", "default:desert_sand"},
249         }
250 })
251
252 minetest.register_craft({
253         output = "default:sand 4",
254         recipe = {
255                 {"default:obsidian_shard"},
256         }
257 })
258
259 minetest.register_craft({
260         output = "default:gravel 2",
261         recipe = {
262                 {"default:cobble"},
263         }
264 })
265
266 minetest.register_craft({
267         output = "default:dirt 2",
268         recipe = {
269                 {"default:gravel"},
270         }
271 })
272
273 minetest.register_craft({
274         output = "default:clay_lump 4",
275         recipe = {
276                 {"default:dirt"},
277         }
278 })
279
280 minetest.register_craft({
281         output = "default:ice",
282         recipe = {
283                 {"bucket:bucket_water"},
284         }
285 })
286
287 minetest.register_craft({
288         output = "default:snowblock 4",
289         recipe = {
290                 {"default:ice"},
291         }
292 })
293
294 minetest.register_craft({
295         type = "cooking",
296         output = "default:lava_source",
297         recipe = "default:stone",
298 })
299
300 minetest.register_craft({
301         output = "default:silver_sand 9",
302         recipe = {
303                 {"default:sand", "default:sand", "default:sand"},
304                 {"default:sand", "moreores:silver_lump", "default:sand"},
305                 {"default:sand", "default:sand", "default:sand"},
306         }
307 })
308
309 -- commands
310
311 minetest.register_chatcommand("island", {
312         params = "",
313         description = "Teleport to your Island",
314         func = function(name, param)
315                 local player = minetest.get_player_by_name(name)
316                 if not player then return end
317                 elidragon.skyblock.spawn_player(player)
318         end,
319 })
320
321 minetest.register_chatcommand("set_skyblock_spawn", {
322         params = "<name> <x> <y> <z>",
323         description = "Set new skyblock spawn for <name>",
324         privs = {server = true},
325         func = function(sender, param)
326                 local name = param:split(" ")[1]
327                 local x = tonumber(param:split(" ")[2])
328                 local y = tonumber(param:split(" ")[3])
329                 local z = tonumber(param:split(" ")[4])
330                 if name and x and y and z and minetest.get_player_by_name(name) then
331                         elidragon.skyblock.set_spawn(minetest.get_player_by_name(name), {x = x, y = y, z = z})
332                 else
333                         minetest.chat_send_player(sender, "Invalid usage or player not online")
334                 end
335         end,
336 })