Merge branch 'master' into beta

This commit is contained in:
Elias Fleckenstein 2021-04-14 16:36:04 +02:00
commit 6d0abb2973
19 changed files with 702 additions and 505 deletions

View file

@ -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.

View file

@ -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

View file

@ -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

View file

@ -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"),

View file

@ -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

View file

@ -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: <https://freesound.org/people/Ned Bouhalassa/sounds/8320/>

View file

@ -0,0 +1,2 @@
name = mcl_firework
author = NO11, j45

View file

@ -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"},
})

View file

@ -0,0 +1,4 @@
local path = minetest.get_modpath("mcl_fireworks")
dofile(path .. "/register.lua")
dofile(path .. "/crafting.lua")

View file

@ -0,0 +1,3 @@
# textdomain: mcl_fireworks
Firework Rocket=Feuerwerksrakete
Flight Duration:=Flugdauer:

View file

@ -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,
})

Binary file not shown.

After

Width:  |  Height:  |  Size: 356 B

View file

@ -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

View file

@ -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,
})

View file

@ -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")

View file

@ -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"},
}
})

View file

@ -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)

View file

@ -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()