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
2022-07-25 21:35:15 +02:00
local function get_beacon_beam ( glass_nodename )
if string.match ( glass_nodename , " cyan " ) then
2022-07-31 13:38:07 +02:00
return 1
2022-07-25 21:35:15 +02:00
elseif string.match ( glass_nodename , " white " ) then
2022-07-31 13:38:07 +02:00
return 2
2022-07-25 21:35:15 +02:00
elseif string.match ( glass_nodename , " brown " ) then
2022-07-31 13:38:07 +02:00
return 3
2022-07-25 21:35:15 +02:00
elseif string.match ( glass_nodename , " blue " ) and not string.match ( glass_nodename , " light " ) then
2022-07-31 13:38:07 +02:00
return 4
2022-07-25 21:35:15 +02:00
elseif string.match ( glass_nodename , " light_blue " ) then
2022-07-31 13:38:07 +02:00
return 5
2022-07-25 21:35:15 +02:00
elseif string.match ( glass_nodename , " pink " ) then
2022-07-31 13:38:07 +02:00
return 6
2022-07-25 21:35:15 +02:00
elseif string.match ( glass_nodename , " purple " ) then
2022-07-31 13:38:07 +02:00
return 7
2022-07-25 21:35:15 +02:00
elseif string.match ( glass_nodename , " red " ) then
2022-07-31 13:38:07 +02:00
return 8
2022-07-25 21:35:15 +02:00
elseif string.match ( glass_nodename , " silver " ) then
2022-07-31 13:38:07 +02:00
return 9
2022-07-25 21:35:15 +02:00
elseif string.match ( glass_nodename , " gray " ) then
2022-07-31 13:38:07 +02:00
return 10
2022-07-25 21:35:15 +02:00
elseif string.match ( glass_nodename , " lime " ) then
2022-07-31 13:38:07 +02:00
return 11
2022-07-25 21:35:15 +02:00
elseif string.match ( glass_nodename , " green " ) then
2022-07-31 13:38:07 +02:00
return 12
2022-07-25 21:35:15 +02:00
elseif string.match ( glass_nodename , " orange " ) then
2022-07-31 13:38:07 +02:00
return 13
2022-07-25 21:35:15 +02:00
elseif string.match ( glass_nodename , " yellow " ) then
2022-07-31 13:38:07 +02:00
return 14
2022-07-25 21:35:15 +02:00
elseif string.match ( glass_nodename , " black " ) then
2022-07-31 13:38:07 +02:00
return 15
2022-07-25 21:35:15 +02:00
elseif string.match ( glass_nodename , " magenta " ) then
2022-07-31 13:38:07 +02:00
return 16
2022-07-25 21:35:15 +02:00
else
2022-07-31 13:38:07 +02:00
return 0
2022-07-25 21:35:15 +02:00
end
end
2022-07-31 13:38:07 +02:00
minetest.register_node ( " mcl_beacons:beacon_beam " , {
tiles = { " ^[colorize:#b8bab9 " } ,
drawtype = " nodebox " ,
node_box = {
type = " fixed " ,
fixed = {
{ - 0.1250 , - 0.5000 , - 0.1250 , 0.1250 , 0.5000 , 0.1250 }
}
} ,
pointable = false ,
light_source = 15 ,
walkable = false ,
groups = { not_in_creative_inventory = 1 } ,
_mcl_blast_resistance = 1200 ,
paramtype2 = " color " ,
palette = " beacon_beam_palette.png " ,
palette_index = 0 ,
buildable_to = true ,
} )
2022-07-25 21:35:15 +02:00
2022-07-31 13:38:07 +02:00
mesecon.register_mvps_stopper ( " mcl_beacons:beacon_beam " )
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-31 13:38:07 +02:00
for y = pos.y , pos.y + 301 do
2022-07-25 17:20:51 +02:00
local node = minetest.get_node ( { x = pos.x , y = y , z = pos.z } )
2022-07-26 11:01:39 +02:00
if node.name ~= " air " and node.name ~= " mcl_core:bedrock " and node.name ~= " mcl_core:void " then
2022-07-25 17:20:51 +02:00
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
2022-07-31 13:38:07 +02:00
if node.name == " mcl_beacons:beacon_beam " then
2022-07-25 17:20:51 +02:00
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
2022-07-31 14:25:57 +02:00
for y = pos.y + 1 , pos.y + 100 do
2022-07-31 13:38:07 +02:00
2022-07-23 23:07:18 +02:00
local nodename = minetest.get_node ( { x = pos.x , y = y , z = pos.z } ) . name
2022-07-31 13:38:07 +02:00
if nodename ~= " mcl_core:bedrock " and nodename ~= " air " and nodename ~= " mcl_core:void " and nodename ~= " ignore " then --ignore means not loaded, let's just assume that's air
if nodename ~= " mcl_beacons:beacon_beam " then
2022-07-25 21:35:15 +02:00
if minetest.get_item_group ( nodename , " glass " ) == 0 then
obstructed = true
remove_beacon_beam ( pos )
return
end
end
2022-07-23 23:07:18 +02:00
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-26 10:40:45 +02:00
drawtype = " mesh " ,
collisionbox = { - 0.5 , - 0.5 , - 0.5 , 0.5 , 0.5 , 0.5 } ,
mesh = " mcl_beacon.b3d " ,
tiles = { " beacon_UV.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 21:35:15 +02:00
2022-07-31 13:38:07 +02:00
local beam_palette_index = 0
2022-07-26 11:07:45 +02:00
remove_beacon_beam ( pos )
2022-07-31 13:38:07 +02:00
for y = pos.y + 1 , pos.y + 201 do
2022-07-25 17:20:51 +02:00
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
2022-07-25 21:35:15 +02:00
if y == pos.y + 1 then
if minetest.get_item_group ( node.name , " glass " ) ~= 0 then
2022-07-31 13:38:07 +02:00
beam_palette_index = get_beacon_beam ( node.name )
2022-07-25 21:35:15 +02:00
end
end
2022-07-25 17:20:51 +02:00
if node.name == " air " then
2022-07-31 13:38:07 +02:00
minetest.set_node ( { x = pos.x , y = y , z = pos.z } , { name = " mcl_beacons:beacon_beam " , param2 = beam_palette_index } )
2022-07-25 17:20:51 +02:00
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
2022-07-25 17:54:15 +02:00
local player_pos = player : get_pos ( )
2022-07-23 12:46:02 +02:00
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 )
2022-07-31 13:38:07 +02:00
minetest.register_abm {
label = " update beacon beam " ,
nodenames = { " mcl_beacons:beacon_beam " } ,
interval = 1 ,
chance = 1 ,
action = function ( pos )
local node_below = minetest.get_node ( { x = pos.x , y = pos.y - 1 , z = pos.z } )
local node_above = minetest.get_node ( { x = pos.x , y = pos.y + 1 , z = pos.z } )
if node_below.name == " air " then
remove_beacon_beam ( pos )
elseif node_above.name == " air " then
2022-07-31 14:25:57 +02:00
minetest.set_node ( { x = pos.x , y = pos.y + 1 , z = pos.z } , { name = " mcl_beacons:beacon_beam " , param2 = node_below.param2 } )
2022-07-31 13:38:07 +02:00
end
end ,
}
2022-07-24 12:45:30 +02:00
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 " }
}
} )