Crafter/mods/aether/init.lua

394 lines
12 KiB
Lua
Raw Normal View History

2020-04-20 15:57:46 -04:00
local path = minetest.get_modpath("aether")
2020-04-24 09:43:24 -04:00
dofile(path.."/schem.lua")
2020-04-20 15:57:46 -04:00
dofile(path.."/nodes.lua")
2020-04-24 09:43:24 -04:00
dofile(path.."/biomes.lua")
2020-06-25 00:56:20 -04:00
local aetherportalSchematic = aetherportalSchematic
local
minetest,math,vector,pairs
=
minetest,math,vector,pairs
local abs = math.abs
local random = math.random
local add_vector = vector.add
local sub_vector = vector.subtract
local vec_distance = vector.distance
local new_vector = vector.new
2020-04-24 09:43:24 -04:00
2020-06-25 00:56:20 -04:00
local t_copy = table.copy
local t_insert = table.insert
local t_getn = table.getn
2020-04-24 09:43:24 -04:00
2020-06-25 00:56:20 -04:00
local emerge_area = minetest.emerge_area
local get_node = minetest.get_node
local find_node_near = minetest.find_node_near
local find_nodes_in_area_under_air = minetest.find_nodes_in_area_under_air
local place_schematic = minetest.place_schematic
local bulk_set_node = minetest.bulk_set_node
local aether_channels = {}
local name
minetest.register_on_joinplayer(function(player)
name = player:get_player_name()
aether_channels[name] = minetest.mod_channel_join(name..":aether_teleporters")
end)
2020-04-20 15:57:46 -04:00
2020-04-24 09:43:24 -04:00
--branch out from center
2020-06-25 00:56:20 -04:00
--these are assigned initially for a reason
2020-04-24 09:43:24 -04:00
local a_index = {}
local aether_portal_failure = false
local x_failed = false
2020-06-25 00:56:20 -04:00
local execute_collection
2020-04-24 09:43:24 -04:00
--this can be used globally to create aether portals from obsidian
function create_aether_portal(pos,origin,axis)
--create the origin node for stored memory
if not origin then
origin = pos
aether_portal_failure = false
end
if not axis then
axis = "x"
end
--2d virtual memory map creation (x axis)
if axis == "x" then
for x = -1,1 do
for y = -1,1 do
--index only direct neighbors
2020-06-25 00:56:20 -04:00
if x_failed == false and (abs(x)+abs(y) == 1) then
local i = add_vector(pos,new_vector(x,y,0))
2020-04-24 09:43:24 -04:00
2020-06-25 00:56:20 -04:00
execute_collection = true
2020-04-24 09:43:24 -04:00
if a_index[i.x] and a_index[i.x][i.y] then
if a_index[i.x][i.y][i.z] then
execute_collection = false
end
end
if execute_collection == true then
2020-06-25 00:56:20 -04:00
--print(get_node(i).name)
2020-04-24 09:43:24 -04:00
--index air
2020-06-25 00:56:20 -04:00
if get_node(i).name == "air" then
2020-04-24 09:43:24 -04:00
2020-06-25 00:56:20 -04:00
if vec_distance(i,origin) < 50 then
2020-04-24 09:43:24 -04:00
--add data to both maps
if not a_index[i.x] then a_index[i.x] = {} end
if not a_index[i.x][i.y] then a_index[i.x][i.y] = {} end
a_index[i.x][i.y][i.z] = {aether_portal=1} --get_group(i,"redstone_power")}
--the data to the 3d array must be written to memory before this is executed
--or a stack overflow occurs!!!
--pass down info for activators
create_aether_portal(i,origin,"x")
else
--print("try z")
x_failed = true
a_index = {}
create_aether_portal(origin,origin,"z")
end
2020-06-25 00:56:20 -04:00
elseif get_node(i).name ~= "nether:glowstone" then
2020-04-24 09:43:24 -04:00
x_failed = true
a_index = {}
create_aether_portal(origin,origin,"z")
end
end
end
end
end
--2d virtual memory map creation (z axis)
elseif axis == "z" then
for z = -1,1 do
for y = -1,1 do
--index only direct neighbors
2020-06-25 00:56:20 -04:00
if x_failed == true and aether_portal_failure == false and (abs(z)+abs(y) == 1) then
local i = add_vector(pos,new_vector(0,y,z))
execute_collection = true
2020-04-24 09:43:24 -04:00
if a_index[i.x] and a_index[i.x][i.y] then
if a_index[i.x][i.y][i.z] then
execute_collection = false
end
end
if execute_collection == true then
2020-06-25 00:56:20 -04:00
--print(get_node(i).name)
2020-04-24 09:43:24 -04:00
--index air
2020-06-25 00:56:20 -04:00
if get_node(i).name == "air" then
if vec_distance(i,origin) < 50 then
2020-04-24 09:43:24 -04:00
--add data to both maps
if not a_index[i.x] then a_index[i.x] = {} end
if not a_index[i.x][i.y] then a_index[i.x][i.y] = {} end
2020-06-25 00:56:20 -04:00
a_index[i.x][i.y][i.z] = {aether_portal=1}
2020-04-24 09:43:24 -04:00
--the data to the 3d array must be written to memory before this is executed
--or a stack overflow occurs!!!
--pass down info for activators
create_aether_portal(i,origin,"z")
else
aether_portal_failure = true
a_index = {}
end
2020-06-25 00:56:20 -04:00
elseif get_node(i).name ~= "nether:glowstone" then
2020-04-24 09:43:24 -04:00
aether_portal_failure = true
a_index = {}
end
end
end
end
end
end
end
--creates a aether portal in the aether
--this essentially makes it so you have to move 30 away from one portal to another otherwise it will travel to an existing portal
local aether_origin_pos = nil
local function spawn_portal_into_aether_callback(blockpos, action, calls_remaining, param)
if calls_remaining == 0 then
2020-06-25 00:56:20 -04:00
local portal_exists = find_node_near(aether_origin_pos, 30, {"aether:portal"})
2020-04-24 09:43:24 -04:00
if not portal_exists then
2020-06-25 00:56:20 -04:00
local min = sub_vector(aether_origin_pos,30)
local max = add_vector(aether_origin_pos,30)
local platform = find_nodes_in_area_under_air(min, max, {"aether:dirt","aether:grass"})
2020-04-24 09:43:24 -04:00
if platform and next(platform) then
--print("setting the platform")
2020-06-25 00:56:20 -04:00
local platform_location = platform[random(1,t_getn(platform))]
2020-04-24 09:43:24 -04:00
2020-06-25 00:56:20 -04:00
place_schematic(platform_location, aetherportalSchematic,"0",nil,true,"place_center_x, place_center_z")
2020-04-24 09:43:24 -04:00
else
--print("generate a portal within aetherrack")
2020-06-25 00:56:20 -04:00
place_schematic(aether_origin_pos, aetherportalSchematic,"0",nil,true,"place_center_x, place_center_z")
2020-04-24 09:43:24 -04:00
end
else
--print("portal exists, utilizing")
end
aether_origin_pos = nil
end
end
--creates aether portals in the overworld
local function spawn_portal_into_overworld_callback(blockpos, action, calls_remaining, param)
if calls_remaining == 0 then
2020-06-25 00:56:20 -04:00
local portal_exists = find_node_near(aether_origin_pos, 30, {"aether:portal"})
2020-04-24 09:43:24 -04:00
if not portal_exists then
2020-06-25 00:56:20 -04:00
local min = sub_vector(aether_origin_pos,30)
local max = add_vector(aether_origin_pos,30)
local platform = find_nodes_in_area_under_air(min, max, {"main:stone","main:water","main:grass","main:sand","main:dirt"})
2020-04-24 09:43:24 -04:00
if platform and next(platform) then
--print("setting the platform")
2020-06-25 00:56:20 -04:00
local platform_location = platform[random(1,t_getn(platform))]
2020-04-24 09:43:24 -04:00
2020-06-25 00:56:20 -04:00
place_schematic(platform_location, aetherportalSchematic,"0",nil,true,"place_center_x, place_center_z")
2020-04-24 09:43:24 -04:00
else
--print("generate a portal within overworld stone")
2020-06-25 00:56:20 -04:00
place_schematic(aether_origin_pos, aetherportalSchematic,"0",nil,true,"place_center_x, place_center_z")
2020-04-24 09:43:24 -04:00
end
else
--print("portal exists, utilizing")
end
aether_origin_pos = nil
end
end
2020-04-20 15:57:46 -04:00
2020-04-24 09:43:24 -04:00
local function generate_aether_portal_in_aether(pos)
if pos.y < 20000 then
--center the location to the lava height
2020-06-25 00:56:20 -04:00
pos.y = 25000--+random(-30,30)
2020-04-24 09:43:24 -04:00
aether_origin_pos = pos
2020-06-25 00:56:20 -04:00
local min = sub_vector(aether_origin_pos,30)
local max = add_vector(aether_origin_pos,30)
2020-04-24 09:43:24 -04:00
--force load the area
2020-06-25 00:56:20 -04:00
emerge_area(min, max, spawn_portal_into_aether_callback)
2020-04-24 09:43:24 -04:00
else
--center the location to the water height
2020-06-25 00:56:20 -04:00
pos.y = 0--+random(-30,30)
2020-04-24 09:43:24 -04:00
aether_origin_pos = pos
--prefer height for mountains
2020-06-25 00:56:20 -04:00
local min = sub_vector(aether_origin_pos,new_vector(30,30,30))
local max = add_vector(aether_origin_pos,new_vector(30,120,30))
2020-04-24 09:43:24 -04:00
--force load the area
2020-06-25 00:56:20 -04:00
emerge_area(min, max, spawn_portal_into_overworld_callback)
2020-04-24 09:43:24 -04:00
end
end
--modify the map with the collected data
local function portal_modify_map(n_copy)
local sorted_table = {}
local created_portal = false
for x,datax in pairs(n_copy) do
for y,datay in pairs(datax) do
for z,index in pairs(datay) do
--try to create a return side aether portal
if created_portal == false then
created_portal = true
2020-06-25 00:56:20 -04:00
generate_aether_portal_in_aether(new_vector(x,y,z))
2020-04-24 09:43:24 -04:00
end
2020-06-25 00:56:20 -04:00
t_insert(sorted_table, new_vector(x,y,z))
2020-04-24 09:43:24 -04:00
end
end
end
2020-06-25 00:56:20 -04:00
bulk_set_node(sorted_table, {name="aether:portal"})
2020-04-24 09:43:24 -04:00
end
-------------------------------------------------------------------------------------------
--the teleporter parts - stored here for now so I can read from other functions
local teleporting_player = nil
local function teleport_to_overworld(blockpos, action, calls_remaining, param)
if calls_remaining == 0 then
2020-06-25 00:56:20 -04:00
local portal_exists = find_node_near(aether_origin_pos, 30, {"aether:portal"})
2020-04-24 09:43:24 -04:00
if portal_exists then
--print(teleporting_player)
if teleporting_player then
2020-06-25 00:56:20 -04:00
teleporting_player:set_pos(new_vector(portal_exists.x,portal_exists.y-0.5,portal_exists.z))
2020-04-24 09:43:24 -04:00
end
end
teleporting_player = nil
end
end
local function teleport_to_aether(blockpos, action, calls_remaining, param)
if calls_remaining == 0 then
2020-06-25 00:56:20 -04:00
local portal_exists = find_node_near(aether_origin_pos, 30, {"aether:portal"})
2020-04-24 09:43:24 -04:00
if portal_exists then
--print(teleporting_player)
if teleporting_player then
2020-06-25 00:56:20 -04:00
teleporting_player:set_pos(new_vector(portal_exists.x,portal_exists.y-0.5,portal_exists.z))
2020-04-24 09:43:24 -04:00
end
end
teleporting_player = nil
end
end
2020-04-20 15:57:46 -04:00
2020-04-24 09:43:24 -04:00
--this initializes all teleporter commands from the client
minetest.register_on_modchannel_message(function(channel_name, sender, message)
local channel_decyphered = channel_name:gsub(sender,"")
if channel_decyphered == ":aether_teleporters" then
2020-04-24 09:43:24 -04:00
local player = minetest.get_player_by_name(sender)
local pos = player:get_pos()
if pos.y < 20000 then
--center the location to the lava height
2020-06-25 00:56:20 -04:00
pos.y = 25000--+random(-30,30)
2020-04-24 09:43:24 -04:00
aether_origin_pos = pos
2020-06-25 00:56:20 -04:00
local min = sub_vector(aether_origin_pos,30)
local max = add_vector(aether_origin_pos,30)
2020-04-24 09:43:24 -04:00
--force load the area
teleporting_player = player
2020-06-25 00:56:20 -04:00
emerge_area(min, max, teleport_to_aether)
2020-04-24 09:43:24 -04:00
else
--center the location to the water height
2020-06-25 00:56:20 -04:00
pos.y = 0--+random(-30,30)
2020-04-24 09:43:24 -04:00
aether_origin_pos = pos
--prefer height for mountains
2020-06-25 00:56:20 -04:00
local min = sub_vector(aether_origin_pos,new_vector(30,30,30))
local max = add_vector(aether_origin_pos,new_vector(30,120,30))
2020-04-24 09:43:24 -04:00
--force load the area
teleporting_player = player
2020-06-25 00:56:20 -04:00
emerge_area(min, max, teleport_to_overworld)
2020-04-24 09:43:24 -04:00
end
2020-04-20 15:57:46 -04:00
end
2020-04-24 09:43:24 -04:00
end)
-------------------------------------------------------------------------------------------
-------------------------------------------------------------------------------
local destroy_a_index = {}
local destroy_aether_portal_failure = false
local destroy_aether_portal_failed = false
2020-06-25 00:56:20 -04:00
local execute_collection
2020-04-24 09:43:24 -04:00
--this can be used globally to create aether portals from obsidian
function destroy_aether_portal(pos,origin,axis)
--create the origin node for stored memory
if not origin then
origin = pos
end
--3d virtual memory map creation (x axis)
for x = -1,1 do
for z = -1,1 do
for y = -1,1 do
--index only direct neighbors
2020-06-25 00:56:20 -04:00
if (abs(x)+abs(z)+abs(y) == 1) then
local i = add_vector(pos,new_vector(x,y,z))
2020-04-20 15:57:46 -04:00
2020-06-25 00:56:20 -04:00
execute_collection = true
2020-04-20 15:57:46 -04:00
2020-04-24 09:43:24 -04:00
if destroy_a_index[i.x] and destroy_a_index[i.x][i.y] then
if destroy_a_index[i.x][i.y][i.z] then
execute_collection = false
end
end
2020-04-20 15:57:46 -04:00
2020-04-24 09:43:24 -04:00
if execute_collection == true then
2020-06-25 00:56:20 -04:00
--print(get_node(i).name)
2020-04-24 09:43:24 -04:00
--index air
2020-06-25 00:56:20 -04:00
if get_node(i).name == "aether:portal" then
if vec_distance(i,origin) < 50 then
2020-04-24 09:43:24 -04:00
--add data to both maps
if not destroy_a_index[i.x] then destroy_a_index[i.x] = {} end
if not destroy_a_index[i.x][i.y] then destroy_a_index[i.x][i.y] = {} end
destroy_a_index[i.x][i.y][i.z] = {aether_portal=1} --get_group(i,"redstone_power")}
--the data to the 3d array must be written to memory before this is executed
--or a stack overflow occurs!!!
--pass down info for activators
destroy_aether_portal(i,origin,"z")
end
2020-04-20 15:57:46 -04:00
end
end
end
end
end
2020-04-24 09:43:24 -04:00
end
end
--modify the map with the collected data
2020-06-25 00:56:20 -04:00
local destroy_sorted_table
2020-04-24 09:43:24 -04:00
local function destroy_portal_modify_map(destroy_n_copy)
2020-06-25 00:56:20 -04:00
destroy_sorted_table = {}
2020-04-24 09:43:24 -04:00
for x,datax in pairs(destroy_n_copy) do
for y,datay in pairs(datax) do
for z,index in pairs(datay) do
2020-06-25 00:56:20 -04:00
t_insert(destroy_sorted_table, new_vector(x,y,z))
2020-04-24 09:43:24 -04:00
end
end
end
2020-06-25 00:56:20 -04:00
bulk_set_node(destroy_sorted_table, {name="air"})
2020-04-24 09:43:24 -04:00
end
minetest.register_globalstep(function(dtime)
--if indexes exist then calculate redstone
if a_index and next(a_index) and aether_portal_failure == false then
--create the old version to help with deactivation calculation
2020-06-25 00:56:20 -04:00
local n_copy = t_copy(a_index)
2020-04-24 09:43:24 -04:00
portal_modify_map(n_copy)
aether_portal_failure = false
end
if x_failed == true then
x_failed = false
end
if aether_portal_failure == true then
aether_portal_failure = false
end
--clear the index to avoid cpu looping wasting processing power
a_index = {}
2020-04-20 15:57:46 -04:00
2020-04-24 09:43:24 -04:00
--if indexes exist then calculate redstone
if destroy_a_index and next(destroy_a_index) and destroy_aether_portal_failure == false then
--create the old version to help with deactivation calculation
2020-06-25 00:56:20 -04:00
local destroy_n_copy = t_copy(destroy_a_index)
2020-04-24 09:43:24 -04:00
destroy_portal_modify_map(destroy_n_copy)
end
--clear the index to avoid cpu looping wasting processing power
destroy_a_index = {}
2020-04-20 15:57:46 -04:00
end)