VoxeLibre/mods/ITEMS/mcl_beacons/init.lua

344 lines
14 KiB
Lua
Raw Normal View History

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 color_list = {"cdf4e9","f9fcfb","7c5e3d","1826c9","16f4f4","f483fc","9712bc","ea1212","adadad","535454","19e52a","549159","ef8813","ebf704","000000","e502d6","e8e3e3"}
local function get_beacon_beam(glass_nodename)
if string.match(glass_nodename, "cyan") then
return "mcl_beacons:beacon_beam_cdf4e9"
elseif string.match(glass_nodename,"white") then
return "mcl_beacons:beacon_beam_f9fcfb"
elseif string.match(glass_nodename,"brown") then
return "mcl_beacons:beacon_beam_7c5e3d"
elseif string.match(glass_nodename,"blue") and not string.match(glass_nodename, "light") then
return "mcl_beacons:beacon_beam_1826c9"
elseif string.match(glass_nodename,"light_blue") then
return "mcl_beacons:beacon_beam_16f4f4"
elseif string.match(glass_nodename,"pink") then
return "mcl_beacons:beacon_beam_f483fc"
elseif string.match(glass_nodename, "purple") then
return "mcl_beacons:beacon_beam_9712bc"
elseif string.match(glass_nodename, "red") then
return "mcl_beacons:beacon_beam_ea1212"
elseif string.match(glass_nodename, "silver") then
return "mcl_beacons:beacon_beam_adadad"
elseif string.match(glass_nodename, "gray") then
return "mcl_beacons:beacon_beam_535454"
elseif string.match(glass_nodename, "lime") then
return "mcl_beacons:beacon_beam_19e52a"
elseif string.match(glass_nodename, "green") then
return "mcl_beacons:beacon_beam_549159"
elseif string.match(glass_nodename, "orange") then
return "mcl_beacons:beacon_beam_ef8813"
elseif string.match(glass_nodename, "yellow") then
return "mcl_beacons:beacon_beam_ebf704"
elseif string.match(glass_nodename, "black") then
return "mcl_beacons:beacon_beam_000000"
elseif string.match(glass_nodename, "magenta") then
return "mcl_beacons:beacon_beam_e502d6"
else
return "mcl_beacons:beacon_beam_e8e3e3"
end
end
for _, color in ipairs(color_list) do
minetest.register_node("mcl_beacons:beacon_beam_"..color, {
tiles = {"^[colorize:#"..color},
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,
})
end
2022-07-25 17:20:51 +02:00
2022-07-22 20:48:36 +02:00
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:")).."]"..
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 21:35:15 +02:00
for y=pos.y+1, pos.y+501 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 ~= "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
2022-07-25 21:35:15 +02:00
if string.match(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
local obstructed = false
2022-07-25 21:35:15 +02:00
for y=pos.y+1, pos.y+501 do
if y >= 31000 then return end
local nodename = minetest.get_node({x=pos.x,y=y, z = pos.z}).name
2022-07-25 21:35:15 +02:00
if nodename ~= "mcl_core:bedrock" and nodename ~= "air" and nodename ~= "ignore" then --ignore means not loaded, let's just assume that's air
if not string.match(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
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", {
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 21:35:15 +02:00
local beam_itemstring = "mcl_beacons:beacon_beam_e8e3e3"
2022-07-25 17:20:51 +02:00
2022-07-25 21:47:03 +02:00
for y = pos.y +1, pos.y + 501 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
beam_itemstring = get_beacon_beam(node.name)
elseif node.name == air then
minetest.set_node({x=pos.x,y=y,z=pos.z},{name=beam_itemstring})
end
end
--if minetest.get_node_group(nodename, "glass") ~= 0 then
2022-07-25 17:20:51 +02:00
if node.name == "air" then
2022-07-25 21:35:15 +02:00
minetest.set_node({x=pos.x,y=y,z=pos.z},{name=beam_itemstring})
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)
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"}
}
})