diff --git a/mods/CORE/mcl_util/init.lua b/mods/CORE/mcl_util/init.lua index 0972e5019..4684234e5 100644 --- a/mods/CORE/mcl_util/init.lua +++ b/mods/CORE/mcl_util/init.lua @@ -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 diff --git a/mods/ENTITIES/mcl_mobs/api.lua b/mods/ENTITIES/mcl_mobs/api.lua index 06a273a14..b306b0fd7 100644 --- a/mods/ENTITIES/mcl_mobs/api.lua +++ b/mods/ENTITIES/mcl_mobs/api.lua @@ -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 diff --git a/mods/ENTITIES/mobs_mc/textures/mobs_mc_villager_mason.png b/mods/ENTITIES/mobs_mc/textures/mobs_mc_villager_mason.png new file mode 100644 index 000000000..a09e79b2a Binary files /dev/null and b/mods/ENTITIES/mobs_mc/textures/mobs_mc_villager_mason.png differ diff --git a/mods/ENTITIES/mobs_mc/villager.lua b/mods/ENTITIES/mobs_mc/villager.lua index 81a23756b..7b7eafda5 100644 --- a/mods/ENTITIES/mobs_mc/villager.lua +++ b/mods/ENTITIES/mobs_mc/villager.lua @@ -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" ) - end - end) - if gp then - mcl_log("Nice bed. I'll defintely take it as I can path") - m:set_string("villager", entity._id) - entity._bed = closest_block - else - mcl_log("Awww. I can't find my bed.") - end - end + 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 + + 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!") diff --git a/mods/HUD/mcl_inventory/init.lua b/mods/HUD/mcl_inventory/init.lua index 2c7c64860..4f50a3ef5 100644 --- a/mods/HUD/mcl_inventory/init.lua +++ b/mods/HUD/mcl_inventory/init.lua @@ -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) diff --git a/mods/ITEMS/mcl_beds/functions.lua b/mods/ITEMS/mcl_beds/functions.lua index c745b5f0c..056da71dc 100644 --- a/mods/ITEMS/mcl_beds/functions.lua +++ b/mods/ITEMS/mcl_beds/functions.lua @@ -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 diff --git a/mods/ITEMS/mcl_itemframes/init.lua b/mods/ITEMS/mcl_itemframes/init.lua index e0c41c1f4..553198c67 100644 --- a/mods/ITEMS/mcl_itemframes/init.lua +++ b/mods/ITEMS/mcl_itemframes/init.lua @@ -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() diff --git a/mods/ITEMS/mcl_itemframes/item_frames_API.lua b/mods/ITEMS/mcl_itemframes/item_frames_API.lua index bd78f33e1..741e6ce71 100644 --- a/mods/ITEMS/mcl_itemframes/item_frames_API.lua +++ b/mods/ITEMS/mcl_itemframes/item_frames_API.lua @@ -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."), diff --git a/mods/ITEMS/mcl_lightning_rods/init.lua b/mods/ITEMS/mcl_lightning_rods/init.lua index 41d9adfbd..72763a37b 100644 --- a/mods/ITEMS/mcl_lightning_rods/init.lua +++ b/mods/ITEMS/mcl_lightning_rods/init.lua @@ -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", "" }, + }, }) diff --git a/mods/ITEMS/mcl_lightning_rods/locale/mcl_lightning_rods.fr.tr b/mods/ITEMS/mcl_lightning_rods/locale/mcl_lightning_rods.fr.tr new file mode 100644 index 000000000..8f99047f6 --- /dev/null +++ b/mods/ITEMS/mcl_lightning_rods/locale/mcl_lightning_rods.fr.tr @@ -0,0 +1,3 @@ +# textdomain: mcl_lightning_rods +Lightning Rod=Paratonnerre +A block that attracts lightning=Un bloc qui attire la foudre \ No newline at end of file diff --git a/mods/ITEMS/mcl_lightning_rods/locale/template.txt b/mods/ITEMS/mcl_lightning_rods/locale/template.txt new file mode 100644 index 000000000..5b2bbbcd2 --- /dev/null +++ b/mods/ITEMS/mcl_lightning_rods/locale/template.txt @@ -0,0 +1,3 @@ +# textdomain: mcl_lightning_rods +Lightning Rod= +A block that attracts lightning= \ No newline at end of file diff --git a/mods/ITEMS/mcl_lightning_rods/mod.conf b/mods/ITEMS/mcl_lightning_rods/mod.conf index cafd9ba5e..dd30d7aa7 100644 --- a/mods/ITEMS/mcl_lightning_rods/mod.conf +++ b/mods/ITEMS/mcl_lightning_rods/mod.conf @@ -1,3 +1,3 @@ name = mcl_lightning_rods author = cora -depends = mcl_sounds, lightning +depends = mcl_sounds, lightning, mesecons diff --git a/mods/ITEMS/mcl_lightning_rods/textures/mcl_lightning_rods_rod.png b/mods/ITEMS/mcl_lightning_rods/textures/mcl_lightning_rods_rod.png index 71a081702..355b2bd01 100644 Binary files a/mods/ITEMS/mcl_lightning_rods/textures/mcl_lightning_rods_rod.png and b/mods/ITEMS/mcl_lightning_rods/textures/mcl_lightning_rods_rod.png differ diff --git a/mods/PLAYER/mcl_playerplus/init.lua b/mods/PLAYER/mcl_playerplus/init.lua index 65e107a44..c21392e75 100644 --- a/mods/PLAYER/mcl_playerplus/init.lua +++ b/mods/PLAYER/mcl_playerplus/init.lua @@ -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 diff --git a/mods/PLAYER/mcl_spawn/init.lua b/mods/PLAYER/mcl_spawn/init.lua index 9022dfc25..c8746fdf0 100644 --- a/mods/PLAYER/mcl_spawn/init.lua +++ b/mods/PLAYER/mcl_spawn/init.lua @@ -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