VoxeLibre/mods/ITEMS/mcl_beacons/init.lua
chmodsayshello ca77ffe1c7 decrease blockcheck by 25 nodes
that way, even with the lowest possible render distance, all nodes are loaded, if there are no nodes above the beacon (excluding glass etc.), it sets the meta and places the beam 175 blocks high, it extends all the way until the next non-air block if the player is near enoght...

Signed-off-by: chmodsayshello <chmodsayshello@hotmail.com>
2022-07-31 22:22:57 +02:00

358 lines
13 KiB
Lua

local S = minetest.get_translator(minetest.get_current_modname())
--[[
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
]]--
local function get_beacon_beam(glass_nodename)
if string.match(glass_nodename, "cyan") then
return 1
elseif string.match(glass_nodename,"white") then
return 2
elseif string.match(glass_nodename,"brown") then
return 3
elseif string.match(glass_nodename,"blue") and not string.match(glass_nodename, "light") then
return 4
elseif string.match(glass_nodename,"light_blue") then
return 5
elseif string.match(glass_nodename,"pink") then
return 6
elseif string.match(glass_nodename, "purple") then
return 7
elseif string.match(glass_nodename, "red") then
return 8
elseif string.match(glass_nodename, "silver") then
return 9
elseif string.match(glass_nodename, "gray") then
return 10
elseif string.match(glass_nodename, "lime") then
return 11
elseif string.match(glass_nodename, "green") then
return 12
elseif string.match(glass_nodename, "orange") then
return 13
elseif string.match(glass_nodename, "yellow") then
return 14
elseif string.match(glass_nodename, "black") then
return 15
elseif string.match(glass_nodename, "magenta") then
return 16
else
return 0
end
end
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,
})
mesecon.register_mvps_stopper("mcl_beacons:beacon_beam")
local formspec_string=
"size[11,14]"..
"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:")).."]"..
"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]"..
"item_image[5.8,7;1,1;mcl_nether:netherite_ingot]"..
mcl_formspec.get_itemslot_bg(7.2,7,1,1)..
"list[context;input;7.2,7;1,1;]"..
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;]"
local function remove_beacon_beam(pos)
for y=pos.y, 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" and node.name ~= "mcl_core:void" 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
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
local valid_block = false --boolean which stores if block is valid or not
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
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)
end
end
local function globalstep_function(pos,player)
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
local colorblock = minetest.get_node({x=pos.x,y=pos.y+1,z=pos.z})
local obstructed = false
for y=pos.y+1, pos.y+170 do
local nodename = minetest.get_node({x=pos.x,y=y, z = pos.z}).name
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
if minetest.get_item_group(nodename,"glass") == 0 then
obstructed = true
remove_beacon_beam(pos)
return
end
end
end
end
if obstructed then
return
end
effect_player(effect_string,pos,power_level,meta:get_int("effect_level"),player)
end
end
minetest.register_node("mcl_beacons:beacon", {
description = S"Beacon",
drawtype = "mesh",
collisionbox = {-0.5, -0.5, -0.5, 0.5, 0.5, 0.5},
mesh = "mcl_beacon.b3d",
tiles = {"beacon_UV.png"},
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,
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
remove_beacon_beam(pos)
end,
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
if not valid_item then
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
if power_level == 4 then
awards.unlock(sender:get_player_name(),"mcl:maxed_beacon")
end
awards.unlock(sender:get_player_name(),"mcl:beacon")
input:take_item()
inv:set_stack("input",1,input)
local beam_palette_index = 0
remove_beacon_beam(pos)
for y = pos.y +1, pos.y + 201 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 y == pos.y+1 then
if minetest.get_item_group(node.name, "glass") ~= 0 then
beam_palette_index = get_beacon_beam(node.name)
end
end
if node.name == "air" then
minetest.set_node({x=pos.x,y=y,z=pos.z},{name="mcl_beacons:beacon_beam",param2=beam_palette_index})
end
end
globalstep_function(pos,sender)--call it once outside the globalstep so the player gets the effect right after selecting it
end
end
end,
light_source = 15,
groups = {handy=1},
drop = "mcl_beacons:beacon",
sounds = mcl_sounds.node_sound_glass_defaults(),
_mcl_hardness = 3,
})
mesecon.register_mvps_stopper("mcl_beacons:beacon")
mcl_wip.register_wip_item("mcl_beacons:beacon")
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"}
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
local timer = 0
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()
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
globalstep_function(pos,player)
end
end
timer = 0
end
end)
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
minetest.set_node({x=pos.x,y=pos.y+1,z=pos.z},{name="mcl_beacons:beacon_beam",param2=node_above.param2})
end
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"}
}
})