ca77ffe1c7
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>
358 lines
13 KiB
Lua
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"}
|
|
}
|
|
}) |