2022-07-25 17:47:36 +02:00
local S = minetest.get_translator ( minetest.get_current_modname ( ) )
2022-07-22 20:48:36 +02:00
--[[
there are strings in meta , which are being used to see which effect will be given to the player ( s )
Valid strings :
swiftness
leaping
strenght
regeneration
] ] --
2022-07-25 17:20:51 +02:00
minetest.register_node ( " mcl_beacons:beacon_beam " , {
tiles = { " ^[colorize:#cdf4e9 " } ,
drawtype = " nodebox " ,
node_box = {
type = " fixed " ,
fixed = {
{ - 0.1250 , - 0.5000 , - 0.1250 , 0.1250 , 0.5000 , 0.1250 }
}
} ,
light_source = 15 ,
walkable = false ,
groups = { not_in_creative_inventory = 1 } ,
_mcl_blast_resistance = 1200 ,
} )
2022-07-22 20:48:36 +02:00
local formspec_string =
" size[11,14] " ..
2022-07-25 17:47:36 +02:00
" label[4.5,0.5; " .. minetest.formspec_escape ( S ( " Beacon: " ) ) .. " ] " ..
" label[0.5,1; " .. minetest.formspec_escape ( S ( " Primary Power: " ) ) .. " ] " ..
" label[0.5,8.25; " .. minetest.formspec_escape ( S ( " Inventory: " ) ) .. " ] " ..
2022-07-22 20:48:36 +02:00
" image[1,1.5;1,1;custom_beacom_symbol_4.png] " ..
" image[1,3;1,1;custom_beacom_symbol_3.png] " ..
" image[1,4.5;1,1;custom_beacom_symbol_2.png] " ..
" image[1,6;1,1;custom_beacom_symbol_1.png] " ..
" image_button[5.2,1.5;1,1;mcl_potions_effect_swift.png;swiftness;] " ..
" image_button[5.2,3;1,1;mcl_potions_effect_leaping.png;leaping;] " ..
" image_button[5.2,4.5;1,1;mcl_potions_effect_strong.png;strenght;] " ..
" image_button[5.2,6;1,1;mcl_potions_effect_regenerating.png;regeneration;] " ..
" item_image[1,7;1,1;mcl_core:diamond] " ..
" item_image[2.2,7;1,1;mcl_core:emerald] " ..
" item_image[3.4,7;1,1;mcl_core:iron_ingot] " ..
" item_image[4.6,7;1,1;mcl_core:gold_ingot] " ..
2022-07-24 13:00:58 +02:00
" item_image[5.8,7;1,1;mcl_nether:netherite_ingot] " ..
2022-07-22 20:48:36 +02:00
2022-07-24 13:00:58 +02:00
mcl_formspec.get_itemslot_bg ( 7.2 , 7 , 1 , 1 ) ..
" list[context;input;7.2,7;1,1;] " ..
2022-07-22 20:48:36 +02:00
mcl_formspec.get_itemslot_bg ( 1 , 9 , 9 , 3 ) ..
" list[current_player;main;1,9;9,3;9] " ..
mcl_formspec.get_itemslot_bg ( 1 , 12.5 , 9 , 1 ) ..
" list[current_player;main;1,12.5;9,1;] "
2022-07-25 17:23:28 +02:00
local function remove_beacon_beam ( pos )
2022-07-25 17:20:51 +02:00
for y = pos.y + 1 , pos.y + 301 do
local node = minetest.get_node ( { x = pos.x , y = y , z = pos.z } )
if node.name ~= " air " and node.name ~= " mcl_core:bedrock " then
if node.name == " ignore " then
minetest.get_voxel_manip ( ) : read_from_map ( { x = pos.x , y = y , z = pos.z } , { x = pos.x , y = y , z = pos.z } )
node = minetest.get_node ( { x = pos.x , y = y , z = pos.z } )
end
if node.name == " mcl_beacons:beacon_beam " then
minetest.remove_node ( { x = pos.x , y = y , z = pos.z } )
end
end
end
end
2022-07-22 20:48:36 +02:00
local function beacon_blockcheck ( pos )
for y_offset = 1 , 4 do
local block_y = pos.y - y_offset
for block_x = ( pos.x - y_offset ) , ( pos.x + y_offset ) do
for block_z = ( pos.z - y_offset ) , ( pos.z + y_offset ) do
2022-07-25 17:23:28 +02:00
local valid_block = false --boolean which stores if block is valid or not
2022-07-22 20:48:36 +02:00
for _ , beacon_block in pairs ( beacon_blocklist ) do
if beacon_block == minetest.get_node ( { x = block_x , y = block_y , z = block_z } ) . name and not valid_block then --is the block in the pyramid a valid beacon block
valid_block = true
end
end
if not valid_block then
return y_offset - 1 --the last layer is complete, this one is missing or incomplete
end
end
end
if y_offset == 4 then --all checks are done, beacon is maxed
return y_offset
end
end
end
2022-07-23 12:46:02 +02:00
2022-07-24 12:32:20 +02:00
local function effect_player ( effect , pos , power_level , effect_level , player )
local distance = vector.distance ( player : get_pos ( ) , pos )
if distance > ( power_level + 1 ) * 10 then return end
if effect == " swiftness " then
mcl_potions.swiftness_func ( player , effect_level , 16 )
elseif effect == " leaping " then
mcl_potions.leaping_func ( player , effect_level , 16 )
elseif effect == " strenght " then
mcl_potions.strength_func ( player , effect_level , 16 )
elseif effect == " regeneration " then
mcl_potions.regeneration_func ( player , effect_level , 16 )
2022-07-23 12:46:02 +02:00
end
end
2022-07-24 12:32:20 +02:00
local function globalstep_function ( pos , player )
2022-07-23 13:06:47 +02:00
local meta = minetest.get_meta ( pos )
local power_level = beacon_blockcheck ( pos )
local effect_string = meta : get_string ( " effect " )
if meta : get_int ( " effect_level " ) == 2 and power_level < 4 then
return
else
2022-07-23 23:07:18 +02:00
local obstructed = false
for y = pos.y + 1 , pos.y + 301 do
if y >= 31000 then return end
local nodename = minetest.get_node ( { x = pos.x , y = y , z = pos.z } ) . name
2022-07-25 17:20:51 +02:00
if nodename ~= " mcl_core:bedrock " and nodename ~= " air " and nodename ~= " mcl_beacons:beacon_beam " and nodename ~= " ignore " then --ignore means not loaded, let's just assume that's air
2022-07-23 23:07:18 +02:00
obstructed = true
2022-07-25 17:20:51 +02:00
remove_beacon_beam ( pos )
2022-07-23 23:07:18 +02:00
return
end
end
2022-07-25 17:20:51 +02:00
if obstructed then
return
end
2022-07-24 12:32:20 +02:00
effect_player ( effect_string , pos , power_level , meta : get_int ( " effect_level " ) , player )
2022-07-23 12:46:02 +02:00
end
end
2022-07-22 20:48:36 +02:00
minetest.register_node ( " mcl_beacons:beacon " , {
2022-07-25 17:47:36 +02:00
description = S " Beacon " ,
2022-07-25 11:59:19 +02:00
drawtype = " glasslike " ,
2022-07-22 20:48:36 +02:00
tiles = {
2022-07-25 11:59:19 +02:00
" default_glass.png^beacon_overlay.png "
2022-07-22 20:48:36 +02:00
} ,
on_construct = function ( pos )
local meta = minetest.get_meta ( pos )
local inv = meta : get_inventory ( )
inv : set_size ( " input " , 1 )
local form = formspec_string
meta : set_string ( " formspec " , form )
end ,
2022-07-25 12:20:15 +02:00
on_destruct = function ( pos )
local meta = minetest.get_meta ( pos )
local input = meta : get_inventory ( ) : get_stack ( " input " , 1 )
if not input : is_empty ( ) then
local p = { x = pos.x + math.random ( 0 , 10 ) / 10 - 0.5 , y = pos.y , z = pos.z + math.random ( 0 , 10 ) / 10 - 0.5 } --from mcl_anvils
minetest.add_item ( p , input )
end
2022-07-25 17:20:51 +02:00
remove_beacon_beam ( pos )
2022-07-25 12:20:15 +02:00
end ,
2022-07-22 20:48:36 +02:00
on_receive_fields = function ( pos , formname , fields , sender )
if fields.swiftness or fields.regeneration or fields.leaping or fields.strenght then
local sender_name = sender : get_player_name ( )
local power_level = beacon_blockcheck ( pos )
if minetest.is_protected ( pos , sender_name ) then
minetest.record_protection_violation ( pos , sender_name )
return
elseif power_level == 0 then
return
end
local meta = minetest.get_meta ( pos )
local inv = meta : get_inventory ( )
local input = inv : get_stack ( " input " , 1 )
if input : is_empty ( ) then
return
end
local valid_item = false
for _ , item in ipairs ( beacon_fuellist ) do
if input : get_name ( ) == item then
valid_item = true
end
end
2022-07-23 13:06:47 +02:00
if not valid_item then
2022-07-22 20:48:36 +02:00
return
end
local successful = false
if fields.swiftness then
if power_level == 4 then
minetest.get_meta ( pos ) : set_int ( " effect_level " , 2 )
else
minetest.get_meta ( pos ) : set_int ( " effect_level " , 1 )
end
minetest.get_meta ( pos ) : set_string ( " effect " , " swiftness " )
successful = true
elseif fields.leaping and power_level >= 2 then
if power_level == 4 then
minetest.get_meta ( pos ) : set_int ( " effect_level " , 2 )
else
minetest.get_meta ( pos ) : set_int ( " effect_level " , 1 )
end
minetest.get_meta ( pos ) : set_string ( " effect " , " leaping " )
successful = true
elseif fields.strenght and power_level >= 3 then
if power_level == 4 then
minetest.get_meta ( pos ) : set_int ( " effect_level " , 2 )
else
minetest.get_meta ( pos ) : set_int ( " effect_level " , 1 )
end
minetest.get_meta ( pos ) : set_string ( " effect " , " strenght " )
successful = true
elseif fields.regeneration and power_level == 4 then
minetest.get_meta ( pos ) : set_int ( " effect_level " , 2 )
minetest.get_meta ( pos ) : set_string ( " effect " , " regeneration " )
successful = true
end
if successful then
2022-07-24 12:32:20 +02:00
if power_level == 4 then
awards.unlock ( sender : get_player_name ( ) , " mcl:maxed_beacon " )
end
awards.unlock ( sender : get_player_name ( ) , " mcl:beacon " )
2022-07-22 20:48:36 +02:00
input : take_item ( )
inv : set_stack ( " input " , 1 , input )
2022-07-25 17:20:51 +02:00
for y = pos.y + 1 , pos.y + 301 do
local node = minetest.get_node ( { x = pos.x , y = y , z = pos.z } )
if node.name == ignore then
minetest.get_voxel_manip ( ) : read_from_map ( { x = pos.x , y = y , z = pos.z } , { x = pos.x , y = y , z = pos.z } )
node = minetest.get_node ( { x = pos.x , y = y , z = pos.z } )
end
if node.name == " air " then
minetest.set_node ( { x = pos.x , y = y , z = pos.z } , { name = " mcl_beacons:beacon_beam " } )
end
end
2022-07-24 12:32:20 +02:00
globalstep_function ( pos , sender ) --call it once outside the globalstep so the player gets the effect right after selecting it
2022-07-22 20:48:36 +02:00
end
end
end ,
light_source = 15 ,
2022-07-24 12:52:57 +02:00
groups = { handy = 1 } ,
drop = " mcl_beacons:beacon " ,
2022-07-22 20:48:36 +02:00
sounds = mcl_sounds.node_sound_glass_defaults ( ) ,
2022-07-24 12:52:57 +02:00
_mcl_hardness = 3 ,
2022-07-22 20:48:36 +02:00
} )
mesecon.register_mvps_stopper ( " mcl_beacons:beacon " )
mcl_wip.register_wip_item ( " mcl_beacons:beacon " )
2022-07-24 13:00:58 +02:00
beacon_blocklist = { " mcl_core:diamondblock " , " mcl_core:ironblock " , " mcl_core:goldblock " , " mcl_core:emeraldblock " , " mcl_nether:netheriteblock " } --this is supposed to be a global, don't change that!
beacon_fuellist = { " mcl_core:diamond " , " mcl_core:emerald " , " mcl_core:iron_ingot " , " mcl_core:gold_ingot " , " mcl_nether:netherite_ingot " }
2022-07-22 20:48:36 +02:00
function register_beaconblock ( itemstring ) --API function for other mods
table.insert ( beacon_blocklist , itemstring )
end
function register_beaconfuel ( itemstring )
table.insert ( beacon_fuellist , itemstring )
end
2022-07-23 12:46:02 +02:00
local timer = 0
2022-07-22 20:48:36 +02:00
2022-07-23 12:46:02 +02:00
minetest.register_globalstep ( function ( dtime )
timer = timer + dtime
if timer >= 3 then
for _ , player in ipairs ( minetest.get_connected_players ( ) ) do
local player_pos = player.get_pos ( player )
local pos_list = minetest.find_nodes_in_area ( { x = player_pos.x - 50 , y = player_pos.y - 50 , z = player_pos.z - 50 } , { x = player_pos.x + 50 , y = player_pos.y + 50 , z = player_pos.z + 50 } , " mcl_beacons:beacon " )
for _ , pos in ipairs ( pos_list ) do
2022-07-24 12:32:20 +02:00
globalstep_function ( pos , player )
2022-07-23 12:46:02 +02:00
end
end
timer = 0
2022-07-22 20:48:36 +02:00
end
2022-07-24 12:45:30 +02:00
end )
minetest.register_craft ( {
output = " mcl_beacons:beacon " ,
recipe = {
{ " mcl_core:glass " , " mcl_core:glass " , " mcl_core:glass " } ,
{ " mcl_core:glass " , " mcl_mobitems:nether_star " , " mcl_core:glass " } ,
{ " mcl_core:obsidian " , " mcl_core:obsidian " , " mcl_core:obsidian " }
}
} )