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