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