diff --git a/README.md b/README.md index 7d860d2c8..7c3cecece 100644 --- a/README.md +++ b/README.md @@ -66,7 +66,7 @@ Use the `/giveme` chat command to obtain them. See the in-game help for an explanation. ## Installation -This game requires [Minetest](http://minetest.net) to run (version 5.4.0 or +This game requires [Minetest](http://minetest.net) to run (version 5.3.0 or later). So you need to install Minetest first. Only stable versions of Minetest are officially supported. There is no support for running MineClone 2 in development versions of Minetest. diff --git a/mods/ENTITIES/mobs_mc/enderman.lua b/mods/ENTITIES/mobs_mc/enderman.lua index 6c87b9305..9c47e98fc 100644 --- a/mods/ENTITIES/mobs_mc/enderman.lua +++ b/mods/ENTITIES/mobs_mc/enderman.lua @@ -323,7 +323,7 @@ mobs:register_mob("mobs_mc:enderman", { -- self:teleport(nil) -- self.state = "" --else - if self.attack ~= nil then + if self.attack ~= nil and not minetest.settings:get_bool("creative_mode") then self.state = 'attack' end --end diff --git a/mods/HUD/mcl_bossbars/init.lua b/mods/HUD/mcl_bossbars/init.lua index 8ed08a613..f1d99e013 100644 --- a/mods/HUD/mcl_bossbars/init.lua +++ b/mods/HUD/mcl_bossbars/init.lua @@ -39,7 +39,7 @@ local last_id = 0 function mcl_bossbars.add_bar(player, def, dynamic, priority) local name = player:get_player_name() local bars = mcl_bossbars.bars[name] - local bar = {text = def.text, priority = priority or 0} + local bar = {text = def.text, priority = priority or 0, timeout = def.timeout} bar.color, bar.image = get_color_info(def.color, def.percentage) if dynamic then for _, other in pairs(bars) do @@ -119,7 +119,7 @@ minetest.register_on_leaveplayer(function(player) mcl_bossbars.bars[name] = nil end) -minetest.register_globalstep(function() +minetest.register_globalstep(function(dtime) for _, player in pairs(minetest.get_connected_players()) do local name = player:get_player_name() local bars = mcl_bossbars.bars[name] @@ -134,7 +134,12 @@ minetest.register_globalstep(function() local hud = table.remove(huds, 1) if bar and bar.id then - table.insert(bars_new, bar) + if bar.timeout then + bar.timeout = bar.timeout - dtime + end + if not bar.timeout or bar.timeout > 0 then + table.insert(bars_new, bar) + end end if bar and not hud then diff --git a/mods/ITEMS/REDSTONE/mesecons_torch/init.lua b/mods/ITEMS/REDSTONE/mesecons_torch/init.lua index c7c4a4ca2..9aefae96c 100644 --- a/mods/ITEMS/REDSTONE/mesecons_torch/init.lua +++ b/mods/ITEMS/REDSTONE/mesecons_torch/init.lua @@ -117,83 +117,90 @@ minetest.register_craft({ {"mcl_core:stick"},} }) -mcl_torches.register_torch("mesecon_torch_off", S("Redstone Torch (off)"), - nil, - nil, - "jeija_torches_off.png", - "mcl_torches_torch_floor.obj", "mcl_torches_torch_wall.obj", - {"jeija_torches_off.png"}, - 0, - {dig_immediate=3, dig_by_water=1, redstone_torch=2, mesecon_ignore_opaque_dig=1, not_in_creative_inventory=1}, - mcl_sounds.node_sound_wood_defaults(), - { - mesecons = { - receptor = { - state = mesecon.state.off, - rules = torch_get_output_rules, - }, - effector = { - state = mesecon.state.on, - rules = torch_get_input_rules, - action_off = torch_action_off, - }, +local off_def = { + name = "mesecon_torch_off", + description = S("Redstone Torch (off)"), + doc_items_create_entry = false, + icon = "jeija_torches_off.png", + tiles = {"jeija_torches_off.png"}, + light = 0, + groups = {dig_immediate=3, dig_by_water=1, redstone_torch=2, mesecon_ignore_opaque_dig=1, not_in_creative_inventory=1}, + sounds = mcl_sounds.node_sound_wood_defaults(), + drop = "mesecons_torch:mesecon_torch_on", +} + +mcl_torches.register_torch(off_def) + +local off_override = { + mesecons = { + receptor = { + state = mesecon.state.off, + rules = torch_get_output_rules, + }, + effector = { + state = mesecon.state.on, + rules = torch_get_input_rules, + action_off = torch_action_off, }, - drop = "mesecons_torch:mesecon_torch_on", - _doc_items_create_entry = false, } -) +} -mcl_torches.register_torch("mesecon_torch_overheated", S("Redstone Torch (overheated)"), - nil, - nil, - "jeija_torches_off.png", - "mcl_torches_torch_floor.obj", "mcl_torches_torch_wall.obj", - {"jeija_torches_off.png"}, - 0, - {dig_immediate=3, dig_by_water=1, redstone_torch=2, mesecon_ignore_opaque_dig=1, not_in_creative_inventory=1}, - mcl_sounds.node_sound_wood_defaults(), - { - drop = "mesecons_torch:mesecon_torch_on", - _doc_items_create_entry = false, - on_timer = function(pos, elapsed) - if not mesecon.is_powered(pos) then - local node = minetest.get_node(pos) - torch_action_off(pos, node) - end - end, - } -) +minetest.override_item("mesecons_torch:mesecon_torch_off", off_override) +minetest.override_item("mesecons_torch:mesecon_torch_off_wall", off_override) +local overheated_def = table.copy(off_def) +overheated_def.name = "mesecon_torch_overheated" +overheated_def.description = S("Redstone Torch (overheated)") +mcl_torches.register_torch(overheated_def) -mcl_torches.register_torch("mesecon_torch_on", S("Redstone Torch"), - S("A redstone torch is a redstone component which can be used to invert a redstone signal. It supplies its surrounding blocks with redstone power, except for the block it is attached to. A redstone torch is normally lit, but it can also be turned off by powering the block it is attached to. While unlit, a redstone torch does not power anything."), - S("Redstone torches can be placed at the side and on the top of full solid opaque blocks."), - "jeija_torches_on.png", - "mcl_torches_torch_floor.obj", "mcl_torches_torch_wall.obj", - {"jeija_torches_on.png"}, - 7, - {dig_immediate=3, dig_by_water=1, redstone_torch=1, mesecon_ignore_opaque_dig=1}, - mcl_sounds.node_sound_wood_defaults(), - { - on_destruct = function(pos, oldnode) +local overheated_override = { + on_timer = function(pos, elapsed) + if not mesecon.is_powered(pos) then local node = minetest.get_node(pos) - torch_action_on(pos, node) - end, - mesecons = { - receptor = { - state = mesecon.state.on, - rules = torch_get_output_rules - }, - effector = { - state = mesecon.state.off, - rules = torch_get_input_rules, - action_on = torch_action_on, - }, + torch_action_off(pos, node) + end + end +} + +minetest.override_item("mesecons_torch:mesecon_torch_overheated", overheated_override) +minetest.override_item("mesecons_torch:mesecon_torch_overheated_wall", overheated_override) + +local on_def = { + name = "mesecon_torch_on", + description = S("Redstone Torch"), + doc_items_longdesc = S("A redstone torch is a redstone component which can be used to invert a redstone signal. It supplies its surrounding blocks with redstone power, except for the block it is attached to. A redstone torch is normally lit, but it can also be turned off by powering the block it is attached to. While unlit, a redstone torch does not power anything."), + doc_items_usagehelp = S("Redstone torches can be placed at the side and on the top of full solid opaque blocks."), + icon = "jeija_torches_on.png", + tiles = {"jeija_torches_on.png"}, + light = 7, + groups = {dig_immediate=3, dig_by_water=1, redstone_torch=1, mesecon_ignore_opaque_dig=1}, + sounds = mcl_sounds.node_sound_wood_defaults(), +} + +mcl_torches.register_torch(on_def) + +local on_override = { + on_destruct = function(pos, oldnode) + local node = minetest.get_node(pos) + torch_action_on(pos, node) + end, + mesecons = { + receptor = { + state = mesecon.state.on, + rules = torch_get_output_rules }, - _tt_help = S("Provides redstone power when it's not powered itself"), - } -) + effector = { + state = mesecon.state.off, + rules = torch_get_input_rules, + action_on = torch_action_on, + }, + }, + _tt_help = S("Provides redstone power when it's not powered itself"), +} + +minetest.override_item("mesecons_torch:mesecon_torch_on", on_override) +minetest.override_item("mesecons_torch:mesecon_torch_on_wall", on_override) minetest.register_node("mesecons_torch:redstoneblock", { description = S("Block of Redstone"), diff --git a/mods/ITEMS/mcl_doors/api_doors.lua b/mods/ITEMS/mcl_doors/api_doors.lua index f3dd0f469..909bb47e4 100644 --- a/mods/ITEMS/mcl_doors/api_doors.lua +++ b/mods/ITEMS/mcl_doors/api_doors.lua @@ -1,4 +1,5 @@ local S = minetest.get_translator("mcl_doors") +local minetest_get_meta = minetest.get_meta -- This helper function calls on_place_node callbacks. local function on_place_node(place_to, newnode, @@ -164,14 +165,14 @@ function mcl_doors:register_door(name, def) end if def.only_placer_can_open then - local meta = minetest.get_meta(pt) + local meta = minetest_get_meta(pt) meta:set_string("doors_owner", "") - meta = minetest.get_meta(pt2) + meta = minetest_get_meta(pt2) meta:set_string("doors_owner", "") end - local meta1 = minetest.get_meta(pt) - local meta2 = minetest.get_meta(pt2) + local meta1 = minetest_get_meta(pt) + local meta2 = minetest_get_meta(pt2) -- save mirror state for the correct door if left_node.name:sub(1, #name) == name then meta1:set_int("is_mirrored", 1) @@ -198,9 +199,9 @@ function mcl_doors:register_door(name, def) local tb = def.tiles_bottom local function on_open_close(pos, dir, check_name, replace, replace_dir) - local meta1 = minetest.get_meta(pos) + local meta1 = minetest_get_meta(pos) pos.y = pos.y+dir - local meta2 = minetest.get_meta(pos) + local meta2 = minetest_get_meta(pos) -- if name of other door is not the same as check_name -> return if not minetest.get_node(pos).name == check_name then @@ -254,7 +255,7 @@ function mcl_doors:register_door(name, def) if not def.only_placer_can_open then return true end - local meta = minetest.get_meta(pos) + local meta = minetest_get_meta(pos) local pn = player:get_player_name() return meta:get_string("doors_owner") == pn end @@ -292,10 +293,15 @@ function mcl_doors:register_door(name, def) sounds = def.sounds, after_destruct = function(bottom, oldnode) - minetest.add_item(bottom, name) - local top = { x = bottom.x, y = bottom.y + 1, z = bottom.z } - if minetest.get_node(bottom).name ~= name.."_b_2" and minetest.get_node(top).name == name.."_t_1" then - minetest.remove_node(top) + local meta_bottom = minetest_get_meta(bottom) + if meta_bottom:get_int("rotation") == 1 then + meta_bottom:set_int("rotation", 0) + else + minetest.add_item(bottom, name) + local top = { x = bottom.x, y = bottom.y + 1, z = bottom.z } + if minetest.get_node(bottom).name ~= name.."_b_2" and minetest.get_node(top).name == name.."_t_1" then + minetest.remove_node(top) + end end end, @@ -305,13 +311,19 @@ function mcl_doors:register_door(name, def) action_on = on_mesecons_signal_open, }}, - on_rotate = function(pos, node, user, mode, param2) + on_rotate = function(bottom, node, user, mode, param2) if mode == screwdriver.ROTATE_FACE then - minetest.remove_node(pos) - node.param2 = screwdriver.rotate.facedir(pos, node, mode) - minetest.set_node(pos, node) + local meta_bottom = minetest_get_meta(bottom) + meta_bottom:set_int("rotation", 1) + node.param2 = screwdriver.rotate.facedir(bottom, node, mode) + minetest.swap_node(bottom, node) + + local top = {x=bottom.x,y=bottom.y+1,z=bottom.z} + local meta_top = minetest_get_meta(top) + meta_top:set_int("rotation", 1) node.name = name .."_t_1" - minetest.set_node({x=pos.x,y=pos.y+1,z=pos.z}, node) + minetest.swap_node(top, node) + return true end return false @@ -353,9 +365,14 @@ function mcl_doors:register_door(name, def) sounds = def.sounds, after_destruct = function(top, oldnode) - local bottom = { x = top.x, y = top.y - 1, z = top.z } - if minetest.get_node(top).name ~= name.."_t_2" and minetest.get_node(bottom).name == name.."_b_1" and oldnode.name == name.."_t_1" then - minetest.dig_node(bottom) + local meta_top = minetest_get_meta(top) + if meta_top:get_int("rotation") == 1 then + meta_top:set_int("rotation", 0) + else + local bottom = { x = top.x, y = top.y - 1, z = top.z } + if minetest.get_node(top).name ~= name.."_t_2" and minetest.get_node(bottom).name == name.."_b_1" and oldnode.name == name.."_t_1" then + minetest.dig_node(bottom) + end end end, @@ -366,13 +383,19 @@ function mcl_doors:register_door(name, def) rules = mesecon.rules.flat, }}, - on_rotate = function(pos, node, user, mode, param2) + on_rotate = function(top, node, user, mode, param2) if mode == screwdriver.ROTATE_FACE then - minetest.remove_node(pos) - node.param2 = screwdriver.rotate.facedir(pos, node, mode) - minetest.set_node(pos, node) + local meta_top = minetest_get_meta(top) + meta_top:set_int("rotation", 1) + node.param2 = screwdriver.rotate.facedir(top, node, mode) + minetest.swap_node(top, node) + + local bottom = {x=top.x,y=top.y-1,z=top.z} + local meta_bottom = minetest_get_meta(bottom) + meta_bottom:set_int("rotation", 1) node.name = name .."_b_1" - minetest.set_node({x=pos.x,y=pos.y-1,z=pos.z}, node) + minetest.swap_node(bottom, node) + return true end return false @@ -414,10 +437,15 @@ function mcl_doors:register_door(name, def) sounds = def.sounds, after_destruct = function(bottom, oldnode) - minetest.add_item(bottom, name) - local top = { x = bottom.x, y = bottom.y + 1, z = bottom.z } - if minetest.get_node(bottom).name ~= name.."_b_1" and minetest.get_node(top).name == name.."_t_2" then - minetest.remove_node(top) + local meta_bottom = minetest_get_meta(bottom) + if meta_bottom:get_int("rotation") == 1 then + meta_bottom:set_int("rotation", 0) + else + local top = { x = bottom.x, y = bottom.y + 1, z = bottom.z } + minetest.add_item(bottom, name) + if minetest.get_node(bottom).name ~= name.."_b_1" and minetest.get_node(top).name == name.."_t_2" then + minetest.remove_node(top) + end end end, @@ -427,13 +455,19 @@ function mcl_doors:register_door(name, def) action_off = on_mesecons_signal_close, }}, - on_rotate = function(pos, node, user, mode, param2) + on_rotate = function(bottom, node, user, mode, param2) if mode == screwdriver.ROTATE_FACE then - minetest.remove_node(pos) - node.param2 = screwdriver.rotate.facedir(pos, node, mode) - minetest.set_node(pos, node) + local meta_bottom = minetest_get_meta(bottom) + meta_bottom:set_int("rotation", 1) + node.param2 = screwdriver.rotate.facedir(bottom, node, mode) + minetest.swap_node(bottom, node) + + local top = {x=bottom.x,y=bottom.y+1,z=bottom.z} + local meta_top = minetest_get_meta(top) + meta_top:set_int("rotation", 1) node.name = name .."_t_2" - minetest.set_node({x=pos.x,y=pos.y+1,z=pos.z}, node) + minetest.swap_node(top, node) + return true end return false @@ -475,9 +509,14 @@ function mcl_doors:register_door(name, def) sounds = def.sounds, after_destruct = function(top, oldnode) - local bottom = { x = top.x, y = top.y - 1, z = top.z } - if minetest.get_node(top).name ~= name.."_t_1" and minetest.get_node(bottom).name == name.."_b_2" and oldnode.name == name.."_t_2" then - minetest.dig_node(bottom) + local meta_top = minetest_get_meta(top) + if meta_top:get_int("rotation") == 1 then + meta_top:set_int("rotation", 0) + else + local bottom = { x = top.x, y = top.y - 1, z = top.z } + if minetest.get_node(top).name ~= name.."_t_1" and minetest.get_node(bottom).name == name.."_b_2" and oldnode.name == name.."_t_2" then + minetest.dig_node(bottom) + end end end, @@ -488,13 +527,19 @@ function mcl_doors:register_door(name, def) rules = mesecon.rules.flat, }}, - on_rotate = function(pos, node, user, mode, param2) + on_rotate = function(top, node, user, mode, param2) if mode == screwdriver.ROTATE_FACE then - minetest.remove_node(pos) - node.param2 = screwdriver.rotate.facedir(pos, node, mode) - minetest.set_node(pos, node) + local meta_top = minetest_get_meta(top) + meta_top:set_int("rotation", 1) + node.param2 = screwdriver.rotate.facedir(top, node, mode) + minetest.swap_node(top, node) + + local bottom = {x=top.x,y=top.y-1,z=top.z} + local meta_bottom = minetest_get_meta(bottom) + meta_bottom:set_int("rotation", 1) node.name = name .."_b_2" - minetest.set_node({x=pos.x,y=pos.y-1,z=pos.z}, node) + minetest.swap_node(bottom, node) + return true end return false diff --git a/mods/ITEMS/mcl_fireworks/README.txt b/mods/ITEMS/mcl_fireworks/README.txt new file mode 100644 index 000000000..4cf71fc9b --- /dev/null +++ b/mods/ITEMS/mcl_fireworks/README.txt @@ -0,0 +1,7 @@ +Firework mod for Mineclone 2 + +by NO11 and and some parts by j45 + +Sound credits: + +* mcl_firework_rocket.ogg (tnt_ignite.ogg): Own derivate work of sound by Ned Bouhalassa (CC0) created in 2005, source: diff --git a/mods/ITEMS/mcl_fireworks/config.txt b/mods/ITEMS/mcl_fireworks/config.txt new file mode 100644 index 000000000..5a12a1f52 --- /dev/null +++ b/mods/ITEMS/mcl_fireworks/config.txt @@ -0,0 +1,2 @@ +name = mcl_firework +author = NO11, j45 diff --git a/mods/ITEMS/mcl_fireworks/crafting.lua b/mods/ITEMS/mcl_fireworks/crafting.lua new file mode 100644 index 000000000..a9e156aa6 --- /dev/null +++ b/mods/ITEMS/mcl_fireworks/crafting.lua @@ -0,0 +1,17 @@ +minetest.register_craft({ + type = "shapeless", + output = "mcl_fireworks:rocket_1 3", + recipe = {"mcl_core:paper", "mcl_mobitems:gunpowder"}, +}) + +minetest.register_craft({ + type = "shapeless", + output = "mcl_fireworks:rocket_2 3", + recipe = {"mcl_core:paper", "mcl_mobitems:gunpowder", "mcl_mobitems:gunpowder"}, +}) + +minetest.register_craft({ + type = "shapeless", + output = "mcl_fireworks:rocket_3 3", + recipe = {"mcl_core:paper", "mcl_mobitems:gunpowder", "mcl_mobitems:gunpowder", "mcl_mobitems:gunpowder"}, +}) \ No newline at end of file diff --git a/mods/ITEMS/mcl_fireworks/init.lua b/mods/ITEMS/mcl_fireworks/init.lua new file mode 100644 index 000000000..cd1922580 --- /dev/null +++ b/mods/ITEMS/mcl_fireworks/init.lua @@ -0,0 +1,4 @@ +local path = minetest.get_modpath("mcl_fireworks") + +dofile(path .. "/register.lua") +dofile(path .. "/crafting.lua") \ No newline at end of file diff --git a/mods/ITEMS/mcl_fireworks/locale/mcl_fireworks.de.tr b/mods/ITEMS/mcl_fireworks/locale/mcl_fireworks.de.tr new file mode 100644 index 000000000..9f9098103 --- /dev/null +++ b/mods/ITEMS/mcl_fireworks/locale/mcl_fireworks.de.tr @@ -0,0 +1,3 @@ +# textdomain: mcl_fireworks +Firework Rocket=Feuerwerksrakete +Flight Duration:=Flugdauer: \ No newline at end of file diff --git a/mods/ITEMS/mcl_fireworks/register.lua b/mods/ITEMS/mcl_fireworks/register.lua new file mode 100644 index 000000000..cce36042a --- /dev/null +++ b/mods/ITEMS/mcl_fireworks/register.lua @@ -0,0 +1,69 @@ +local S = minetest.get_translator("mcl_fireworks") + +player_rocketing = {} + +local help = S("Flight Duration:") +local description = S("Firework Rocket") +local rocket_sound = function() + minetest.sound_play("mcl_fireworks_rocket") +end + +minetest.register_craftitem("mcl_fireworks:rocket_1", { + description = description, + _tt_help = help.." 1", + inventory_image = "mcl_fireworks_rocket.png", + stack_max = 64, + on_use = function(itemstack, user, pointed_thing) + local torso = user:get_inventory():get_stack("armor", 3) + if torso and torso:get_name() == "mcl_armor:elytra" and player_rocketing[user] ~= true then + player_rocketing[user] = true + minetest.after(2.2, function() + player_rocketing[user] = false + end) + itemstack:take_item() + --user:add_player_velocity(vector.multiply(user:get_look_dir(), 20)) + rocket_sound() + end + return itemstack + end, +}) + +minetest.register_craftitem("mcl_fireworks:rocket_2", { + description = description, + _tt_help = help.." 2", + inventory_image = "mcl_fireworks_rocket.png", + stack_max = 64, + on_use = function(itemstack, user, pointed_thing) + local torso = user:get_inventory():get_stack("armor", 3) + if torso and torso:get_name() == "mcl_armor:elytra" and player_rocketing[user] ~= true then + player_rocketing[user] = true + minetest.after(4.5, function() + player_rocketing[user] = false + end) + itemstack:take_item() + --user:add_player_velocity(vector.multiply(user:get_look_dir(), 20)) + rocket_sound() + end + return itemstack + end, +}) + +minetest.register_craftitem("mcl_fireworks:rocket_3", { + description = description, + _tt_help = help.." 3", + inventory_image = "mcl_fireworks_rocket.png", + stack_max = 64, + on_use = function(itemstack, user, pointed_thing) + local torso = user:get_inventory():get_stack("armor", 3) + if torso and torso:get_name() == "mcl_armor:elytra" and player_rocketing[user] ~= true then + player_rocketing[user] = true + minetest.after(6, function() + player_rocketing[user] = false + end) + itemstack:take_item() + --user:add_player_velocity(vector.multiply(user:get_look_dir(), 20)) + rocket_sound() + end + return itemstack + end, +}) diff --git a/mods/ITEMS/mcl_fireworks/sounds/mcl_fireworks_rocket.ogg b/mods/ITEMS/mcl_fireworks/sounds/mcl_fireworks_rocket.ogg new file mode 100644 index 000000000..aa232f0de Binary files /dev/null and b/mods/ITEMS/mcl_fireworks/sounds/mcl_fireworks_rocket.ogg differ diff --git a/mods/ITEMS/mcl_fireworks/textures/mcl_fireworks_rocket.png b/mods/ITEMS/mcl_fireworks/textures/mcl_fireworks_rocket.png new file mode 100644 index 000000000..682a8c40d Binary files /dev/null and b/mods/ITEMS/mcl_fireworks/textures/mcl_fireworks_rocket.png differ diff --git a/mods/ITEMS/mcl_potions/functions.lua b/mods/ITEMS/mcl_potions/functions.lua index 996637aa7..211cf50b0 100644 --- a/mods/ITEMS/mcl_potions/functions.lua +++ b/mods/ITEMS/mcl_potions/functions.lua @@ -701,6 +701,10 @@ function mcl_potions.healing_func(player, hp) local obj = player:get_luaentity() + if player:get_hp() == 0 then + return + end + if obj and obj.harmed_by_heal then hp = -hp end if hp > 0 then diff --git a/mods/ITEMS/mcl_torches/api.lua b/mods/ITEMS/mcl_torches/api.lua new file mode 100644 index 000000000..ced566bbd --- /dev/null +++ b/mods/ITEMS/mcl_torches/api.lua @@ -0,0 +1,287 @@ +local spawn_flames_floor = function(pos) + -- Flames + mcl_particles.add_node_particlespawner(pos, { + amount = 8, + time = 0, + minpos = vector.add(pos, { x = -0.1, y = 0.05, z = -0.1 }), + maxpos = vector.add(pos, { x = 0.1, y = 0.15, z = 0.1 }), + minvel = { x = -0.01, y = 0, z = -0.01 }, + maxvel = { x = 0.01, y = 0.1, z = 0.01 }, + minexptime = 0.3, + maxexptime = 0.6, + minsize = 0.7, + maxsize = 2, + texture = "mcl_particles_flame.png", + glow = minetest.registered_nodes[minetest.get_node(pos).name].light_source, + }, "low") + -- Smoke + mcl_particles.add_node_particlespawner(pos, { + amount = 0.5, + time = 0, + minpos = vector.add(pos, { x = -1/16, y = 0.04, z = -1/16 }), + maxpos = vector.add(pos, { x = -1/16, y = 0.06, z = -1/16 }), + minvel = { x = 0, y = 0.5, z = 0 }, + maxvel = { x = 0, y = 0.6, z = 0 }, + minexptime = 2.0, + maxexptime = 2.0, + minsize = 1.5, + maxsize = 1.5, + texture = "mcl_particles_smoke_anim.png", + animation = { + type = "vertical_frames", + aspect_w = 8, + aspect_h = 8, + length = 2.05, + }, + }, "medium") +end + +local spawn_flames_wall = function(pos) + local minrelpos, maxrelpos + local node = minetest.get_node(pos) + local dir = minetest.wallmounted_to_dir(node.param2) + if dir.x < 0 then + minrelpos = { x = -0.38, y = 0.04, z = -0.1 } + maxrelpos = { x = -0.2, y = 0.14, z = 0.1 } + elseif dir.x > 0 then + minrelpos = { x = 0.2, y = 0.04, z = -0.1 } + maxrelpos = { x = 0.38, y = 0.14, z = 0.1 } + elseif dir.z < 0 then + minrelpos = { x = -0.1, y = 0.04, z = -0.38 } + maxrelpos = { x = 0.1, y = 0.14, z = -0.2 } + elseif dir.z > 0 then + minrelpos = { x = -0.1, y = 0.04, z = 0.2 } + maxrelpos = { x = 0.1, y = 0.14, z = 0.38 } + else + return + end + -- Flames + mcl_particles.add_node_particlespawner(pos, { + amount = 8, + time = 0, + minpos = vector.add(pos, minrelpos), + maxpos = vector.add(pos, maxrelpos), + minvel = { x = -0.01, y = 0, z = -0.01 }, + maxvel = { x = 0.01, y = 0.1, z = 0.01 }, + minexptime = 0.3, + maxexptime = 0.6, + minsize = 0.7, + maxsize = 2, + texture = "mcl_particles_flame.png", + glow = minetest.registered_nodes[node.name].light_source, + }, "low") + -- Smoke + mcl_particles.add_node_particlespawner(pos, { + amount = 0.5, + time = 0, + minpos = vector.add(pos, minrelpos), + maxpos = vector.add(pos, maxrelpos), + minvel = { x = 0, y = 0.5, z = 0 }, + maxvel = { x = 0, y = 0.6, z = 0 }, + minexptime = 2.0, + maxexptime = 2.0, + minsize = 1.5, + maxsize = 1.5, + texture = "mcl_particles_smoke_anim.png", + animation = { + type = "vertical_frames", + aspect_w = 8, + aspect_h = 8, + length = 2.05, + }, + }, "medium") +end + +local remove_flames = function(pos) + mcl_particles.delete_node_particlespawners(pos) +end + +-- +-- 3d torch part +-- + +-- Check if placement at given node is allowed +local function check_placement_allowed(node, wdir) + -- Torch placement rules: Disallow placement on some nodes. General rule: Solid, opaque, full cube collision box nodes are allowed. + -- Special allowed nodes: + -- * soul sand + -- * mob spawner + -- * chorus flower + -- * glass, barrier, ice + -- * Fence, wall, end portal frame with ender eye: Only on top + -- * Slab, stairs: Only on top if upside down + + -- Special forbidden nodes: + -- * Piston, sticky piston + local def = minetest.registered_nodes[node.name] + if not def then + return false + -- No ceiling torches + elseif wdir == 0 then + return false + elseif not def.buildable_to then + if node.name ~= "mcl_core:ice" and node.name ~= "mcl_nether:soul_sand" and node.name ~= "mcl_mobspawners:spawner" and node.name ~= "mcl_core:barrier" and node.name ~= "mcl_end:chorus_flower" and node.name ~= "mcl_end:chorus_flower_dead" and (not def.groups.glass) and + ((not def.groups.solid) or (not def.groups.opaque)) then + -- Only allow top placement on these nodes + if node.name == "mcl_end:dragon_egg" or node.name == "mcl_portals:end_portal_frame_eye" or def.groups.fence == 1 or def.groups.wall or def.groups.slab_top == 1 or def.groups.anvil or def.groups.pane or (def.groups.stair == 1 and minetest.facedir_to_dir(node.param2).y ~= 0) then + if wdir ~= 1 then + return false + end + else + return false + end + elseif minetest.get_item_group(node.name, "piston") >= 1 then + return false + end + end + return true +end + +function mcl_torches.register_torch(def) + local itemstring = minetest.get_current_modname() .. ":" .. def.name + local itemstring_wall = itemstring .. "_wall" + + def.light = def.light or minetest.LIGHT_MAX + def.mesh_floor = def.mesh_floor or "mcl_torches_torch_floor.obj" + def.mesh_wall = def.mesh_wall or "mcl_torches_torch_wall.obj" + + local groups = def.groups or {} + + groups.attached_node = 1 + groups.torch = 1 + groups.torch_particles = def.particles and 1 + groups.dig_by_water = 1 + groups.destroy_by_lava_flow = 1 + groups.dig_by_piston = 1 + + local floordef = { + description = def.description, + _doc_items_longdesc = def.doc_items_longdesc, + _doc_items_usagehelp = def.doc_items_usagehelp, + _doc_items_hidden = def.doc_items_hidden, + _doc_items_create_entry = def._doc_items_create_entry, + drawtype = "mesh", + mesh = def.mesh_floor, + inventory_image = def.icon, + wield_image = def.icon, + tiles = def.tiles, + use_texture_alpha = minetest.features.use_texture_alpha_string_modes and "opaque" or false, + paramtype = "light", + paramtype2 = "wallmounted", + sunlight_propagates = true, + is_ground_content = false, + walkable = false, + liquids_pointable = false, + light_source = def.light, + groups = groups, + drop = def.drop or itemstring, + selection_box = { + type = "wallmounted", + wall_top = {-1/16, -1/16, -1/16, 1/16, 0.5, 1/16}, + wall_bottom = {-1/16, -0.5, -1/16, 1/16, 1/16, 1/16}, + }, + sounds = def.sounds, + node_placement_prediction = "", + on_place = function(itemstack, placer, pointed_thing) + if pointed_thing.type ~= "node" then + -- no interaction possible with entities, for now. + return itemstack + end + + local under = pointed_thing.under + local node = minetest.get_node(under) + local def = minetest.registered_nodes[node.name] + if not def then return itemstack end + + -- Call on_rightclick if the pointed node defines it + if placer and not placer:get_player_control().sneak then + if minetest.registered_nodes[node.name] and minetest.registered_nodes[node.name].on_rightclick then + return minetest.registered_nodes[node.name].on_rightclick(under, node, placer, itemstack) or itemstack + end + end + + local above = pointed_thing.above + local wdir = minetest.dir_to_wallmounted({x = under.x - above.x, y = under.y - above.y, z = under.z - above.z}) + + if check_placement_allowed(node, wdir) == false then + return itemstack + end + + local itemstring = itemstack:get_name() + local fakestack = ItemStack(itemstack) + local idef = fakestack:get_definition() + local retval + + if wdir == 1 then + retval = fakestack:set_name(itemstring) + else + retval = fakestack:set_name(itemstring_wall) + end + if not retval then + return itemstack + end + + local success + itemstack, success = minetest.item_place(fakestack, placer, pointed_thing, wdir) + itemstack:set_name(itemstring) + + if success and idef.sounds and idef.sounds.place then + minetest.sound_play(idef.sounds.place, {pos=under, gain=1}, true) + end + return itemstack + end, + on_rotate = false, + on_construct = def.particles and spawn_flames_floor, + on_destruct = def.particles and remove_flames, + } + minetest.register_node(itemstring, floordef) + + local groups_wall = table.copy(groups) + groups_wall.torch = 2 + + local walldef = { + drawtype = "mesh", + mesh = def.mesh_wall, + tiles = def.tiles, + use_texture_alpha = minetest.features.use_texture_alpha_string_modes and "opaque" or false, + paramtype = "light", + paramtype2 = "wallmounted", + sunlight_propagates = true, + is_ground_content = false, + walkable = false, + light_source = def.light, + groups = groups_wall, + drop = def.drop or itemstring, + selection_box = { + type = "wallmounted", + wall_top = {-0.1, -0.1, -0.1, 0.1, 0.5, 0.1}, + wall_bottom = {-0.1, -0.5, -0.1, 0.1, 0.1, 0.1}, + wall_side = {-0.5, -0.5, -0.1, -0.2, 0.1, 0.1}, + }, + sounds = def.sounds, + on_rotate = false, + on_construct = def.particles and spawn_flames_wall, + on_destruct = def.particles and remove_flames, + } + minetest.register_node(itemstring_wall, walldef) + + -- Add entry alias for the Help + if minetest.get_modpath("doc") then + doc.add_entry_alias("nodes", itemstring, "nodes", itemstring_wall) + end +end + +minetest.register_lbm({ + label = "Torch flame particles", + name = "mcl_torches:flames", + nodenames = {"group:torch_particles"}, + run_at_every_load = true, + action = function(pos, node) + local torch_group = minetest.get_node_group(node.name, "torch") + if torch_group == 1 then + spawn_flames_floor(pos) + elseif torch_group == 2 then + spawn_flames_wall(pos) + end + end, +}) diff --git a/mods/ITEMS/mcl_torches/init.lua b/mods/ITEMS/mcl_torches/init.lua index 451a8dfad..1102731c1 100644 --- a/mods/ITEMS/mcl_torches/init.lua +++ b/mods/ITEMS/mcl_torches/init.lua @@ -1,338 +1,6 @@ -local S = minetest.get_translator("mcl_torches") -local LIGHT_TORCH = minetest.LIGHT_MAX - -local spawn_flames_floor = function(pos) - -- Flames - mcl_particles.add_node_particlespawner(pos, { - amount = 8, - time = 0, - minpos = vector.add(pos, { x = -0.1, y = 0.05, z = -0.1 }), - maxpos = vector.add(pos, { x = 0.1, y = 0.15, z = 0.1 }), - minvel = { x = -0.01, y = 0, z = -0.01 }, - maxvel = { x = 0.01, y = 0.1, z = 0.01 }, - minexptime = 0.3, - maxexptime = 0.6, - minsize = 0.7, - maxsize = 2, - texture = "mcl_particles_flame.png", - glow = LIGHT_TORCH, - }, "low") - -- Smoke - mcl_particles.add_node_particlespawner(pos, { - amount = 0.5, - time = 0, - minpos = vector.add(pos, { x = -1/16, y = 0.04, z = -1/16 }), - maxpos = vector.add(pos, { x = -1/16, y = 0.06, z = -1/16 }), - minvel = { x = 0, y = 0.5, z = 0 }, - maxvel = { x = 0, y = 0.6, z = 0 }, - minexptime = 2.0, - maxexptime = 2.0, - minsize = 1.5, - maxsize = 1.5, - texture = "mcl_particles_smoke_anim.png", - animation = { - type = "vertical_frames", - aspect_w = 8, - aspect_h = 8, - length = 2.05, - }, - }, "medium") -end - -local spawn_flames_wall = function(pos, param2) - local minrelpos, maxrelpos - local dir = minetest.wallmounted_to_dir(param2) - if dir.x < 0 then - minrelpos = { x = -0.38, y = 0.04, z = -0.1 } - maxrelpos = { x = -0.2, y = 0.14, z = 0.1 } - elseif dir.x > 0 then - minrelpos = { x = 0.2, y = 0.04, z = -0.1 } - maxrelpos = { x = 0.38, y = 0.14, z = 0.1 } - elseif dir.z < 0 then - minrelpos = { x = -0.1, y = 0.04, z = -0.38 } - maxrelpos = { x = 0.1, y = 0.14, z = -0.2 } - elseif dir.z > 0 then - minrelpos = { x = -0.1, y = 0.04, z = 0.2 } - maxrelpos = { x = 0.1, y = 0.14, z = 0.38 } - else - return - end - -- Flames - mcl_particles.add_node_particlespawner(pos, { - amount = 8, - time = 0, - minpos = vector.add(pos, minrelpos), - maxpos = vector.add(pos, maxrelpos), - minvel = { x = -0.01, y = 0, z = -0.01 }, - maxvel = { x = 0.01, y = 0.1, z = 0.01 }, - minexptime = 0.3, - maxexptime = 0.6, - minsize = 0.7, - maxsize = 2, - texture = "mcl_particles_flame.png", - glow = LIGHT_TORCH, - }, "low") - -- Smoke - mcl_particles.add_node_particlespawner(pos, { - amount = 0.5, - time = 0, - minpos = vector.add(pos, minrelpos), - maxpos = vector.add(pos, maxrelpos), - minvel = { x = 0, y = 0.5, z = 0 }, - maxvel = { x = 0, y = 0.6, z = 0 }, - minexptime = 2.0, - maxexptime = 2.0, - minsize = 1.5, - maxsize = 1.5, - texture = "mcl_particles_smoke_anim.png", - animation = { - type = "vertical_frames", - aspect_w = 8, - aspect_h = 8, - length = 2.05, - }, - }, "medium") -end - -local remove_flames = function(pos) - mcl_particles.delete_node_particlespawners(pos) -end - --- --- 3d torch part --- - --- Check if placement at given node is allowed -local function check_placement_allowed(node, wdir) - -- Torch placement rules: Disallow placement on some nodes. General rule: Solid, opaque, full cube collision box nodes are allowed. - -- Special allowed nodes: - -- * soul sand - -- * mob spawner - -- * chorus flower - -- * glass, barrier, ice - -- * Fence, wall, end portal frame with ender eye: Only on top - -- * Slab, stairs: Only on top if upside down - - -- Special forbidden nodes: - -- * Piston, sticky piston - local def = minetest.registered_nodes[node.name] - if not def then - return false - -- No ceiling torches - elseif wdir == 0 then - return false - elseif not def.buildable_to then - if node.name ~= "mcl_core:ice" and node.name ~= "mcl_nether:soul_sand" and node.name ~= "mcl_mobspawners:spawner" and node.name ~= "mcl_core:barrier" and node.name ~= "mcl_end:chorus_flower" and node.name ~= "mcl_end:chorus_flower_dead" and (not def.groups.glass) and - ((not def.groups.solid) or (not def.groups.opaque)) then - -- Only allow top placement on these nodes - if node.name == "mcl_end:dragon_egg" or node.name == "mcl_portals:end_portal_frame_eye" or def.groups.fence == 1 or def.groups.wall or def.groups.slab_top == 1 or def.groups.anvil or def.groups.pane or (def.groups.stair == 1 and minetest.facedir_to_dir(node.param2).y ~= 0) then - if wdir ~= 1 then - return false - end - else - return false - end - elseif minetest.get_item_group(node.name, "piston") >= 1 then - return false - end - end - return true -end - mcl_torches = {} -mcl_torches.register_torch = function(substring, description, doc_items_longdesc, doc_items_usagehelp, icon, mesh_floor, mesh_wall, tiles, light, groups, sounds, moredef, moredef_floor, moredef_wall) - local itemstring = minetest.get_current_modname()..":"..substring - local itemstring_wall = minetest.get_current_modname()..":"..substring.."_wall" - - if light == nil then light = minetest.LIGHT_MAX end - if mesh_floor == nil then mesh_floor = "mcl_torches_torch_floor.obj" end - if mesh_wall == nil then mesh_wall = "mcl_torches_torch_wall.obj" end - if groups == nil then groups = {} end - - groups.attached_node = 1 - groups.torch = 1 - groups.dig_by_water = 1 - groups.destroy_by_lava_flow = 1 - groups.dig_by_piston = 1 - - local floordef = { - description = description, - _doc_items_longdesc = doc_items_longdesc, - _doc_items_usagehelp = doc_items_usagehelp, - drawtype = "mesh", - mesh = mesh_floor, - inventory_image = icon, - wield_image = icon, - tiles = tiles, - use_texture_alpha = minetest.features.use_texture_alpha_string_modes and "opaque" or false, - paramtype = "light", - paramtype2 = "wallmounted", - sunlight_propagates = true, - is_ground_content = false, - walkable = false, - liquids_pointable = false, - light_source = light, - groups = groups, - drop = itemstring, - selection_box = { - type = "wallmounted", - wall_top = {-1/16, -1/16, -1/16, 1/16, 0.5, 1/16}, - wall_bottom = {-1/16, -0.5, -1/16, 1/16, 1/16, 1/16}, - }, - sounds = sounds, - node_placement_prediction = "", - on_place = function(itemstack, placer, pointed_thing) - if pointed_thing.type ~= "node" then - -- no interaction possible with entities, for now. - return itemstack - end - - local under = pointed_thing.under - local node = minetest.get_node(under) - local def = minetest.registered_nodes[node.name] - if not def then return itemstack end - - -- Call on_rightclick if the pointed node defines it - if placer and not placer:get_player_control().sneak then - if minetest.registered_nodes[node.name] and minetest.registered_nodes[node.name].on_rightclick then - return minetest.registered_nodes[node.name].on_rightclick(under, node, placer, itemstack) or itemstack - end - end - - local above = pointed_thing.above - local wdir = minetest.dir_to_wallmounted({x = under.x - above.x, y = under.y - above.y, z = under.z - above.z}) - - if check_placement_allowed(node, wdir) == false then - return itemstack - end - - local itemstring = itemstack:get_name() - local fakestack = ItemStack(itemstack) - local idef = fakestack:get_definition() - local retval - - if wdir == 1 then - retval = fakestack:set_name(itemstring) - else - retval = fakestack:set_name(itemstring_wall) - end - if not retval then - return itemstack - end - - local success - itemstack, success = minetest.item_place(fakestack, placer, pointed_thing, wdir) - itemstack:set_name(itemstring) - - if success and idef.sounds and idef.sounds.place then - minetest.sound_play(idef.sounds.place, {pos=under, gain=1}, true) - end - return itemstack - end, - on_rotate = false, - } - if moredef ~= nil then - for k,v in pairs(moredef) do - floordef[k] = v - end - end - if moredef_floor ~= nil then - for k,v in pairs(moredef_floor) do - floordef[k] = v - end - end - minetest.register_node(itemstring, floordef) - - local groups_wall = table.copy(groups) - groups_wall.torch = 2 - - local walldef = { - drawtype = "mesh", - mesh = mesh_wall, - tiles = tiles, - use_texture_alpha = minetest.features.use_texture_alpha_string_modes and "opaque" or false, - paramtype = "light", - paramtype2 = "wallmounted", - sunlight_propagates = true, - is_ground_content = false, - walkable = false, - light_source = light, - groups = groups_wall, - drop = itemstring, - selection_box = { - type = "wallmounted", - wall_top = {-0.1, -0.1, -0.1, 0.1, 0.5, 0.1}, - wall_bottom = {-0.1, -0.5, -0.1, 0.1, 0.1, 0.1}, - wall_side = {-0.5, -0.5, -0.1, -0.2, 0.1, 0.1}, - }, - sounds = sounds, - on_rotate = false, - } - if moredef ~= nil then - for k,v in pairs(moredef) do - walldef[k] = v - end - end - if moredef_wall ~= nil then - for k,v in pairs(moredef_wall) do - walldef[k] = v - end - end - minetest.register_node(itemstring_wall, walldef) - - - -- Add entry alias for the Help - if minetest.get_modpath("doc") then - doc.add_entry_alias("nodes", itemstring, "nodes", itemstring_wall) - end - -end - -mcl_torches.register_torch("torch", - S("Torch"), - S("Torches are light sources which can be placed at the side or on the top of most blocks."), - nil, - "default_torch_on_floor.png", - "mcl_torches_torch_floor.obj", "mcl_torches_torch_wall.obj", - {{ - name = "default_torch_on_floor_animated.png", - animation = {type = "vertical_frames", aspect_w = 16, aspect_h = 16, length = 3.3} - }}, - LIGHT_TORCH, - {dig_immediate=3, torch=1, deco_block=1}, - mcl_sounds.node_sound_wood_defaults(), - {_doc_items_hidden = false, - on_destruct = function(pos) - remove_flames(pos) - end}, - {on_construct = function(pos) - spawn_flames_floor(pos) - end}, - {on_construct = function(pos) - local node = minetest.get_node(pos) - spawn_flames_wall(pos, node.param2) - end}) - -minetest.register_craft({ - output = "mcl_torches:torch 4", - recipe = { - { "group:coal" }, - { "mcl_core:stick" }, - } -}) - -minetest.register_lbm({ - label = "Torch flame particles", - name = "mcl_torches:flames", - nodenames = {"mcl_torches:torch", "mcl_torches:torch_wall"}, - run_at_every_load = true, - action = function(pos, node) - if node.name == "mcl_torches:torch" then - spawn_flames_floor(pos) - elseif node.name == "mcl_torches:torch_wall" then - spawn_flames_wall(pos, node.param2) - end - end, -}) +local modpath = minetest.get_modpath("mcl_torches") +dofile(modpath .. "/api.lua") +dofile(modpath .. "/register.lua") diff --git a/mods/ITEMS/mcl_torches/register.lua b/mods/ITEMS/mcl_torches/register.lua new file mode 100644 index 000000000..4218889d9 --- /dev/null +++ b/mods/ITEMS/mcl_torches/register.lua @@ -0,0 +1,27 @@ +local S = minetest.get_translator("mcl_torches") + +mcl_torches.register_torch({ + name = "torch", + description = S("Torch"), + doc_items_longdesc = S("Torches are light sources which can be placed at the side or on the top of most blocks."), + doc_items_hidden = false, + icon = "default_torch_on_floor.png", + tiles = {{ + name = "default_torch_on_floor_animated.png", + animation = {type = "vertical_frames", aspect_w = 16, aspect_h = 16, length = 3.3} + }}, + -- this is 15 in minecraft + light = 14, + groups = {dig_immediate = 3, deco_block = 1}, + sounds = mcl_sounds.node_sound_wood_defaults(), + particles = true, +}) + +minetest.register_craft({ + output = "mcl_torches:torch 4", + recipe = { + {"group:coal"}, + {"mcl_core:stick"}, + } +}) + diff --git a/mods/MAPGEN/mcl_dungeons/init.lua b/mods/MAPGEN/mcl_dungeons/init.lua index dc9c6d619..928faaa11 100644 --- a/mods/MAPGEN/mcl_dungeons/init.lua +++ b/mods/MAPGEN/mcl_dungeons/init.lua @@ -9,15 +9,38 @@ if mcl_vars.mg_dungeons == false or mg_name == "singlenode" then return end -local min_y = math.max(mcl_vars.mg_overworld_min, mcl_vars.mg_bedrock_overworld_max) + 1 -local max_y = mcl_vars.mg_overworld_max - 1 +--lua locals +--minetest +local registered_nodes = minetest.registered_nodes +local swap_node = minetest.swap_node +local set_node = minetest.set_node +local dir_to_facedir = minetest.dir_to_facedir +local get_meta = minetest.get_meta +local emerge_area = minetest.emerge_area +--vector +local vector_add = vector.add +local vector_subtract = vector.subtract + +--table +local table_insert = table.insert +local table_sort = table.sort + +--math +local math_min = math.min +local math_max = math.max +local math_ceil = math.ceil + +--custom mcl_vars local get_node = mcl_vars.get_node + +local min_y = math_max(mcl_vars.mg_overworld_min, mcl_vars.mg_bedrock_overworld_max) + 1 +local max_y = mcl_vars.mg_overworld_max - 1 -- Calculate the number of dungeon spawn attempts -- In Minecraft, there 8 dungeon spawn attempts Minecraft chunk (16*256*16 = 65536 blocks). -- Minetest chunks don't have this size, so scale the number accordingly. -local attempts = math.ceil(((mcl_vars.chunksize * mcl_vars.MAP_BLOCKSIZE) ^ 3) / 8192) -- 63 = 80*80*80/8192 +local attempts = math_ceil(((mcl_vars.chunksize * mcl_vars.MAP_BLOCKSIZE) ^ 3) / 8192) -- 63 = 80*80*80/8192 local dungeonsizes = { { x=5, y=4, z=5}, @@ -51,8 +74,8 @@ local function ecb_spawn_dungeon(blockpos, action, calls_remaining, param) local y_floor = y local y_ceiling = y + dim.y + 1 if check then for tx = x+1, x+dim.x do for tz = z+1, z+dim.z do - if not minetest.registered_nodes[get_node({x = tx, y = y_floor , z = tz}).name].walkable - or not minetest.registered_nodes[get_node({x = tx, y = y_ceiling, z = tz}).name].walkable then return false end + if not registered_nodes[get_node({x = tx, y = y_floor , z = tz}).name].walkable + or not registered_nodes[get_node({x = tx, y = y_ceiling, z = tz}).name].walkable then return false end end end end -- Check for air openings (2 stacked air at ground level) in wall positions @@ -69,25 +92,25 @@ local function ecb_spawn_dungeon(blockpos, action, calls_remaining, param) openings_counter = openings_counter + 1 if not openings[x] then openings[x]={} end openings[x][z] = true - table.insert(corners, {x=x, z=z}) + table_insert(corners, {x=x, z=z}) end if get_node({x=x2, y=y+1, z=z}).name == "air" and get_node({x=x2, y=y+2, z=z}).name == "air" then openings_counter = openings_counter + 1 if not openings[x2] then openings[x2]={} end openings[x2][z] = true - table.insert(corners, {x=x2, z=z}) + table_insert(corners, {x=x2, z=z}) end if get_node({x=x, y=y+1, z=z2}).name == "air" and get_node({x=x, y=y+2, z=z2}).name == "air" then openings_counter = openings_counter + 1 if not openings[x] then openings[x]={} end openings[x][z2] = true - table.insert(corners, {x=x, z=z2}) + table_insert(corners, {x=x, z=z2}) end if get_node({x=x2, y=y+1, z=z2}).name == "air" and get_node({x=x2, y=y+2, z=z2}).name == "air" then openings_counter = openings_counter + 1 if not openings[x2] then openings[x2]={} end openings[x2][z2] = true - table.insert(corners, {x=x2, z=z2}) + table_insert(corners, {x=x2, z=z2}) end for wx = x+1, x+dim.x do @@ -180,16 +203,16 @@ local function ecb_spawn_dungeon(blockpos, action, calls_remaining, param) secondChance = false end lastRandom = r - table.insert(chestSlots, r) + table_insert(chestSlots, r) end - table.sort(chestSlots) + table_sort(chestSlots) local currentChest = 1 -- Calculate the mob spawner position, to be re-used for later - local sp = {x = x + math.ceil(dim.x/2), y = y+1, z = z + math.ceil(dim.z/2)} - local rn = minetest.registered_nodes[get_node(sp).name] + local sp = {x = x + math_ceil(dim.x/2), y = y+1, z = z + math_ceil(dim.z/2)} + local rn = registered_nodes[get_node(sp).name] if rn and rn.is_ground_content then - table.insert(spawner_posses, sp) + table_insert(spawner_posses, sp) end -- Generate walls and floor @@ -203,13 +226,13 @@ local function ecb_spawn_dungeon(blockpos, action, calls_remaining, param) -- Do not overwrite nodes with is_ground_content == false (e.g. bedrock) -- Exceptions: cobblestone and mossy cobblestone so neighborings dungeons nicely connect to each other local name = get_node(p).name - if minetest.registered_nodes[name].is_ground_content or name == "mcl_core:cobble" or name == "mcl_core:mossycobble" then + if registered_nodes[name].is_ground_content or name == "mcl_core:cobble" or name == "mcl_core:mossycobble" then -- Floor if ty == y then if pr:next(1,4) == 1 then - minetest.swap_node(p, {name = "mcl_core:cobble"}) + swap_node(p, {name = "mcl_core:cobble"}) else - minetest.swap_node(p, {name = "mcl_core:mossycobble"}) + swap_node(p, {name = "mcl_core:mossycobble"}) end -- Generate walls @@ -221,14 +244,14 @@ local function ecb_spawn_dungeon(blockpos, action, calls_remaining, param) -- Check if it's an opening first if (ty == maxy) or (not (openings[tx] and openings[tx][tz])) then -- Place wall or ceiling - minetest.swap_node(p, {name = "mcl_core:cobble"}) + swap_node(p, {name = "mcl_core:cobble"}) elseif ty < maxy - 1 then -- Normally the openings are already clear, but not if it is a corner -- widening. Make sure to clear at least the bottom 2 nodes of an opening. - if name ~= "air" then minetest.swap_node(p, {name = "air"}) end + if name ~= "air" then swap_node(p, {name = "air"}) end elseif name ~= "air" then -- This allows for variation between 2-node and 3-node high openings. - minetest.swap_node(p, {name = "mcl_core:cobble"}) + swap_node(p, {name = "mcl_core:cobble"}) end -- If it was an opening, the lower 3 blocks are not touched at all @@ -236,9 +259,9 @@ local function ecb_spawn_dungeon(blockpos, action, calls_remaining, param) else if (ty==y+1) and (tx==x+1 or tx==maxx-1 or tz==z+1 or tz==maxz-1) and (currentChest < totalChests + 1) and (chestSlots[currentChest] == chestSlotCounter) then currentChest = currentChest + 1 - table.insert(chests, {x=tx, y=ty, z=tz}) + table_insert(chests, {x=tx, y=ty, z=tz}) else - minetest.swap_node(p, {name = "air"}) + swap_node(p, {name = "air"}) end local forChest = ty==y+1 and (tx==x+1 or tx==maxx-1 or tz==z+1 or tz==maxz-1) @@ -246,9 +269,9 @@ local function ecb_spawn_dungeon(blockpos, action, calls_remaining, param) -- Place next chest at the wall (if it was its chosen wall slot) if forChest and (currentChest < totalChests + 1) and (chestSlots[currentChest] == chestSlotCounter) then currentChest = currentChest + 1 - table.insert(chests, {x=tx, y=ty, z=tz}) + table_insert(chests, {x=tx, y=ty, z=tz}) -- else - --minetest.swap_node(p, {name = "air"}) + --swap_node(p, {name = "air"}) end if forChest then chestSlotCounter = chestSlotCounter + 1 @@ -263,15 +286,15 @@ local function ecb_spawn_dungeon(blockpos, action, calls_remaining, param) local surroundings = {} for s=1, #surround_vectors do -- Detect the 4 horizontal neighbors - local spos = vector.add(pos, surround_vectors[s]) - local wpos = vector.subtract(pos, surround_vectors[s]) + local spos = vector_add(pos, surround_vectors[s]) + local wpos = vector_subtract(pos, surround_vectors[s]) local nodename = get_node(spos).name local nodename2 = get_node(wpos).name - local nodedef = minetest.registered_nodes[nodename] - local nodedef2 = minetest.registered_nodes[nodename2] + local nodedef = registered_nodes[nodename] + local nodedef2 = registered_nodes[nodename2] -- The chest needs an open space in front of it and a walkable node (except chest) behind it if nodedef and nodedef.walkable == false and nodedef2 and nodedef2.walkable == true and nodename2 ~= "mcl_chests:chest" then - table.insert(surroundings, spos) + table_insert(surroundings, spos) end end -- Set param2 (=facedir) of this chest @@ -282,11 +305,11 @@ local function ecb_spawn_dungeon(blockpos, action, calls_remaining, param) else -- 1 or multiple possible open directions: Choose random facedir local face_to = surroundings[pr:next(1, #surroundings)] - facedir = minetest.dir_to_facedir(vector.subtract(pos, face_to)) + facedir = dir_to_facedir(vector_subtract(pos, face_to)) end - minetest.set_node(pos, {name="mcl_chests:chest", param2=facedir}) - local meta = minetest.get_meta(pos) + set_node(pos, {name="mcl_chests:chest", param2=facedir}) + local meta = get_meta(pos) local loottable = { @@ -336,7 +359,7 @@ local function ecb_spawn_dungeon(blockpos, action, calls_remaining, param) -- Bonus loot for v6 mapgen: Otherwise unobtainable saplings. if mg_name == "v6" then - table.insert(loottable, { + table_insert(loottable, { stacks_min = 1, stacks_max = 3, items = { @@ -356,7 +379,7 @@ local function ecb_spawn_dungeon(blockpos, action, calls_remaining, param) for s=#spawner_posses, 1, -1 do local sp = spawner_posses[s] -- ... and place it and select a random mob - minetest.set_node(sp, {name = "mcl_mobspawners:spawner"}) + set_node(sp, {name = "mcl_mobspawners:spawner"}) local mobs = { "mobs_mc:zombie", "mobs_mc:zombie", @@ -370,7 +393,7 @@ local function ecb_spawn_dungeon(blockpos, action, calls_remaining, param) end local function dungeons_nodes(minp, maxp, blockseed) - local ymin, ymax = math.max(min_y, minp.y), math.min(max_y, maxp.y) + local ymin, ymax = math_max(min_y, minp.y), math_min(max_y, maxp.y) if ymax < ymin then return false end local pr = PseudoRandom(blockseed) for a=1, attempts do @@ -382,7 +405,7 @@ local function dungeons_nodes(minp, maxp, blockseed) local p2 = {x = x+dim.x+1, y = y+dim.y+1, z = z+dim.z+1} minetest.log("verbose","[mcl_dungeons] size=" ..minetest.pos_to_string(dim) .. ", emerge from "..minetest.pos_to_string(p1) .. " to " .. minetest.pos_to_string(p2)) local param = {p1=p1, p2=p2, dim=dim, pr=pr} - minetest.emerge_area(p1, p2, ecb_spawn_dungeon, param) + emerge_area(p1, p2, ecb_spawn_dungeon, param) end end @@ -392,7 +415,7 @@ function mcl_dungeons.spawn_dungeon(p1, _, pr) local p2 = {x = p1.x+dim.x+1, y = p1.y+dim.y+1, z = p1.z+dim.z+1} minetest.log("verbose","[mcl_dungeons] size=" ..minetest.pos_to_string(dim) .. ", emerge from "..minetest.pos_to_string(p1) .. " to " .. minetest.pos_to_string(p2)) local param = {p1=p1, p2=p2, dim=dim, pr=pr, dontcheck=true} - minetest.emerge_area(p1, p2, ecb_spawn_dungeon, param) + emerge_area(p1, p2, ecb_spawn_dungeon, param) end mcl_mapgen_core.register_generator("dungeons", nil, dungeons_nodes, 999999) diff --git a/mods/PLAYER/mcl_playerplus/init.lua b/mods/PLAYER/mcl_playerplus/init.lua index 5ba73cd60..f4dceb9b4 100644 --- a/mods/PLAYER/mcl_playerplus/init.lua +++ b/mods/PLAYER/mcl_playerplus/init.lua @@ -1,6 +1,6 @@ local S = minetest.get_translator("mcl_playerplus") -local elytra = {} +elytra = {} local node_stand_return = ":air" local get_connected_players = minetest.get_connected_players @@ -24,6 +24,7 @@ local mcl_playerplus_internal = {} local def = {} local time = 0 +local look_pitch = 0 local player_collision = function(player) @@ -175,14 +176,14 @@ minetest.register_globalstep(function(dtime) ]]-- - local controls = player:get_player_control() + local control = player:get_player_control() local name = player:get_player_name() local meta = player:get_meta() local parent = player:get_attach() local wielded = player:get_wielded_item() local player_velocity = player:get_velocity() or player:get_player_velocity() - -- controls head bone + -- control head bone local pitch = - degrees(player:get_look_vertical()) local yaw = degrees(player:get_look_horizontal()) @@ -194,16 +195,44 @@ minetest.register_globalstep(function(dtime) player_vel_yaws[name] = player_vel_yaw if minetest.get_node_or_nil({x=player:get_pos().x, y=player:get_pos().y - 0.5, z=player:get_pos().z}) then - node_stand_return = minetest.get_node_or_nil({x=player:get_pos().x, y=player:get_pos().y - 0.5, z=player:get_pos().z}).name + node_stand_return = minetest.get_node_or_nil({x=player:get_pos().x, y=player:get_pos().y - 0.1, z=player:get_pos().z}).name else minetest.log("action", "somehow player got of loaded areas") end + local chestplate = player:get_inventory():get_stack("armor", 3) + + if player_rocketing[player] and player_rocketing[player] == true and chestplate:get_name() == "mcl_armor:elytra" then + if math.abs(player_velocity.x) + math.abs(player_velocity.y) + math.abs(player_velocity.z) < 40 then + player:add_player_velocity(vector.multiply(player:get_look_dir(), 4)) + elytra[player] = true + end + end + + + controls.register_on_press(function(player, key) + if key~="jump" and key~="RMB" then return end + if key=="jump" then + if player:get_inventory():get_stack("armor", 3):get_name() == "mcl_armor:elytra" and player_velocity.y < -6 and elytra[player] ~= true then + elytra[player] = true + elseif key=="RMB" then + if wielded:get_name() == "mcl_tools:rocket" then + local item = wielded:take_item() + player:set_wielded_item(wielded) + end + end + end + end) + + if elytra[player] == true and node_stand_return ~= "air" or elytra[player] == true and player:get_inventory():get_stack("armor", 3):get_name() ~= "mcl_armor:elytra" or player:get_attach() ~= nil then + elytra[player] = false + end +--[[ if player:get_inventory():get_stack("armor", 3):get_name() == "mcl_armor:elytra" and player_velocity.y < -6 and elytra[player] ~= true and is_sprinting(name) then elytra[player] = true elseif elytra[player] == true and node_stand_return ~= "air" or elytra[player] == true and player:get_inventory():get_stack("armor", 3):get_name() ~= "mcl_armor:elytra" or player:get_attach() ~= nil then elytra[player] = false - end + end]] if elytra[player] == true then mcl_player.player_set_animation(player, "fly") @@ -213,23 +242,23 @@ minetest.register_globalstep(function(dtime) end if math.abs(player_velocity.x) + math.abs(player_velocity.z) < 20 then local dir = minetest.yaw_to_dir(player:get_look_horizontal()) - player:add_velocity({x=dir.x, y=0, z=dir.z}) - end - if controls.sneak then - if player_velocity.y > -5 then - player:add_velocity({x=0, y=-2, z=0}) + if degrees(player:get_look_vertical()) * -.01 < .1 then + look_pitch = degrees(player:get_look_vertical()) * -.01 + else + look_pitch = .1 end + player:add_velocity({x=dir.x, y=look_pitch, z=dir.z}) end else playerphysics.remove_physics_factor(player, "gravity", "mcl_playerplus:elytra") end -- controls right and left arms pitch when shooting a bow - if string.find(wielded:get_name(), "mcl_bows:bow") and controls.RMB and not controls.LMB and not controls.up and not controls.down and not controls.left and not controls.right then + if string.find(wielded:get_name(), "mcl_bows:bow") and control.RMB and not control.LMB and not control.up and not control.down and not control.left and not control.right then player:set_bone_position("Arm_Right_Pitch_Control", vector.new(-3,5.785,0), vector.new(pitch+90,-30,pitch * -1 * .35)) player:set_bone_position("Arm_Left_Pitch_Control", vector.new(3.5,5.785,0), vector.new(pitch+90,43,pitch * .35)) -- when punching - elseif controls.LMB and not parent then + elseif control.LMB and not parent then player:set_bone_position("Arm_Right_Pitch_Control", vector.new(-3,5.785,0), vector.new(pitch,0,0)) player:set_bone_position("Arm_Left_Pitch_Control", vector.new(3,5.785,0), vector.new(0,0,0)) -- when holding an item. @@ -246,15 +275,15 @@ minetest.register_globalstep(function(dtime) -- set head pitch and yaw when swimming player:set_bone_position("Head", vector.new(0,6.3,0), vector.new(pitch+90-degrees(dir_to_pitch(player_velocity)),player_vel_yaw - yaw,0)) -- sets eye height, and nametag color accordingly - player:set_properties({collisionbox = {-0.35,0,-0.35,0.35,0.8,0.35}, eye_height = 0.5, nametag_color = { r = 225, b = 225, a = 225, g = 225 }}) + player:set_properties({collisionbox = {-0.35,0,-0.35,0.35,0.8,0.35}, eye_height = 0.5, nametag_color = { r = 225, b = 225, a = 0, g = 225 }}) -- control body bone when swimming player:set_bone_position("Body_Control", vector.new(0,6.3,0), vector.new(degrees(dir_to_pitch(player_velocity)) - 90,-player_vel_yaw + yaw + 180,0)) elseif parent then local parent_yaw = degrees(parent:get_yaw()) - player:set_properties({collisionbox = {-0.312,0,-0.312,0.312,1.8,0.312}, eye_height = 1.5, nametag_color = { r = 225, b = 225, a = 225, g = 225 }}) + player:set_properties({collisionbox = {-0.312,0,-0.312,0.312,1.8,0.312}, eye_height = 1.5, nametag_color = { r = 225, b = 225, a = 0, g = 225 }}) player:set_bone_position("Head", vector.new(0,6.3,0), vector.new(pitch, -limit_vel_yaw(yaw, parent_yaw) + parent_yaw, 0)) player:set_bone_position("Body_Control", vector.new(0,6.3,0), vector.new(0,0,0)) - elseif controls.sneak then + elseif control.sneak then -- controls head pitch when sneaking player:set_bone_position("Head", vector.new(0,6.3,0), vector.new(pitch+36,0,0)) -- sets eye height, and nametag color accordingly @@ -265,12 +294,12 @@ minetest.register_globalstep(function(dtime) -- set head pitch and yaw when swimming player:set_bone_position("Head", vector.new(0,6.3,0), vector.new(pitch+90-degrees(dir_to_pitch(player_velocity)),player_vel_yaw - yaw,0)) -- sets eye height, and nametag color accordingly - player:set_properties({collisionbox = {-0.312,0,-0.312,0.312,0.8,0.312}, eye_height = 0.5, nametag_color = { r = 225, b = 225, a = 225, g = 225 }}) + player:set_properties({collisionbox = {-0.312,0,-0.312,0.312,0.8,0.312}, eye_height = 0.5, nametag_color = { r = 225, b = 225, a = 0, g = 225 }}) -- control body bone when swimming player:set_bone_position("Body_Control", vector.new(0,6.3,0), vector.new(degrees(dir_to_pitch(player_velocity)) - 90,-player_vel_yaw + yaw + 180,0)) else -- sets eye height, and nametag color accordingly - player:set_properties({collisionbox = {-0.312,0,-0.312,0.312,1.8,0.312}, eye_height = 1.5, nametag_color = { r = 225, b = 225, a = 225, g = 225 }}) + player:set_properties({collisionbox = {-0.312,0,-0.312,0.312,1.8,0.312}, eye_height = 1.5, nametag_color = { r = 225, b = 225, a = 0, g = 225 }}) player:set_bone_position("Head", vector.new(0,6.3,0), vector.new(pitch, player_vel_yaw - yaw, 0)) player:set_bone_position("Body_Control", vector.new(0,6.3,0), vector.new(0, -player_vel_yaw + yaw, 0)) @@ -283,7 +312,7 @@ minetest.register_globalstep(function(dtime) mcl_playerplus_internal[name].jump_cooldown = mcl_playerplus_internal[name].jump_cooldown - dtime end - if controls.jump and mcl_playerplus_internal[name].jump_cooldown <= 0 then + if control.jump and mcl_playerplus_internal[name].jump_cooldown <= 0 then pos = player:get_pos()