]> git.lizzy.rs Git - Crafter.git/blob - mods/nether/init.lua
Fix nether and void deprecated 3d noise calls
[Crafter.git] / mods / nether / init.lua
1 local nether_channel = minetest.mod_channel_join("nether_teleporters")
2
3 local path = minetest.get_modpath("nether")
4 dofile(path.."/schem.lua")
5 dofile(path.."/nodes.lua")
6 dofile(path.."/biomes.lua")
7 dofile(path.."/craft_recipes.lua")
8 dofile(path.."/ore.lua")
9 dofile(path.."/items.lua")
10
11
12 minetest.register_node("nether:portal", {
13         description = "Nether Portal",
14
15         tiles = {
16                 {
17                         name = "nether_portal.png",
18                         backface_culling = true,
19                         animation = {
20                                 type = "vertical_frames",
21                                 aspect_w = 16,
22                                 aspect_h = 16,
23                                 length = 0.5,
24                         },
25                 },
26                 {
27                         name = "nether_portal.png",
28                         backface_culling = true,
29                         animation = {
30                                 type = "vertical_frames",
31                                 aspect_w = 16,
32                                 aspect_h = 16,
33                                 length = 0.5,
34                         },
35                 },
36         },
37         drawtype = "nodebox",
38         paramtype = "light",
39         --paramtype2 = "facedir",
40         sunlight_propagates = true,
41         use_texture_alpha = false,
42         walkable = false,
43         diggable = false,
44         pointable = false,
45         buildable_to = false,
46         is_ground_content = false,
47         drop = "",
48         light_source = 7,
49         --post_effect_color = {a = 180, r = 51, g = 7, b = 89},
50         alpha = 140,
51         node_box = {
52         type = "connected",
53                 -- connect_top =
54                 -- connect_bottom =
55                 connect_front = {0,  -1/2, -1/2,   0,  1/2, 0 },
56                 connect_left =  {-1/2,   -1/2, 0, 0,   1/2,  0},
57                 connect_back =  {0,  -1/2,  0,   0,  1/2,  1/2 },
58                 connect_right = { 0,   -1/2, 0,  1/2,   1/2,  0},
59         },
60         connects_to = {"nether:portal","nether:obsidian"},
61         groups = {unbreakable=1},
62         --on_destruct = destroy_portal,
63 })
64
65 --branch out from center
66 local n_index = {}
67 local portal_failure = false
68 local x_failed = false
69
70 --this can be used globally to create nether portals from obsidian
71 function create_nether_portal(pos,origin,axis)
72         --create the origin node for stored memory
73         if not origin then
74                 origin = pos
75                 portal_failure = false
76         end
77         if not axis then
78                 axis = "x"
79         end
80                 
81         --2d virtual memory map creation (x axis)
82         if axis == "x" then
83                 for x = -1,1 do
84                 for y = -1,1 do
85                         --index only direct neighbors
86                         if x_failed == false and (math.abs(x)+math.abs(y) == 1) then
87                                 local i = vector.add(pos,vector.new(x,y,0))
88                                 
89                                 local execute_collection = true
90                                 
91                                 if n_index[i.x] and n_index[i.x][i.y] then
92                                         if n_index[i.x][i.y][i.z] then
93                                                 execute_collection = false
94                                         end
95                                 end     
96                                 
97                                 if execute_collection == true then
98                                         --print(minetest.get_node(i).name)
99                                         --index air
100                                         if minetest.get_node(i).name == "air" then
101                                                 
102                                                 if vector.distance(i,origin) < 50 then
103                                                         --add data to both maps
104                                                         if not n_index[i.x] then n_index[i.x] = {} end
105                                                         if not n_index[i.x][i.y] then n_index[i.x][i.y] = {} end
106                                                         n_index[i.x][i.y][i.z] = {nether_portal=1} --get_group(i,"redstone_power")}             
107                                                         --the data to the 3d array must be written to memory before this is executed
108                                                         --or a stack overflow occurs!!!
109                                                         --pass down info for activators
110                                                         create_nether_portal(i,origin,"x")
111                                                 else
112                                                         --print("try z")
113                                                         x_failed = true
114                                                         n_index = {}
115                                                         create_nether_portal(origin,origin,"z")
116                                                 end
117                                         elseif minetest.get_node(i).name ~= "nether:obsidian" then
118                                                 x_failed = true
119                                                 n_index = {}
120                                                 create_nether_portal(origin,origin,"z")
121                                         end
122                                 end
123                         end
124                 end
125                 end
126         --2d virtual memory map creation (z axis)
127         elseif axis == "z" then
128                 for z = -1,1 do
129                 for y = -1,1 do
130                         --index only direct neighbors
131                         if x_failed == true and portal_failure == false and (math.abs(z)+math.abs(y) == 1) then
132                                 local i = vector.add(pos,vector.new(0,y,z))
133                                 
134                                 local execute_collection = true
135                                 
136                                 if n_index[i.x] and n_index[i.x][i.y] then
137                                         if n_index[i.x][i.y][i.z] then
138                                                 execute_collection = false
139                                         end
140                                 end     
141                                 
142                                 if execute_collection == true then
143                                         --print(minetest.get_node(i).name)
144                                         --index air
145                                         if minetest.get_node(i).name == "air" then
146                                                 if vector.distance(i,origin) < 50 then
147                                                         --add data to both maps
148                                                         if not n_index[i.x] then n_index[i.x] = {} end
149                                                         if not n_index[i.x][i.y] then n_index[i.x][i.y] = {} end
150                                                         n_index[i.x][i.y][i.z] = {nether_portal=1} --get_group(i,"redstone_power")}                             
151                                                         --the data to the 3d array must be written to memory before this is executed
152                                                         --or a stack overflow occurs!!!
153                                                         --pass down info for activators
154                                                         create_nether_portal(i,origin,"z")
155                                                 else
156                                                         --print("portal failed")
157                                                         portal_failure = true
158                                                         n_index = {}
159                                                         --print("try z")
160                                                 end
161                                         elseif minetest.get_node(i).name ~= "nether:obsidian" then
162                                                 --print("portal failed")
163                                                 portal_failure = true
164                                                 n_index = {}
165                                         end
166                                 end
167                         end
168                 end
169                 end
170         end
171 end
172
173 --creates a nether portal in the nether
174 --this essentially makes it so you have to move 30 away from one portal to another otherwise it will travel to an existing portal
175 local nether_origin_pos = nil
176 local function spawn_portal_into_nether_callback(blockpos, action, calls_remaining, param)
177         if calls_remaining == 0 then
178                 local portal_exists = minetest.find_node_near(nether_origin_pos, 30, {"nether:portal"})
179                                 
180                 if not portal_exists then
181                         local min = vector.subtract(nether_origin_pos,30)
182                         local max = vector.add(nether_origin_pos,30)
183                         local platform = minetest.find_nodes_in_area_under_air(min, max, {"nether:netherrack","main:lava"})
184                         
185                         if platform and next(platform) then
186                                 --print("setting the platform")
187                                 local platform_location = platform[math.random(1,table.getn(platform))]
188                                 
189                                 minetest.place_schematic(platform_location, portalSchematic,"0",nil,true,"place_center_x, place_center_z")
190                         else
191                                 --print("generate a portal within netherrack")
192                                 minetest.place_schematic(nether_origin_pos, portalSchematic,"0",nil,true,"place_center_x, place_center_z")
193                         end
194                 else
195                         --print("portal exists, utilizing")
196                 end
197                 nether_origin_pos = nil
198         end
199 end
200 --creates nether portals in the overworld
201 local function spawn_portal_into_overworld_callback(blockpos, action, calls_remaining, param)
202         if calls_remaining == 0 then
203                 local portal_exists = minetest.find_node_near(nether_origin_pos, 30, {"nether:portal"})
204                                 
205                 if not portal_exists then
206                         local min = vector.subtract(nether_origin_pos,30)
207                         local max = vector.add(nether_origin_pos,30)
208                         local platform = minetest.find_nodes_in_area_under_air(min, max, {"main:stone","main:water","main:grass","main:sand","main:dirt"})
209                         
210                         if platform and next(platform) then
211                                 --print("setting the platform")
212                                 local platform_location = platform[math.random(1,table.getn(platform))]
213                                 
214                                 minetest.place_schematic(platform_location, portalSchematic,"0",nil,true,"place_center_x, place_center_z")
215                         else
216                                 --print("generate a portal within overworld stone")
217                                 minetest.place_schematic(nether_origin_pos, portalSchematic,"0",nil,true,"place_center_x, place_center_z")
218                         end
219                 else
220                         --print("portal exists, utilizing")
221                 end
222                 nether_origin_pos = nil
223         end
224 end
225
226
227 local function generate_nether_portal_in_nether(pos)
228         if pos.y > -10033 then
229                 --center the location to the lava height
230                 pos.y = -15000--+math.random(-30,30)    
231                 nether_origin_pos = pos
232                 
233                 local min = vector.subtract(nether_origin_pos,30)
234                 local max = vector.add(nether_origin_pos,30)
235                 
236                 --force load the area
237                 minetest.emerge_area(min, max, spawn_portal_into_nether_callback)
238         else
239                 --center the location to the water height
240                 pos.y = 0--+math.random(-30,30) 
241                 nether_origin_pos = pos
242                 --prefer height for mountains
243                 local min = vector.subtract(nether_origin_pos,vector.new(30,30,30))
244                 local max = vector.add(nether_origin_pos,vector.new(30,120,30))
245                 
246                 --force load the area
247                 minetest.emerge_area(min, max, spawn_portal_into_overworld_callback)
248         end
249 end
250
251
252 --modify the map with the collected data
253 local function portal_modify_map(n_copy)
254         local sorted_table = {}
255         local created_portal = false
256         for x,datax in pairs(n_copy) do
257                 for y,datay in pairs(datax) do
258                         for z,index in pairs(datay) do
259                                 --try to create a return side nether portal
260                                 if created_portal == false then
261                                         created_portal = true
262                                         generate_nether_portal_in_nether(vector.new(x,y,z))
263                                 end
264                                 table.insert(sorted_table, vector.new(x,y,z))
265                         end
266                 end
267         end
268         minetest.bulk_set_node(sorted_table, {name="nether:portal"})
269 end
270
271 -------------------------------------------------------------------------------------------
272 --the teleporter parts - stored here for now so I can read from other functions
273 local teleporting_player = nil
274 local function teleport_to_overworld(blockpos, action, calls_remaining, param)
275         if calls_remaining == 0 then
276                 local portal_exists = minetest.find_node_near(nether_origin_pos, 30, {"nether:portal"})
277                 if portal_exists then
278                         --print(teleporting_player)
279                         if teleporting_player then
280                                 teleporting_player:set_pos(vector.new(portal_exists.x,portal_exists.y-0.5,portal_exists.z))
281                         end
282                 end
283                 teleporting_player = nil
284         end
285 end
286 local function teleport_to_nether(blockpos, action, calls_remaining, param)
287         if calls_remaining == 0 then
288                 local portal_exists = minetest.find_node_near(nether_origin_pos, 30, {"nether:portal"})
289                 if portal_exists then
290                         --print(teleporting_player)
291                         if teleporting_player then
292                                 teleporting_player:set_pos(vector.new(portal_exists.x,portal_exists.y-0.5,portal_exists.z))
293                         end
294                 end
295                 teleporting_player = nil
296         end
297 end
298
299 --this initializes all teleporter commands from the client
300 minetest.register_on_modchannel_message(function(channel_name, sender, message)
301         if channel_name == "nether_teleporters" then
302                 local player = minetest.get_player_by_name(sender)
303                 local pos = player:get_pos()
304                 
305                 if pos.y > -10033 then
306                         --center the location to the lava height
307                         pos.y = -15000--+math.random(-30,30)    
308                         nether_origin_pos = pos
309                         
310                         local min = vector.subtract(nether_origin_pos,30)
311                         local max = vector.add(nether_origin_pos,30)
312                         
313                         --force load the area
314                         teleporting_player = player
315                         minetest.emerge_area(min, max, teleport_to_nether)
316                 else
317                         --center the location to the water height
318                         pos.y = 0--+math.random(-30,30) 
319                         nether_origin_pos = pos
320                         --prefer height for mountains
321                         local min = vector.subtract(nether_origin_pos,vector.new(30,30,30))
322                         local max = vector.add(nether_origin_pos,vector.new(30,120,30))
323                         
324                         --force load the area
325                         teleporting_player = player
326                         minetest.emerge_area(min, max, teleport_to_overworld)
327                 end
328         end
329 end)
330 -------------------------------------------------------------------------------------------
331
332 -------------------------------------------------------------------------------
333
334 local destroy_n_index = {}
335 local destroy_portal_failure = false
336 local destroy_x_failed = false
337
338 --this can be used globally to create nether portals from obsidian
339 function destroy_nether_portal(pos,origin,axis)
340         --create the origin node for stored memory
341         if not origin then
342                 origin = pos
343         end             
344         --3d virtual memory map creation (x axis)
345         for x = -1,1 do
346         for z = -1,1 do
347         for y = -1,1 do
348                 --index only direct neighbors
349                 if (math.abs(x)+math.abs(z)+math.abs(y) == 1) then
350                         local i = vector.add(pos,vector.new(x,y,z))
351                         
352                         local execute_collection = true
353                         
354                         if destroy_n_index[i.x] and destroy_n_index[i.x][i.y] then
355                                 if destroy_n_index[i.x][i.y][i.z] then
356                                         execute_collection = false
357                                 end
358                         end     
359                         
360                         if execute_collection == true then
361                                 --print(minetest.get_node(i).name)
362                                 --index air
363                                 if minetest.get_node(i).name == "nether:portal" then
364                                         if vector.distance(i,origin) < 50 then
365                                                 --add data to both maps
366                                                 if not destroy_n_index[i.x] then destroy_n_index[i.x] = {} end
367                                                 if not destroy_n_index[i.x][i.y] then destroy_n_index[i.x][i.y] = {} end
368                                                 destroy_n_index[i.x][i.y][i.z] = {nether_portal=1} --get_group(i,"redstone_power")}                             
369                                                 --the data to the 3d array must be written to memory before this is executed
370                                                 --or a stack overflow occurs!!!
371                                                 --pass down info for activators
372                                                 destroy_nether_portal(i,origin,"z")
373                                         end
374                                 end
375                         end
376                 end
377         end
378         end
379         end
380 end
381
382 --modify the map with the collected data
383 local function destroy_portal_modify_map(destroy_n_copy)
384         local destroy_sorted_table = {}
385         for x,datax in pairs(destroy_n_copy) do
386                 for y,datay in pairs(datax) do
387                         for z,index in pairs(datay) do
388                                 table.insert(destroy_sorted_table, vector.new(x,y,z))
389                         end
390                 end
391         end
392         minetest.bulk_set_node(destroy_sorted_table, {name="air"})
393 end
394
395 minetest.register_globalstep(function(dtime)
396         --if indexes exist then calculate redstone
397         if n_index and next(n_index) and portal_failure == false then
398                 --create the old version to help with deactivation calculation
399                 local n_copy = table.copy(n_index)
400                 portal_modify_map(n_copy)
401                 portal_failure = false
402         end
403         if x_failed == true then
404                 x_failed = false
405         end
406         if portal_failure == true then
407                 portal_failure = false
408         end
409         --clear the index to avoid cpu looping wasting processing power
410         n_index = {}
411         
412         
413         --if indexes exist then calculate redstone
414         if destroy_n_index and next(destroy_n_index) and destroy_portal_failure == false then
415                 --create the old version to help with deactivation calculation
416                 local destroy_n_copy = table.copy(destroy_n_index)
417                 destroy_portal_modify_map(destroy_n_copy)
418         end
419         --clear the index to avoid cpu looping wasting processing power
420         destroy_n_index = {}
421 end)