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