Merge branch 'master' into hoppers_w_composter

This commit is contained in:
cora 2022-11-12 12:27:49 +00:00
commit b625fba4f2
15 changed files with 516 additions and 143 deletions

@ -22,6 +22,19 @@ function table.update_nil(t, ...)
return t
end
local LOGGING_ON = minetest.settings:get_bool("mcl_logging_default",false)
local LOG_MODULE = "[MCL2]"
function mcl_util.mcl_log (message, module, bypass_default_logger)
local selected_module = LOG_MODULE
if module then
selected_module = module
end
if (bypass_default_logger or LOGGING_ON) and message then
minetest.log(selected_module .. " " .. message)
end
end
function mcl_util.file_exists(name)
if type(name) ~= "string" then return end
local f = io.open(name)
@ -600,10 +613,12 @@ function mcl_util.get_object_name(object)
end
function mcl_util.replace_mob(obj, mob)
if not obj then return end
local rot = obj:get_yaw()
local pos = obj:get_pos()
obj:remove()
obj = minetest.add_entity(pos, mob)
if not obj then return end
obj:set_yaw(rot)
return obj
end
@ -705,10 +720,11 @@ function mcl_util.set_properties(obj,props)
end
end
function mcl_util.set_bone_position(obj,b,p,r) --bone,position,rotation
local oldp,oldr=obj:get_bone_position(b)
if vector.equals(vector.round(oldp),vector.round(p)) and vector.equals(vector.round(oldr),vector.round(r)) then
return
function mcl_util.set_bone_position(obj, bone, pos, rot)
local current_pos, current_rot = obj:get_bone_position(bone)
local pos_equal = not pos or vector.equals(vector.round(current_pos), vector.round(pos))
local rot_equal = not rot or vector.equals(vector.round(current_rot), vector.round(rot))
if not pos_equal or not rot_equal then
obj:set_bone_position(bone, pos or current_pos, rot or current_rot)
end
obj:set_bone_position(b,p,r)
end

@ -21,11 +21,9 @@ local S = minetest.get_translator("mcl_mobs")
local mob_active_range = tonumber(minetest.settings:get("mcl_mob_active_range")) or 48
local LOGGING_ON = minetest.settings:get_bool("mcl_logging_mobs_villager",false)
local LOG_MODULE = "[Mobs]"
local function mcl_log (message)
if LOGGING_ON and message then
minetest.log(LOG_MODULE .. " " .. message)
if LOGGING_ON then
mcl_util.mcl_log (message, "[Mobs]", true)
end
end
@ -2212,7 +2210,7 @@ local monster_attack = function(self)
end
end
end
if not min_player then
if not min_player and #blacklist_attack > 0 then
min_player=blacklist_attack[math.random(#blacklist_attack)]
end
-- attack player

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.3 KiB

@ -45,10 +45,9 @@ local PATHFINDING = "gowp"
-- will be much easier.
local LOGGING_ON = minetest.settings:get_bool("mcl_logging_mobs_villager",false)
local LOG_MODULE = "[Mobs - Villager]"
local function mcl_log (message)
if LOGGING_ON and message then
minetest.log(LOG_MODULE .. " " .. message)
if LOGGING_ON then
mcl_util.mcl_log (message, "[Mobs - Villager]", true)
end
end
@ -496,6 +495,53 @@ local professions = {
},
},
},
mason = {
name = N("Mason"),
texture = "mobs_mc_villager_mason.png",
jobsite = "mcl_stonecutter:stonecutter",
trades = {
{
{ { "mcl_core:clay_lump", 10, 10 }, E1 },
{ E1, { "mcl_core:brick", 10, 10 } },
},
{
{ { "mcl_core:stone", 20, 20 }, E1 },
{ E1, { "mcl_core:stonebrickcarved", 4, 4 } },
},
{
{ { "mcl_core:granite", 16, 16 }, E1 },
{ { "mcl_core:andesite", 16, 16 }, E1 },
{ { "mcl_core:diorite", 16, 16 }, E1 },
{ E1, { "mcl_core:granite_smooth", 4, 4 } },
{ E1, { "mcl_core:andesite_smooth", 4, 4 } },
{ E1, { "mcl_core:diorite_smooth", 4, 4 } },
},
{
{ { "mcl_nether:quartz", 12, 12 }, E1 },
{ E1, { "mcl_colorblocks:hardened_clay", 1, 1} },
{ E1, { "mcl_colorblocks:hardened_clay_white", 1, 1} },
{ E1, { "mcl_colorblocks:hardened_clay_grey", 1, 1} },
{ E1, { "mcl_colorblocks:hardened_clay_silver", 1, 1} },
{ E1, { "mcl_colorblocks:hardened_clay_black", 1, 1} },
{ E1, { "mcl_colorblocks:hardened_clay_red", 1, 1} },
{ E1, { "mcl_colorblocks:hardened_clay_yellow", 1, 1} },
{ E1, { "mcl_colorblocks:hardened_clay_green", 1, 1} },
{ E1, { "mcl_colorblocks:hardened_clay_cyan", 1, 1} },
{ E1, { "mcl_colorblocks:hardened_clay_blue", 1, 1} },
{ E1, { "mcl_colorblocks:hardened_clay_magenta", 1, 1} },
{ E1, { "mcl_colorblocks:hardened_clay_orange", 1, 1} },
{ E1, { "mcl_colorblocks:hardened_clay_brown", 1, 1} },
{ E1, { "mcl_colorblocks:hardened_clay_pink", 1, 1} },
{ E1, { "mcl_colorblocks:hardened_clay_light_blue", 1, 1} },
{ E1, { "mcl_colorblocks:hardened_clay_lime", 1, 1} },
{ E1, { "mcl_colorblocks:hardened_clay_purple", 1, 1 } },
},
{
{ E1, { "mcl_nether:quartz_pillar", 1, 1 } },
{ E1, { "mcl_nether:quartz_block", 1, 1 } },
},
},
},
nitwit = {
name = N("Nitwit"),
texture = "mobs_mc_villager_nitwit.png",
@ -531,9 +577,6 @@ end
jobsites = populate_jobsites()
local spawnable_bed={}
table.insert(spawnable_bed, "mcl_beds:bed_red_bottom")
local function stand_still(self)
self.walk_chance = 0
self.jump = false
@ -601,6 +644,95 @@ function get_activity(tod)
end
local function find_closest_bed (self)
local p = self.object:get_pos()
--local spawnable_bed={}
--table.insert(spawnable_bed, "mcl_beds:bed_red_bottom")
--local nn = minetest.find_nodes_in_area(vector.offset(p,-48,-48,-48),vector.offset(p,48,48,48), spawnable_bed)
--if nn then
-- mcl_log("Red beds: " .. #nn)
--end
local unclaimed_beds = {}
local nn2 = minetest.find_nodes_in_area(vector.offset(p,-48,-48,-48),vector.offset(p,48,48,48), {"group:bed"})
if nn2 then
--mcl_log("All bed parts: " .. #nn2)
for a,b in pairs(nn2) do
mcl_log("b: " .. minetest.pos_to_string(b))
local bed_node = minetest.get_node(b)
local bed_name = bed_node.name
local is_bed_bottom = string.find(bed_name,"_bottom")
local bed_meta = minetest.get_meta(b)
local owned_by = bed_meta:get_string("villager")
--mcl_log("Owned by villager: ".. tostring(owned_by))
if (owned_by and owned_by == self._id) then
mcl_log("Clear as already owned by me.")
bed_meta:set_string("villager", nil)
owned_by = nil
end
if is_bed_bottom then
local bed_top = mcl_beds.get_bed_top (b)
mcl_log("bed_top: " .. tostring(bed_top))
local bed_top_node = minetest.get_node(bed_top)
if bed_top_node then
mcl_log("There is a block here for bed top: ".. bed_top_node.name)
else
mcl_log("There is no block here for bed top")
end
local bed_top_meta = minetest.get_meta(bed_top)
local owned_by_player = bed_top_meta:get_string("player")
if bed_top_meta then
mcl_log("Player: " .. tostring(owned_by_player))
else
mcl_log("No bed top meta")
end
if owned_by == "" and (not owned_by_player or owned_by_player == "") then
table.insert(unclaimed_beds, b)
mcl_log("is an unowned bed bottom")
else
end
else
--mcl_log("bed_node name: " .. bed_name)
end
end
end
local distance_to_closest_block = nil
local closest_block = nil
if unclaimed_beds then
mcl_log("All unclaimed bed bottoms: " .. #unclaimed_beds)
for i,b in pairs(unclaimed_beds) do
mcl_log("b: " .. minetest.pos_to_string(b))
local distance_to_block = vector.distance(p, b)
mcl_log("Distance to block ".. i .. ": ".. distance_to_block)
if not distance_to_closest_block or distance_to_closest_block > distance_to_block then
mcl_log("This block is closer than the last.")
closest_block = b
distance_to_closest_block = distance_to_block
end
local bed_node = minetest.get_node(b)
local bed_name = bed_node.name
mcl_log("bed_node name: " .. bed_name)
end
end
return closest_block
end
local function find_closest_unclaimed_block (p, requested_block_types)
local nn = minetest.find_nodes_in_area(vector.offset(p,-48,-48,-48),vector.offset(p,48,48,48), requested_block_types)
@ -634,7 +766,10 @@ local function check_bed (entity)
end
local n = minetest.get_node(b)
if n and n.name ~= "mcl_beds:bed_red_bottom" then
local is_bed_bottom = string.find(n.name,"_bottom")
mcl_log("" .. tostring(is_bed_bottom))
if n and not is_bed_bottom then
mcl_log("Where did my bed go?!")
entity._bed = nil --the stormtroopers have killed uncle owen
return false
@ -702,28 +837,44 @@ local function take_bed (entity)
local p = entity.object:get_pos()
local closest_block = find_closest_unclaimed_block (p, spawnable_bed)
local closest_block = find_closest_bed (entity)
if closest_block then
local m = minetest.get_meta(closest_block)
mcl_log("Can we path to bed: "..minetest.pos_to_string(closest_block) )
local gp = mcl_mobs:gopath(entity, closest_block,function(self)
if self then
self.order = SLEEP
mcl_log("Sleepy time" )
else
mcl_log("Can't sleep, no self in the callback" )
local distance_to_block = vector.distance(p, closest_block)
mcl_log("Distance: " .. distance_to_block)
if distance_to_block < 2 then
local m = minetest.get_meta(closest_block)
local owner = m:get_string("villager")
mcl_log("owner: ".. owner)
if owner and owner ~= "" and owner ~= entity._id then
mcl_log("Already taken")
if entity.order == "stand" then entity.order = nil end
return
end
end)
if gp then
mcl_log("Nice bed. I'll defintely take it as I can path")
if entity.order ~= SLEEP then
mcl_log("Sleepy time" )
entity.order = SLEEP
m:set_string("villager", entity._id)
entity._bed = closest_block
else
--entity.order = nil
mcl_log("Set as sleep already..." )
end
else
local gp = mcl_mobs:gopath(entity, closest_block,function(self) end)
if gp then
mcl_log("Nice bed. I'll defintely take it as I can path")
else
mcl_log("Awww. I can't find my bed.")
end
end
else
mcl_log("Cannot find a bed to claim.")
if entity.order == "stand" then entity.order = nil end
end
end
local function has_golem(pos)
@ -1058,11 +1209,46 @@ local function go_to_town_bell(self)
return nil
end
local function validate_bed(self)
if not self or not self._bed then
return false
end
local n = mcl_vars.get_node(self._bed)
if not n then
self._bed = nil
return false
end
local bed_valid = true
local m = minetest.get_meta(self._bed)
local owned_by_player = m:get_string("player")
mcl_log("Player owner: " .. owned_by_player)
if owned_by_player ~= "" then
mcl_log("Player owns this. Villager won't take this.")
m:set_string("villager", nil)
self._bed = nil
bed_valid = false
return
end
if m:get_string("villager") ~= self._id then
mcl_log("This bed is owned by another player. I'll unclaim.")
self._bed = nil
return false
else
mcl_log("Bed is valid")
return true
end
end
local function do_activity (self)
-- Maybe just check we're pathfinding first?
if not self._bed and self.state ~= PATHFINDING then
--mcl_log("Villager has no bed. Currently at location: "..minetest.pos_to_string(self.object:get_pos()))
if not validate_bed(self) and self.state ~= PATHFINDING then
if self.order == SLEEP then self.order = nil end
mcl_log("Villager has no bed. Currently at location: "..minetest.pos_to_string(self.object:get_pos()))
take_bed (self)
end
@ -1832,7 +2018,7 @@ mcl_mobs:register_mob("mobs_mc:villager", {
end
end
if has_player then
minetest.log("verbose", "[mobs_mc] Player near villager found!")
--minetest.log("verbose", "[mobs_mc] Player near villager found!")
stand_still(self)
else
--minetest.log("verbose", "[mobs_mc] No player near villager found!")

@ -213,8 +213,7 @@ minetest.register_on_punchnode(function(pos, node, puncher, pointed_thing)
if pointed_thing.type ~= "node" then return end
local def = minetest.registered_nodes[node.name]
if def then
if def.on_destruct then def.on_destruct(pos) end
minetest.dig_node(pos)
minetest.node_dig(pos,node,puncher)
return true
end
end)

@ -10,6 +10,10 @@ local explosions_mod = minetest.get_modpath("mcl_explosions")
local spawn_mod = minetest.get_modpath("mcl_spawn")
local worlds_mod = minetest.get_modpath("mcl_worlds")
local function mcl_log (message)
mcl_util.mcl_log (message, "[Beds]")
end
-- Helper functions
local function get_look_yaw(pos)
@ -300,6 +304,37 @@ function mcl_beds.skip_night()
minetest.set_timeofday(0.25) -- tod = 6000
end
function mcl_beds.get_bed_top (pos)
local node = minetest.get_node(pos)
local dir = minetest.facedir_to_dir(node.param2)
local bed_top_pos = vector.add(pos, dir)
local bed_top = minetest.get_node(bed_top_pos)
if bed_top then
mcl_log("Has a bed top")
else
mcl_log("No bed top")
end
return bed_top_pos
end
function mcl_beds.get_bed_bottom (pos)
local node = minetest.get_node(pos)
local dir = minetest.facedir_to_dir(node.param2)
mcl_log("Dir: " .. tostring(dir))
local bed_bottom = vector.add(pos, -dir)
mcl_log("bed_bottom: " .. tostring(bed_bottom))
local bed_bottom_node = minetest.get_node(bed_bottom)
if bed_bottom_node then
mcl_log("Bed bottom node name:" .. bed_bottom_node.name)
else
mcl_log("Didn't get bed bottom")
end
return bed_bottom
end
function mcl_beds.on_rightclick(pos, player, is_top)
-- Anti-Inception: Don't allow to sleep while you're sleeping
if player:get_meta():get_string("mcl_beds:sleeping") == "true" then
@ -329,9 +364,7 @@ function mcl_beds.on_rightclick(pos, player, is_top)
if is_top then
message = select(2, lay_down(player, ppos, pos))
else
local node = minetest.get_node(pos)
local dir = minetest.facedir_to_dir(node.param2)
local other = vector.add(pos, dir)
local other = mcl_beds.get_bed_top (pos)
message = select(2, lay_down(player, ppos, other))
end
if message then

@ -14,11 +14,11 @@ mcl_itemframes.backwards_compatibility()
-- Define the standard frames.
mcl_itemframes.create_custom_frame("false", "item_frame", false,
"mcl_itemframes_item_frame.png", mcl_colors.WHITE, "Item Frame",
"Can hold an item.","")
"mcl_itemframes_item_frame.png", mcl_colors.WHITE, "Can hold an item.",
"Item Frame", "")
mcl_itemframes.create_custom_frame("false", "glow_item_frame", true,
"mcl_itemframes_glow_item_frame.png", mcl_colors.WHITE, "Glowing Item Frame",
"Can hold an item and glows.","")
"mcl_itemframes_glow_item_frame.png", mcl_colors.WHITE, "Can hold an item and glows.",
"Glowing Item Frame", "")
-- Register the base frame's recipes.
-- was going to make it a specialized function, but minetest refuses to play nice.
@ -37,26 +37,4 @@ minetest.register_craft({
recipe = { 'mcl_mobitems:glow_ink_sac', 'mcl_itemframes:item_frame' },
})
--[[ green frames just for testing
mcl_itemframes.create_custom_frame("false", "my_regular_frame", false,
"mcl_itemframes_item_frame.png", mcl_colors.DARK_GREEN, "A Green frame",
"My Green Frame")
mcl_itemframes.create_custom_frame("false", "my_glowing_frame", true,
"mcl_itemframes_glow_item_frame.png", mcl_colors.DARK_GREEN, "A Green glowing frame",
"My Green glowing Frame")
minetest.register_craft({
output = "mcl_itemframes:my_regular_frame",
recipe = {
{ "", "mcl_core:stick", "" },
{ "mcl_core:stick", "", "mcl_core:stick" },
{ "", "mcl_core:stick", "" },
}
})
minetest.register_craft({
type = "shapeless",
output = "mcl_itemframes:my_glowing_frame",
recipe = { "mcl_mobitems:glow_ink_sac", "mcl_itemframes:my_regular_frame" },
})
--]]
mcl_itemframes.custom_register_lbm()

@ -529,18 +529,30 @@ function mcl_itemframes.create_custom_frame(modname, name, has_glow, tiles, colo
minetest.register_node(":" .. working_name, custom_itemframe_definition)
mcl_itemframes.update_frame_registry(modname, working_name, has_glow)
mcl_itemframes.custom_register_lbm(working_name)
-- register Doc entry
if minetest.get_modpath("doc") then
doc.add_entry_alias("nodes", "mcl_itemframes:item_frame", "nodes", working_name)
end
end
function mcl_itemframes.custom_register_lbm(name)
function mcl_itemframes.custom_register_lbm()
local registered_frame_nodenames = {}
for i = 0, #mcl_itemframes.frames_registered.glowing do
table.insert(registered_frame_nodenames, mcl_itemframes.frames_registered.glowing[i])
end
for i = 0, #mcl_itemframes.frames_registered.standard do
table.insert(registered_frame_nodenames, mcl_itemframes.frames_registered.standard[i])
end
-- FIXME: Item entities can get destroyed by /clearobjects
-- glow frame
minetest.register_lbm({
label = "Respawn item frame item entities",
name = "mcl_itemframes:respawn_entities",
nodenames = { name },
nodenames = registered_frame_nodenames,
run_at_every_load = true,
action = function(pos, node)
mcl_itemframes.update_item_entity(pos, node)
@ -562,6 +574,7 @@ function mcl_itemframes.create_base_definitions()
mcl_itemframes.item_frame_base = {
description = S("Item Frame"),
name = "mcl_itemframes:item_frame",
_tt_help = S("Can hold an item"),
_doc_items_longdesc = S("Item frames are decorative blocks in which items can be placed."),
_doc_items_usagehelp = S("Just place any item on the item frame. Use the item frame again to retrieve the item."),

@ -1,34 +1,49 @@
local S = minetest.get_translator("mobs_mc")
local S = minetest.get_translator("mcl_lightning_rods")
---@type nodebox
local cbox = {
type = "fixed",
fixed = {
{ 0/16, -8/16, 0/16, 2/16, 4/16, 2/16 },
{ 0/16, 4/16, 0/16, 3/16, 8/16, 3/16 },
}
{ -0.0625, -0.5, -0.0625, 0.0625, 0.25, 0.0625 },
{ -0.125, 0.25, -0.125, 0.125, 0.5, 0.125 },
},
}
minetest.register_node("mcl_lightning_rods:rod", {
local text_top = "[combine:16x16:6,6=mcl_lightning_rods_rod.png"
local text_side = "[combine:16x16:7,0=mcl_lightning_rods_rod.png:-6,0=mcl_lightning_rods_rod.png\\^[transformR270"
local text_top_active = "[combine:16x16:6,6=mcl_lightning_rods_rod.png\\^[brighten"
local text_side_active = "[combine:16x16:7,0=mcl_lightning_rods_rod.png\\^[brighten:-6,0=mcl_lightning_rods_rod.png\\^[transformR270\\^[brighten"
---@type node_definition
local rod_def = {
description = S("Lightning Rod"),
_doc_items_longdesc = S("A block that attracts lightning"),
--inventory_image = "mcl_lightning_rods_rod_inv.png",
tiles = {
"mcl_lightning_rods_rod.png",
"mcl_lightning_rods_rod.png",
"mcl_lightning_rods_rod.png",
"mcl_lightning_rods_rod.png",
"mcl_lightning_rods_rod.png",
"mcl_lightning_rods_rod.png",
text_top,
text_top,
text_side,
text_side,
text_side,
text_side,
},
drawtype = "nodebox",
is_ground_content = false,
paramtype = "light",
paramtype2 = "facedir",
groups = {pickaxey=2,attracts_lightning=1},
use_texture_alpha = "opaque",
groups = { pickaxey = 2, attracts_lightning = 1 },
sounds = mcl_sounds.node_sound_metal_defaults(),
node_box = cbox,
selection_box = cbox,
collision_box = cbox,
node_placement_prediction = "",
mesecons = {
receptor = {
state = mesecon.state.off,
rules = mesecon.rules.alldirs,
},
},
on_place = function(itemstack, placer, pointed_thing)
if pointed_thing.type ~= "node" then
return itemstack
@ -40,12 +55,7 @@ minetest.register_node("mcl_lightning_rods:rod", {
local placer_pos = placer:get_pos()
if placer_pos then
local dir = {
x = p1.x - placer_pos.x,
y = p1.y - placer_pos.y,
z = p1.z - placer_pos.z
}
param2 = minetest.dir_to_facedir(dir)
param2 = minetest.dir_to_facedir(vector.subtract(p1, placer_pos))
end
if p0.y - 1 == p1.y then
@ -63,20 +73,66 @@ minetest.register_node("mcl_lightning_rods:rod", {
return minetest.item_place(itemstack, placer, pointed_thing, param2)
end,
sounds = mcl_sounds.node_sound_glass_defaults(),
_mcl_blast_resistance = 0,
})
}
lightning.register_on_strike(function(pos,pos2,objects)
local lr = minetest.find_node_near(pos,128,{"group:attracts_lightning"},true)
return lr,nil
minetest.register_node("mcl_lightning_rods:rod", rod_def)
local rod_def_a = table.copy(rod_def)
rod_def_a.tiles = {
text_top_active,
text_top_active,
text_side_active,
text_side_active,
text_side_active,
text_side_active,
}
rod_def_a.groups.not_in_creative_inventory = 1
rod_def_a.mesecons = {
receptor = {
state = mesecon.state.on,
rules = mesecon.rules.alldirs,
},
}
rod_def_a.on_timer = function(pos, elapsed)
local node = minetest.get_node(pos)
if node.name == "mcl_lightning_rods:rod_powered" then --has not been dug
minetest.set_node(pos, { name = "mcl_lightning_rods:rod" })
mesecon.receptor_off(pos, mesecon.rules.alldirs)
end
return false
end
minetest.register_node("mcl_lightning_rods:rod_powered", rod_def_a)
lightning.register_on_strike(function(pos, pos2, objects)
local lr = minetest.find_node_near(pos, 128, { "group:attracts_lightning" }, true)
if lr then
local node = minetest.get_node(lr)
if node.name == "mcl_lightning_rods:rod" then
minetest.set_node(lr, { name = "mcl_lightning_rods:rod_powered" })
mesecon.receptor_on(lr, mesecon.rules.alldirs)
minetest.get_node_timer(lr):start(0.4)
end
end
return lr, nil
end)
minetest.register_craft({
output = "mcl_lightning_rods:rod",
recipe = {
{"", "mcl_copper:copper_ingot",""},
{"", "mcl_copper:copper_ingot",""},
{"", "mcl_copper:copper_ingot",""},
}
{ "", "mcl_copper:copper_ingot", "" },
{ "", "mcl_copper:copper_ingot", "" },
{ "", "mcl_copper:copper_ingot", "" },
},
})

@ -0,0 +1,3 @@
# textdomain: mcl_lightning_rods
Lightning Rod=Paratonnerre
A block that attracts lightning=Un bloc qui attire la foudre

@ -0,0 +1,3 @@
# textdomain: mcl_lightning_rods
Lightning Rod=
A block that attracts lightning=

@ -1,3 +1,3 @@
name = mcl_lightning_rods
author = cora
depends = mcl_sounds, lightning
depends = mcl_sounds, lightning, mesecons

Binary file not shown.

Before

Width:  |  Height:  |  Size: 236 B

After

Width:  |  Height:  |  Size: 203 B

@ -121,8 +121,8 @@ end
local node_stand, node_stand_below, node_head, node_feet, node_head_top
local is_swimming
local set_bone_position_conditional = mcl_util.set_bone_position
local set_properties_conditional = mcl_util.set_properties
local set_bone_pos = mcl_util.set_bone_position
local set_properties = mcl_util.set_properties
local function get_overall_velocity(vector)
local v = math.sqrt(vector.x^2 + vector.y^2 + vector.z^2)
@ -145,6 +145,31 @@ local elytra_vars = {
rocket_speed = 5.5,
}
local player_props_elytra = {
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 }
}
local player_props_riding = {
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 }
}
local player_props_sneaking = {
collisionbox = { -0.312, 0, -0.312, 0.312, 1.8, 0.312 },
eye_height = 1.35,
nametag_color = { r = 225, b = 225, a = 0, g = 225 }
}
local player_props_swimming = {
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 }
}
local player_props_normal = {
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 }
}
minetest.register_globalstep(function(dtime)
@ -208,7 +233,7 @@ minetest.register_globalstep(function(dtime)
end
elytra.active = player:get_inventory():get_stack("armor", 3):get_name() == "mcl_armor:elytra"
and not player:get_attach()
and not parent
and (elytra.active or (is_just_jumped and player_velocity.y < -0))
and ((not minetest.registered_nodes[fly_node].walkable) or fly_node == "ignore")
@ -273,84 +298,101 @@ minetest.register_globalstep(function(dtime)
end
if wielded_def and wielded_def._mcl_toollike_wield then
set_bone_position_conditional(player,"Wield_Item", vector.new(0,4.7,3.1), vector.new(-90,225,90))
set_bone_pos(player, "Wield_Item", vector.new(0, 4.7, 3.1), vector.new(-90, 225, 90))
elseif string.find(wielded:get_name(), "mcl_bows:bow") then
set_bone_position_conditional(player,"Wield_Item", vector.new(1,4,0), vector.new(90,130,115))
set_bone_pos(player, "Wield_Item", vector.new(1, 4, 0), vector.new(90, 130, 115))
elseif string.find(wielded:get_name(), "mcl_bows:crossbow_loaded") then
set_bone_position_conditional(player,"Wield_Item", vector.new(0,5.2,1.2), vector.new(0,180,73))
set_bone_pos(player, "Wield_Item", vector.new(0, 5.2, 1.2), vector.new(0, 180, 73))
elseif string.find(wielded:get_name(), "mcl_bows:crossbow") then
set_bone_position_conditional(player,"Wield_Item", vector.new(0,5.2,1.2), vector.new(0,180,45))
set_bone_pos(player, "Wield_Item", vector.new(0, 5.2, 1.2), vector.new(0, 180, 45))
elseif wielded_def.inventory_image == "" then
set_bone_position_conditional(player,"Wield_Item", vector.new(0,6,2), vector.new(180,-45,0))
set_bone_pos(player,"Wield_Item", vector.new(0, 6, 2), vector.new(180, -45, 0))
else
set_bone_position_conditional(player,"Wield_Item", vector.new(0,5.3,2), vector.new(90,0,0))
set_bone_pos(player, "Wield_Item", vector.new(0, 5.3, 2), vector.new(90, 0, 0))
end
-- controls right and left arms pitch when shooting a bow or blocking
if mcl_shields.is_blocking(player) == 2 then
set_bone_position_conditional(player, "Arm_Right_Pitch_Control", vector.new(-3, 5.785, 0), vector.new(20, -20, 0))
set_bone_pos(player, "Arm_Right_Pitch_Control", nil, vector.new(20, -20, 0))
elseif mcl_shields.is_blocking(player) == 1 then
set_bone_position_conditional(player, "Arm_Left_Pitch_Control", vector.new(3, 5.785, 0), vector.new(20, 20, 0))
set_bone_pos(player, "Arm_Left_Pitch_Control", nil, vector.new(20, 20, 0))
elseif string.find(wielded:get_name(), "mcl_bows:bow") and control.RMB then
set_bone_position_conditional(player,"Arm_Right_Pitch_Control", vector.new(-3,5.785,0), vector.new(pitch+90,-30,pitch * -1 * .35))
set_bone_position_conditional(player,"Arm_Left_Pitch_Control", vector.new(3.5,5.785,0), vector.new(pitch+90,43,pitch * .35))
local right_arm_rot = vector.new(pitch + 90, -30, pitch * -1 * .35)
local left_arm_rot = vector.new(pitch + 90, 43, pitch * .35)
set_bone_pos(player, "Arm_Right_Pitch_Control", nil, right_arm_rot)
set_bone_pos(player, "Arm_Left_Pitch_Control", nil, left_arm_rot)
-- controls right and left arms pitch when holing a loaded crossbow
elseif string.find(wielded:get_name(), "mcl_bows:crossbow_loaded") then
set_bone_position_conditional(player,"Arm_Right_Pitch_Control", vector.new(-3,5.785,0), vector.new(pitch+90,-30,pitch * -1 * .35))
set_bone_position_conditional(player,"Arm_Left_Pitch_Control", vector.new(3.5,5.785,0), vector.new(pitch+90,43,pitch * .35))
local right_arm_rot = vector.new(pitch + 90, -30, pitch * -1 * .35)
local left_arm_rot = vector.new(pitch + 90, 43, pitch * .35)
set_bone_pos(player, "Arm_Right_Pitch_Control", nil, right_arm_rot)
set_bone_pos(player, "Arm_Left_Pitch_Control", nil, left_arm_rot)
-- controls right and left arms pitch when loading a crossbow
elseif string.find(wielded:get_name(), "mcl_bows:crossbow_") then
set_bone_position_conditional(player,"Arm_Right_Pitch_Control", vector.new(-3,5.785,0), vector.new(45,-20,25))
set_bone_position_conditional(player,"Arm_Left_Pitch_Control", vector.new(3,5.785,0), vector.new(55,20,-45))
set_bone_pos(player, "Arm_Right_Pitch_Control", nil, vector.new(45, -20, 25))
set_bone_pos(player, "Arm_Left_Pitch_Control", nil, vector.new(55, 20, -45))
-- when punching
elseif control.LMB and not parent then
set_bone_position_conditional(player,"Arm_Right_Pitch_Control", vector.new(-3,5.785,0), vector.new(pitch,0,0))
set_bone_position_conditional(player,"Arm_Left_Pitch_Control", vector.new(3,5.785,0), vector.new(0,0,0))
set_bone_pos(player,"Arm_Right_Pitch_Control", nil, vector.new(pitch, 0, 0))
set_bone_pos(player,"Arm_Left_Pitch_Control", nil, vector.zero())
-- when holding an item.
elseif wielded:get_name() ~= "" then
set_bone_position_conditional(player,"Arm_Right_Pitch_Control", vector.new(-3,5.785,0), vector.new(20,0,0))
set_bone_position_conditional(player,"Arm_Left_Pitch_Control", vector.new(3,5.785,0), vector.new(0,0,0))
set_bone_pos(player, "Arm_Right_Pitch_Control", nil, vector.new(20, 0, 0))
set_bone_pos(player, "Arm_Left_Pitch_Control", nil, vector.zero())
-- resets arms pitch
else
set_bone_position_conditional(player,"Arm_Left_Pitch_Control", vector.new(3,5.785,0), vector.new(0,0,0))
set_bone_position_conditional(player,"Arm_Right_Pitch_Control", vector.new(-3,5.785,0), vector.new(0,0,0))
set_bone_pos(player, "Arm_Left_Pitch_Control", nil, vector.zero())
set_bone_pos(player, "Arm_Right_Pitch_Control", nil, vector.zero())
end
if elytra.active then
-- set head pitch and yaw when flying
set_bone_position_conditional(player,"Head_Control", vector.new(0,6.3,0), vector.new(pitch-degrees(dir_to_pitch(player_velocity))+50,player_vel_yaw - yaw,0))
local head_rot = vector.new(pitch - degrees(dir_to_pitch(player_velocity)) + 50, player_vel_yaw - yaw, 0)
set_bone_pos(player,"Head_Control", nil, head_rot)
-- sets eye height, and nametag color accordingly
set_properties_conditional(player,{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 }})
set_properties(player, player_props_elytra)
-- control body bone when flying
set_bone_position_conditional(player,"Body_Control", vector.new(0,6.3,0), vector.new((75-degrees(dir_to_pitch(player_velocity))) , -player_vel_yaw + yaw, 0))
local body_rot = vector.new((75 - degrees(dir_to_pitch(player_velocity))), -player_vel_yaw + yaw, 0)
set_bone_pos(player, "Body_Control", nil, body_rot)
elseif parent then
set_properties(player, player_props_riding)
local parent_yaw = degrees(parent:get_yaw())
set_properties_conditional(player,{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 }})
set_bone_position_conditional(player,"Head_Control", vector.new(0,6.3,0), vector.new(pitch, -limit_vel_yaw(yaw, parent_yaw) + parent_yaw, 0))
set_bone_position_conditional(player,"Body_Control", vector.new(0,6.3,0), vector.new(0,0,0))
local head_rot = vector.new(pitch, -limit_vel_yaw(yaw, parent_yaw) + parent_yaw, 0)
set_bone_pos(player, "Head_Control", nil, head_rot)
set_bone_pos(player,"Body_Control", nil, vector.zero())
elseif control.sneak then
-- controls head pitch when sneaking
set_bone_position_conditional(player,"Head_Control", vector.new(0,6.3,0), vector.new(pitch, player_vel_yaw - yaw, player_vel_yaw - yaw))
local head_rot = vector.new(pitch, player_vel_yaw - yaw, player_vel_yaw - yaw)
set_bone_pos(player, "Head_Control", nil, head_rot)
-- sets eye height, and nametag color accordingly
set_properties_conditional(player,{collisionbox = {-0.312,0,-0.312,0.312,1.8,0.312}, eye_height = 1.35, nametag_color = { r = 225, b = 225, a = 0, g = 225 }})
set_properties(player, player_props_sneaking)
-- sneaking body conrols
set_bone_position_conditional(player,"Body_Control", vector.new(0,6.3,0), vector.new(0, -player_vel_yaw + yaw, 0))
set_bone_pos(player, "Body_Control", nil, vector.new(0, -player_vel_yaw + yaw, 0))
elseif get_item_group(mcl_playerinfo[name].node_head, "water") ~= 0 and is_sprinting(name) == true then
-- set head pitch and yaw when swimming
is_swimming = true
set_bone_position_conditional(player,"Head_Control", vector.new(0,6.3,0), vector.new(pitch-degrees(dir_to_pitch(player_velocity))+20,player_vel_yaw - yaw,0))
local head_rot = vector.new(pitch - degrees(dir_to_pitch(player_velocity)) + 20, player_vel_yaw - yaw, 0)
set_bone_pos(player, "Head_Control", nil, head_rot)
-- sets eye height, and nametag color accordingly
set_properties_conditional(player,{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 }})
set_properties(player, player_props_swimming)
-- control body bone when swimming
set_bone_position_conditional(player,"Body_Control", vector.new(0,6.3,0), vector.new((75-degrees(dir_to_pitch(player_velocity))) , -player_vel_yaw + yaw, 0))
local body_rot = vector.new((75 + degrees(dir_to_pitch(player_velocity))), player_vel_yaw - yaw, 180)
set_bone_pos(player,"Body_Control", nil, body_rot)
elseif get_item_group(mcl_playerinfo[name].node_head, "solid") == 0
and get_item_group(mcl_playerinfo[name].node_head_top, "solid") == 0 then
-- sets eye height, and nametag color accordingly
is_swimming = false
set_properties_conditional(player,{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 }})
set_properties(player, player_props_normal)
set_bone_position_conditional(player,"Head_Control", vector.new(0,6.3,0), vector.new(pitch, player_vel_yaw - yaw, 0))
set_bone_position_conditional(player,"Body_Control", vector.new(0,6.3,0), vector.new(0, -player_vel_yaw + yaw, 0))
set_bone_pos(player,"Head_Control", nil, vector.new(pitch, player_vel_yaw - yaw, 0))
set_bone_pos(player,"Body_Control", nil, vector.new(0, -player_vel_yaw + yaw, 0))
end
elytra.last_yaw = player:get_look_horizontal()
@ -507,7 +549,7 @@ minetest.register_globalstep(function(dtime)
--[[ Swimming: Cause exhaustion.
NOTE: As of 0.4.15, it only counts as swimming when you are with the feet inside the liquid!
Head alone does not count. We respect that for now. ]]
if not player:get_attach() and (get_item_group(node_feet, "liquid") ~= 0 or
if not parent and (get_item_group(node_feet, "liquid") ~= 0 or
get_item_group(node_stand, "liquid") ~= 0) then
local lastPos = mcl_playerplus_internal[name].lastPos
if lastPos then
@ -597,6 +639,13 @@ minetest.register_on_joinplayer(function(player)
jump_cooldown = -1, -- Cooldown timer for jumping, we need this to prevent the jump exhaustion to increase rapidly
}
mcl_playerplus.elytra[player] = {active = false, rocketing = 0, speed = 0}
-- Minetest bug: get_bone_position() returns all zeros vectors.
-- Workaround: call set_bone_position() one time first.
player:set_bone_position("Head_Control", vector.new(0, 6.75, 0))
player:set_bone_position("Arm_Right_Pitch_Control", vector.new(-3, 5.785, 0))
player:set_bone_position("Arm_Left_Pitch_Control", vector.new(3, 5.785, 0))
player:set_bone_position("Body_Control", vector.new(0, 6.75, 0))
end)
-- clear when player leaves

@ -4,6 +4,10 @@ local S = minetest.get_translator(minetest.get_current_modname())
local mg_name = minetest.get_mapgen_setting("mg_name")
local storage = minetest.get_mod_storage()
local function mcl_log (message)
mcl_util.mcl_log (message, "[Spawn]")
end
-- Parameters
-------------
@ -429,6 +433,41 @@ function mcl_spawn.set_spawn_pos(player, pos, message)
else
local oldpos = minetest.string_to_pos(meta:get_string("mcl_beds:spawn"))
meta:set_string("mcl_beds:spawn", minetest.pos_to_string(pos))
-- Set player ownership on bed
local bed_node = minetest.get_node(pos)
local bed_meta = minetest.get_meta(pos)
local bed_bottom = mcl_beds.get_bed_bottom (pos)
local bed_bottom_meta = minetest.get_meta(bed_bottom)
if bed_meta then
if bed_node then
mcl_log("Bed name: " .. bed_node.name)
end
mcl_log("Setting bed meta: " .. player:get_player_name())
bed_meta:set_string("player", player:get_player_name())
-- Pass in villager as arg. Shouldn't know about villagers
if bed_bottom_meta then
mcl_log("Removing villager from bed bottom meta")
bed_bottom_meta:set_string("villager", nil)
else
mcl_log("Cannot remove villager from bed bottom meta")
end
local old_bed_meta = minetest.get_meta(oldpos)
if oldpos ~= pos and old_bed_meta then
mcl_log("Removing old bed meta")
old_bed_meta:set_string("player", "")
else
mcl_log("No old bed meta to remove or same as current")
end
end
if oldpos then
-- We don't bother sending a message if the new spawn pos is basically the same
spawn_changed = vector.distance(pos, oldpos) > 0.1