diff --git a/API.md b/API.md index 738fe52fa..e73d5f8a4 100644 --- a/API.md +++ b/API.md @@ -17,6 +17,10 @@ Items can have these fields: anvil. See `mcl_banners` for an example. +Tools can have these fields: +* `_mcl_diggroups`: Specifies the digging groups that a tool can dig and how + efficiently. See `_mcl_autogroup` for more information. + All nodes can have these fields: * `_mcl_hardness`: Hardness of the block, ranges from 0 to infinity (represented by -1). Determines digging times. Default: 0 diff --git a/minetest.conf b/minetest.conf index 7e1ca9cd8..e122db7b3 100644 --- a/minetest.conf +++ b/minetest.conf @@ -33,10 +33,10 @@ mgvalleys_spflags = noaltitude_chill,noaltitude_dry,nohumid_rivers,vary_river_de keepInventory = false # Performance settings -dedicated_server_step = 0.001 -abm_interval = 0.25 -max_objects_per_block = 4096 -max_packets_per_iteration = 10096 +# dedicated_server_step = 0.001 +# abm_interval = 0.25 +# max_objects_per_block = 4096 +# max_packets_per_iteration = 10096 # Clientmodding to support official client enable_client_modding = true diff --git a/mods/CORE/_mcl_autogroup/README.txt b/mods/CORE/_mcl_autogroup/README.txt index b7068a0b3..11383f311 100644 --- a/mods/CORE/_mcl_autogroup/README.txt +++ b/mods/CORE/_mcl_autogroup/README.txt @@ -4,6 +4,11 @@ Specifically, this mod has 2 purposes: 1) Automatically adding the group “solid” for blocks considered “solid” in Minecraft. 2) Generating digging time group for all nodes based on node metadata (it's complicated) +This mod also requires another mod called “mcl_autogroup” to function properly. +“mcl_autogroup” exposes the API used to register digging groups, while this mod +uses those digging groups to set the digging time groups for all the nodes and +tools. + See init.lua for more infos. The leading underscore in the name “_mcl_autogroup” was added to force Minetest to load this mod as late as possible. diff --git a/mods/CORE/_mcl_autogroup/init.lua b/mods/CORE/_mcl_autogroup/init.lua index aabfa5906..75ed4ce2b 100644 --- a/mods/CORE/_mcl_autogroup/init.lua +++ b/mods/CORE/_mcl_autogroup/init.lua @@ -1,169 +1,358 @@ ---[[ Mining times. Yeah, mining times … Alright, this is going to be FUN! +--[[ +This mod implements a HACK to make 100% sure the digging times of all tools +match Minecraft's perfectly. The digging times system of Minetest is very +different, so this weird group trickery has to be used. In Minecraft, each +block has a hardness and the actual Minecraft digging time is determined by +this: -This mod does include a HACK to make 100% sure the digging times of all tools match Minecraft's perfectly. -The digging times system of Minetest is very different, so this weird group trickery has to be used. -In Minecraft, each block has a hardness and the actual Minecraft digging time is determined by this: 1) The block's hardness -2) The tool being used -3) Whether the tool is considered as “eligible” for the block +2) The tool being used (the tool speed and its efficiency level) +3) Whether the tool is considered as "eligible" for the block (e.g. only diamond pick eligible for obsidian) -See Minecraft Wiki for more information. -In MineClone 2, all diggable node have the hardness set in the custom field “_mcl_hardness” (0 by default). -The nodes are also required to specify the “eligible” tools in groups like “pickaxey”, “shovely”, etc. -This mod then calculates the real digging time based on the node meta data. The real digging times -are then added into mcl_autogroup.digtimes where the table indices are group rating and the values are the -digging times in seconds. These digging times can be then added verbatim into the tool definitions. +See Minecraft Wiki for more +information. -Example: -mcl_autogroup.digtimes.pickaxey_dig_diamond[1] = 0.2 +How the mod is used +=================== -→ This means that when a node has been assigned the group “pickaxey_dig_diamond=1”, it can be dug by the -diamond pickaxe in 0.2 seconds. +In MineClone 2, all diggable nodes have the hardness set in the custom field +"_mcl_hardness" (0 by default). These values are used together with digging +groups by this mod to create the correct digging times for nodes. Digging +groups are registered using the following code: + mcl_autogroup.register_diggroup("shovely") + mcl_autogroup.register_diggroup("pickaxey", { + levels = { "wood", "gold", "stone", "iron", "diamond" } + }) +The first line registers a simple digging group. The second line registers a +digging group with 5 different levels (in this case one for each material of a +pickaxes). -This strange setup with mcl_autogroup has been done to minimize the amount of required digging times -a single tool needs to use. If this is not being done, the loading time will increase considerably -(>10s). +Nodes indicate that they belong to a particular digging group by being member of +the digging group in their node definition. "mcl_core:dirt" for example has +shovely=1 in its groups. If the digging group has multiple levels the value of +the group indicates which digging level the node requires. +"mcl_core:stone_with_gold" for example has pickaxey=4 because it requires a +pickaxe of level 4 be mined. -]] +For tools to be able to dig nodes of digging groups they need to use the have +the custom field "_mcl_diggroups" function to get the groupcaps. The value of +this field is a table which defines which groups the tool can dig and how +efficiently. -local materials = { "wood", "gold", "stone", "iron", "diamond" } -local basegroups = { "pickaxey", "axey", "shovely" } -local minigroups = { "handy", "shearsy", "swordy", "shearsy_wool", "swordy_cobweb" } -local divisors = { - ["wood"] = 2, - ["gold"] = 12, - ["stone"] = 4, - ["iron"] = 6, - ["diamond"] = 8, - ["handy"] = 1, - ["shearsy"] = 15, - ["swordy"] = 1.5, - ["shearsy_wool"] = 5, - ["swordy_cobweb"] = 15, -} -local max_efficiency_level = 5 + _mcl_diggroups = { + handy = { speed = 1, level = 1, uses = 0 }, + pickaxey = { speed = 1, level = 0, uses = 0 }, + } -mcl_autogroup = {} -mcl_autogroup.digtimes = {} -mcl_autogroup.creativetimes = {} -- Copy of digtimes, except that all values are 0. Used for creative mode +The "uses" field indicate how many uses (0 for infinite) a tool has when used on +the specified digging group. The "speed" field is a multiplier to the dig speed +on that digging group. -for m=1, #materials do - for g=1, #basegroups do - mcl_autogroup.digtimes[basegroups[g].."_dig_"..materials[m]] = {} - mcl_autogroup.creativetimes[basegroups[g].."_dig_"..materials[m]] = {} - for e=1, max_efficiency_level do - mcl_autogroup.digtimes[basegroups[g].."_dig_"..materials[m].."_efficiency_"..e] = {} +The "level" field indicates which levels of the group the tool can harvest. A +level of 0 means that the tool cannot harvest blocks of that node. A level of 1 +or above means that the tool can harvest nodes with that level or below. See +"mcl_tools/init.lua" for examples on how "_mcl_diggroups" is used in practice. + +Information about the mod +========================= + +The mod is split up into two parts, mcl_autogroup and _mcl_autogroup. +mcl_autogroup contains the API functions used to register custom digging groups. +_mcl_autogroup contains most of the code. The leading underscore in the name +"_mcl_autogroup" is used to force Minetest to load that part of the mod as late +as possible. Minetest loads mods in reverse alphabetical order. + +This also means that it is very important that no mod adds _mcl_autogroup as a +dependency. +--]] + +assert(minetest.get_modpath("mcl_autogroup"), "This mod requires the mod mcl_autogroup to function") + +-- Returns a table containing the unique "_mcl_hardness" for nodes belonging to +-- each diggroup. +local function get_hardness_values_for_groups() + local maps = {} + local values = {} + for g, _ in pairs(mcl_autogroup.registered_diggroups) do + maps[g] = {} + values[g] = {} + end + + for _, ndef in pairs(minetest.registered_nodes) do + for g, _ in pairs(mcl_autogroup.registered_diggroups) do + if ndef.groups[g] ~= nil then + maps[g][ndef._mcl_hardness or 0] = true + end end end -end -for g=1, #minigroups do - mcl_autogroup.digtimes[minigroups[g].."_dig"] = {} - mcl_autogroup.creativetimes[minigroups[g].."_dig"] = {} - for e=1, max_efficiency_level do - mcl_autogroup.digtimes[minigroups[g].."_dig_efficiency_"..e] = {} - mcl_autogroup.creativetimes[minigroups[g].."_dig_efficiency_"..e] = {} + + for g, map in pairs(maps) do + for k, _ in pairs(map) do + table.insert(values[g], k) + end end + + for g, _ in pairs(mcl_autogroup.registered_diggroups) do + table.sort(values[g]) + end + return values +end + +-- Returns a table containing a table indexed by "_mcl_hardness_value" to get +-- its index in the list of unique hardnesses for each diggroup. +local function get_hardness_lookup_for_groups(hardness_values) + local map = {} + for g, values in pairs(hardness_values) do + map[g] = {} + for k, v in pairs(values) do + map[g][v] = k + end + end + return map +end + +-- Array of unique hardness values for each group which affects dig time. +local hardness_values = get_hardness_values_for_groups() + +-- Map indexed by hardness values which return the index of that value in +-- hardness_value. Used for quick lookup. +local hardness_lookup = get_hardness_lookup_for_groups(hardness_values) + +local function compute_creativetimes(group) + local creativetimes = {} + + for index, hardness in pairs(hardness_values[group]) do + table.insert(creativetimes, 0) + end + + return creativetimes +end + +-- Get the list of digging times for using a specific tool on a specific +-- diggroup. +-- +-- Parameters: +-- group - the group which it is digging +-- can_harvest - if the tool can harvest the block +-- speed - dig speed multiplier for tool (default 1) +-- efficiency - efficiency level for the tool if applicable +local function get_digtimes(group, can_harvest, speed, efficiency) + local speed = speed or 1 + if efficiency then + speed = speed + efficiency * efficiency + 1 + end + + local digtimes = {} + + for index, hardness in pairs(hardness_values[group]) do + local digtime = (hardness or 0) / speed + if can_harvest then + digtime = digtime * 1.5 + else + digtime = digtime * 5 + end + + if digtime <= 0.05 then + digtime = 0 + else + digtime = math.ceil(digtime * 20) / 20 + end + table.insert(digtimes, digtime) + end + + return digtimes +end + +-- Get one groupcap field for using a specific tool on a specific group. +local function get_groupcap(group, can_harvest, multiplier, efficiency, uses) + return { + times = get_digtimes(group, can_harvest, multiplier, efficiency), + uses = uses, + maxlevel = 0, + } +end + +-- Add the groupcaps from a field in "_mcl_diggroups" to the groupcaps of a +-- tool. +local function add_groupcaps(toolname, groupcaps, groupcaps_def, efficiency) + for g, capsdef in pairs(groupcaps_def) do + local mult = capsdef.speed or 1 + local uses = capsdef.uses + local def = mcl_autogroup.registered_diggroups[g] + local max_level = def.levels and #def.levels or 1 + + assert(capsdef.level, toolname .. ' is missing level for ' .. g) + local level = math.min(capsdef.level, max_level) + + if def.levels then + groupcaps[g .. "_dig_default"] = get_groupcap(g, false, mult, efficiency, uses) + if level > 0 then + groupcaps[g .. "_dig_" .. def.levels[level]] = get_groupcap(g, true, mult, efficiency, uses) + end + else + groupcaps[g .. "_dig"] = get_groupcap(g, level > 0, mult, efficiency, uses) + end + end + return groupcaps +end + +-- Checks if the given node would drop its useful drop if dug by a given tool. +-- Returns true if it will yield its useful drop, false otherwise. +function mcl_autogroup.can_harvest(nodename, toolname) + local ndef = minetest.registered_nodes[nodename] + + if minetest.get_item_group(nodename, "dig_immediate") >= 2 then + return true + end + + -- Check if it can be dug by tool + local tdef = minetest.registered_tools[toolname] + if tdef and tdef._mcl_diggroups then + for g, gdef in pairs(tdef._mcl_diggroups) do + if ndef.groups[g] then + if ndef.groups[g] <= gdef.level then + return true + end + end + end + end + + -- Check if it can be dug by hand + local tdef = minetest.registered_tools[""] + if tdef then + for g, gdef in pairs(tdef._mcl_diggroups) do + if ndef.groups[g] then + if ndef.groups[g] <= gdef.level then + return true + end + end + end + end + + return false +end + +-- Get one groupcap field for using a specific tool on a specific group. +local function get_groupcap(group, can_harvest, multiplier, efficiency, uses) + return { + times = get_digtimes(group, can_harvest, multiplier, efficiency), + uses = uses, + maxlevel = 0, + } +end + +-- Returns the tool_capabilities from a tool definition or a default set of +-- tool_capabilities +local function get_tool_capabilities(tdef) + if tdef.tool_capabilities then + return tdef.tool_capabilities + end + + -- If the damage group and punch interval from hand is not included, + -- then the user will not be able to attack with the tool. + local hand_toolcaps = minetest.registered_tools[""].tool_capabilities + return { + full_punch_interval = hand_toolcaps.full_punch_interval, + damage_groups = hand_toolcaps.damage_groups + } +end + +-- Get the groupcaps for a tool. This function returns "groupcaps" table of +-- digging which should be put in the "tool_capabilities" of the tool definition +-- or in the metadata of an enchanted tool. +-- +-- Parameters: +-- toolname - Name of the tool being enchanted (like "mcl_tools:diamond_pickaxe") +-- efficiency - The efficiency level the tool is enchanted with (default 0) +-- +-- NOTE: +-- This function can only be called after mod initialization. Otherwise a mod +-- would have to add _mcl_autogroup as a dependency which would break the mod +-- loading order. +function mcl_autogroup.get_groupcaps(toolname, efficiency) + local tdef = minetest.registered_tools[toolname] + local groupcaps = table.copy(get_tool_capabilities(tdef).groupcaps or {}) + add_groupcaps(toolname, groupcaps, tdef._mcl_diggroups, efficiency) + return groupcaps +end + +-- Get the wear from using a tool on a digging group. +-- +-- Parameters +-- toolname - Name of the tool used +-- diggroup - The name of the diggroup the tool is used on +-- +-- NOTE: +-- This function can only be called after mod initialization. Otherwise a mod +-- would have to add _mcl_autogroup as a dependency which would break the mod +-- loading order. +function mcl_autogroup.get_wear(toolname, diggroup) + local tdef = minetest.registered_tools[toolname] + local uses = tdef._mcl_diggroups[diggroup].uses + return math.ceil(65535 / uses) end local overwrite = function() for nname, ndef in pairs(minetest.registered_nodes) do - local groups_changed = false local newgroups = table.copy(ndef.groups) if (nname ~= "ignore" and ndef.diggable) then - -- Automatically assign the “solid” group for solid nodes + -- Automatically assign the "solid" group for solid nodes if (ndef.walkable == nil or ndef.walkable == true) and (ndef.collision_box == nil or ndef.collision_box.type == "regular") and (ndef.node_box == nil or ndef.node_box.type == "regular") and (ndef.groups.not_solid == 0 or ndef.groups.not_solid == nil) then newgroups.solid = 1 - groups_changed = true end - -- Automatically assign the “opaque” group for opaque nodes + -- Automatically assign the "opaque" group for opaque nodes if (not (ndef.paramtype == "light" or ndef.sunlight_propagates)) and (ndef.groups.not_opaque == 0 or ndef.groups.not_opaque == nil) then newgroups.opaque = 1 - groups_changed = true end - local function calculate_group(hardness, material, diggroup, newgroups, actual_rating, expected_rating, efficiency) - local time, validity_factor - if actual_rating >= expected_rating then - -- Valid tool - validity_factor = 1.5 - else - -- Wrong tool (higher digging time) - validity_factor = 5 - end - local speed_multiplier = divisors[material] - if efficiency then - speed_multiplier = speed_multiplier + efficiency * efficiency + 1 - end - time = (hardness * validity_factor) / speed_multiplier - if time <= 0.05 then - time = 0 - else - time = math.ceil(time * 20) / 20 - end - table.insert(mcl_autogroup.digtimes[diggroup], time) - if not efficiency then - table.insert(mcl_autogroup.creativetimes[diggroup], 0) - end - newgroups[diggroup] = #mcl_autogroup.digtimes[diggroup] - return newgroups - end + local creative_breakable = false - -- Hack in digging times - local hardness = ndef._mcl_hardness - if not hardness then - hardness = 0 - end + -- Assign groups used for digging this node depending on + -- the registered digging groups + for g, gdef in pairs(mcl_autogroup.registered_diggroups) do + creative_breakable = true + local index = hardness_lookup[g][ndef._mcl_hardness or 0] + if ndef.groups[g] then + if gdef.levels then + newgroups[g .. "_dig_default"] = index - -- Handle pickaxey, axey and shovely - for _, basegroup in pairs(basegroups) do - if (hardness ~= -1 and ndef.groups[basegroup]) then - for g=1,#materials do - local diggroup = basegroup.."_dig_"..materials[g] - newgroups = calculate_group(hardness, materials[g], diggroup, newgroups, g, ndef.groups[basegroup]) - for e=1,max_efficiency_level do - newgroups = calculate_group(hardness, materials[g], diggroup .. "_efficiency_" .. e, newgroups, g, ndef.groups[basegroup], e) + for i = ndef.groups[g], #gdef.levels do + newgroups[g .. "_dig_" .. gdef.levels[i]] = index end - groups_changed = true - end - end - end - for m=1, #minigroups do - local minigroup = minigroups[m] - if hardness ~= -1 then - local diggroup = minigroup.."_dig" - -- actual rating - local ar = ndef.groups[minigroup] - if ar == nil then - ar = 0 - end - if (minigroup == "handy") - or - (ndef.groups.shearsy_wool and minigroup == "shearsy_wool" and ndef.groups.wool) - or - (ndef.groups.swordy_cobweb and minigroup == "swordy_cobweb" and nname == "mcl_core:cobweb") - or - (ndef.groups[minigroup] and minigroup ~= "swordy_cobweb" and minigroup ~= "shearsy_wool") then - newgroups = calculate_group(hardness, minigroup, diggroup, newgroups, ar, 1) - for e=1,max_efficiency_level do - newgroups = calculate_group(hardness, minigroup, diggroup .. "_efficiency_" .. e, newgroups, ar, 1, e) - end - groups_changed = true + else + newgroups[g .. "_dig"] = index end end end - if groups_changed then - minetest.override_item(nname, { - groups = newgroups - }) - end + -- Automatically assign the node to the + -- creative_breakable group if it belongs to any digging + -- group. + newgroups["creative_breakable"] = 1 + + minetest.override_item(nname, { + groups = newgroups + }) + end + end + + for tname, tdef in pairs(minetest.registered_tools) do + -- Assign groupcaps for digging the registered digging groups + -- depending on the _mcl_diggroups in the tool definition + if tdef._mcl_diggroups then + local toolcaps = table.copy(get_tool_capabilities(tdef)) + toolcaps.groupcaps = mcl_autogroup.get_groupcaps(tname) + + minetest.override_item(tname, { + tool_capabilities = toolcaps + }) end end end diff --git a/mods/CORE/_mcl_autogroup/mod.conf b/mods/CORE/_mcl_autogroup/mod.conf index 11efdf9d1..eea72c40f 100644 --- a/mods/CORE/_mcl_autogroup/mod.conf +++ b/mods/CORE/_mcl_autogroup/mod.conf @@ -1,3 +1,3 @@ name = _mcl_autogroup -author = Wuzzy +author = ryvnf description = MineClone 2 core mod which automatically adds groups to all items. Very important for digging times. diff --git a/mods/CORE/mcl_autogroup/init.lua b/mods/CORE/mcl_autogroup/init.lua new file mode 100644 index 000000000..16dd831c0 --- /dev/null +++ b/mods/CORE/mcl_autogroup/init.lua @@ -0,0 +1,28 @@ +--[[ +This is one part of a mod to replicate the digging times from Minecraft. This +part only exposes a function to register digging groups. The rest of the mod is +implemented and documented in the _mcl_autogroup. + +The mod is split up into two parts, mcl_autogroup and _mcl_autogroup. +mcl_autogroup contains the API functions used to register custom digging groups. +_mcl_autogroup contains most of the code. The leading underscore in the name +"_mcl_autogroup" is used to force Minetest to load that part of the mod as late +as possible. Minetest loads mods in reverse alphabetical order. +--]] +mcl_autogroup = {} +mcl_autogroup.registered_diggroups = {} + +assert(minetest.get_modpath("_mcl_autogroup"), "This mod requires the mod _mcl_autogroup to function") + +-- Register a group as a digging group. +-- +-- Parameters: +-- group - Name of the group to register as a digging group +-- def - Table with information about the diggroup (defaults to {} if unspecified) +-- +-- Values in def: +-- level - If specified it is an array containing the names of the different +-- digging levels the digging group supports. +function mcl_autogroup.register_diggroup(group, def) + mcl_autogroup.registered_diggroups[group] = def or {} +end diff --git a/mods/CORE/mcl_autogroup/mod.conf b/mods/CORE/mcl_autogroup/mod.conf new file mode 100644 index 000000000..45818cd58 --- /dev/null +++ b/mods/CORE/mcl_autogroup/mod.conf @@ -0,0 +1,3 @@ +name = mcl_autogroup +author = ryvnf +description = MineClone 2 core mod which automatically adds groups to all items. Very important for digging times. diff --git a/mods/CORE/mcl_init/init.lua b/mods/CORE/mcl_init/init.lua index 884ebfae1..ca510b74f 100644 --- a/mods/CORE/mcl_init/init.lua +++ b/mods/CORE/mcl_init/init.lua @@ -33,25 +33,26 @@ mcl_vars.MAP_BLOCKSIZE = math.max(1, core.MAP_BLOCKSIZE or 16) mcl_vars.mapgen_limit = math.max(1, tonumber(minetest.get_mapgen_setting("mapgen_limit")) or 31000) mcl_vars.MAX_MAP_GENERATION_LIMIT = math.max(1, core.MAX_MAP_GENERATION_LIMIT or 31000) local central_chunk_offset = -math.floor(mcl_vars.chunksize / 2) -local chunk_size_in_nodes = mcl_vars.chunksize * mcl_vars.MAP_BLOCKSIZE +mcl_vars.central_chunk_offset_in_nodes = central_chunk_offset * mcl_vars.MAP_BLOCKSIZE +mcl_vars.chunk_size_in_nodes = mcl_vars.chunksize * mcl_vars.MAP_BLOCKSIZE local central_chunk_min_pos = central_chunk_offset * mcl_vars.MAP_BLOCKSIZE -local central_chunk_max_pos = central_chunk_min_pos + chunk_size_in_nodes - 1 +local central_chunk_max_pos = central_chunk_min_pos + mcl_vars.chunk_size_in_nodes - 1 local ccfmin = central_chunk_min_pos - mcl_vars.MAP_BLOCKSIZE -- Fullminp/fullmaxp of central chunk, in nodes local ccfmax = central_chunk_max_pos + mcl_vars.MAP_BLOCKSIZE local mapgen_limit_b = math.floor(math.min(mcl_vars.mapgen_limit, mcl_vars.MAX_MAP_GENERATION_LIMIT) / mcl_vars.MAP_BLOCKSIZE) local mapgen_limit_min = -mapgen_limit_b * mcl_vars.MAP_BLOCKSIZE local mapgen_limit_max = (mapgen_limit_b + 1) * mcl_vars.MAP_BLOCKSIZE - 1 -local numcmin = math.max(math.floor((ccfmin - mapgen_limit_min) / chunk_size_in_nodes), 0) -- Number of complete chunks from central chunk -local numcmax = math.max(math.floor((mapgen_limit_max - ccfmax) / chunk_size_in_nodes), 0) -- fullminp/fullmaxp to effective mapgen limits. -mcl_vars.mapgen_edge_min = central_chunk_min_pos - numcmin * chunk_size_in_nodes -mcl_vars.mapgen_edge_max = central_chunk_max_pos + numcmax * chunk_size_in_nodes +local numcmin = math.max(math.floor((ccfmin - mapgen_limit_min) / mcl_vars.chunk_size_in_nodes), 0) -- Number of complete chunks from central chunk +local numcmax = math.max(math.floor((mapgen_limit_max - ccfmax) / mcl_vars.chunk_size_in_nodes), 0) -- fullminp/fullmaxp to effective mapgen limits. +mcl_vars.mapgen_edge_min = central_chunk_min_pos - numcmin * mcl_vars.chunk_size_in_nodes +mcl_vars.mapgen_edge_max = central_chunk_max_pos + numcmax * mcl_vars.chunk_size_in_nodes local function coordinate_to_block(x) return math.floor(x / mcl_vars.MAP_BLOCKSIZE) end local function coordinate_to_chunk(x) - return math.floor((coordinate_to_block(x) + central_chunk_offset) / mcl_vars.chunksize) + return math.floor((coordinate_to_block(x) - central_chunk_offset) / mcl_vars.chunksize) end function mcl_vars.pos_to_block(pos) @@ -70,7 +71,7 @@ function mcl_vars.pos_to_chunk(pos) } end -local k_positive = math.ceil(mcl_vars.MAX_MAP_GENERATION_LIMIT / chunk_size_in_nodes) +local k_positive = math.ceil(mcl_vars.MAX_MAP_GENERATION_LIMIT / mcl_vars.chunk_size_in_nodes) local k_positive_z = k_positive * 2 local k_positive_y = k_positive_z * k_positive_z diff --git a/mods/CORE/mcl_worlds/init.lua b/mods/CORE/mcl_worlds/init.lua index 35549ffad..6cdeaab7e 100644 --- a/mods/CORE/mcl_worlds/init.lua +++ b/mods/CORE/mcl_worlds/init.lua @@ -6,7 +6,7 @@ mcl_worlds = {} function mcl_worlds.is_in_void(pos) local void = not ((pos.y < mcl_vars.mg_overworld_max and pos.y > mcl_vars.mg_overworld_min) or - (pos.y < mcl_vars.mg_nether_max and pos.y > mcl_vars.mg_nether_min) or + (pos.y < mcl_vars.mg_nether_max+128 and pos.y > mcl_vars.mg_nether_min) or (pos.y < mcl_vars.mg_end_max and pos.y > mcl_vars.mg_end_min)) local void_deadly = false @@ -15,11 +15,11 @@ function mcl_worlds.is_in_void(pos) -- Overworld → Void → End → Void → Nether → Void if pos.y < mcl_vars.mg_overworld_min and pos.y > mcl_vars.mg_end_max then void_deadly = pos.y < mcl_vars.mg_overworld_min - deadly_tolerance - elseif pos.y < mcl_vars.mg_end_min and pos.y > mcl_vars.mg_nether_max then + elseif pos.y < mcl_vars.mg_end_min and pos.y > mcl_vars.mg_nether_max+128 then -- The void between End and Nether. Like usual, but here, the void -- *above* the Nether also has a small tolerance area, so player -- can fly above the Nether without getting hurt instantly. - void_deadly = (pos.y < mcl_vars.mg_end_min - deadly_tolerance) and (pos.y > mcl_vars.mg_nether_max + deadly_tolerance) + void_deadly = (pos.y < mcl_vars.mg_end_min - deadly_tolerance) and (pos.y > mcl_vars.mg_nether_max+128 + deadly_tolerance) elseif pos.y < mcl_vars.mg_nether_min then void_deadly = pos.y < mcl_vars.mg_nether_min - deadly_tolerance end @@ -35,7 +35,7 @@ end function mcl_worlds.y_to_layer(y) if y >= mcl_vars.mg_overworld_min then return y - mcl_vars.mg_overworld_min, "overworld" - elseif y >= mcl_vars.mg_nether_min and y <= mcl_vars.mg_nether_max then + elseif y >= mcl_vars.mg_nether_min and y <= mcl_vars.mg_nether_max+128 then return y - mcl_vars.mg_nether_min, "nether" elseif y >= mcl_vars.mg_end_min and y <= mcl_vars.mg_end_max then return y - mcl_vars.mg_end_min, "end" @@ -73,7 +73,7 @@ end -- Takes a position and returns true if this position can have Nether dust function mcl_worlds.has_dust(pos) -- Weather in the Overworld and the high part of the void below - return pos.y <= mcl_vars.mg_nether_max + 64 and pos.y >= mcl_vars.mg_nether_min - 64 + return pos.y <= mcl_vars.mg_nether_max + 138 and pos.y >= mcl_vars.mg_nether_min - 10 end -- Takes a position (pos) and returns true if compasses are working here diff --git a/mods/ENTITIES/mcl_burning/api.lua b/mods/ENTITIES/mcl_burning/api.lua index 723b29a8b..4eac333a2 100644 --- a/mods/ENTITIES/mcl_burning/api.lua +++ b/mods/ENTITIES/mcl_burning/api.lua @@ -117,6 +117,10 @@ function mcl_burning.damage(obj) end function mcl_burning.set_on_fire(obj, burn_time, reason) + if obj:get_hp() < 0 then + return + end + local luaentity = obj:get_luaentity() if luaentity and luaentity.fire_resistant then return @@ -145,7 +149,7 @@ function mcl_burning.set_on_fire(obj, burn_time, reason) end if old_burn_time <= burn_time then - local sound_id = mcl_burning.get(obj, "int", "sound_id") + --[[local sound_id = mcl_burning.get(obj, "int", "sound_id") if sound_id == 0 then sound_id = minetest.sound_play("fire_fire", { object = obj, @@ -153,7 +157,7 @@ function mcl_burning.set_on_fire(obj, burn_time, reason) max_hear_distance = 16, loop = true, }) + 1 - end + end]]-- local hud_id if obj:is_player() then @@ -163,7 +167,7 @@ function mcl_burning.set_on_fire(obj, burn_time, reason) hud_elem_type = "image", position = {x = 0.5, y = 0.5}, scale = {x = -100, y = -100}, - text = "fire_basic_flame.png", + text = "mcl_burning_hud_flame_animated.png", z_index = 1000, }) + 1 end @@ -171,7 +175,7 @@ function mcl_burning.set_on_fire(obj, burn_time, reason) mcl_burning.set(obj, "float", "burn_time", burn_time) mcl_burning.set(obj, "string", "reason", reason) mcl_burning.set(obj, "int", "hud_id", hud_id) - mcl_burning.set(obj, "int", "sound_id", sound_id) + --mcl_burning.set(obj, "int", "sound_id", sound_id) local fire_entity = minetest.add_entity(obj:get_pos(), "mcl_burning:fire") local minp, maxp = mcl_burning.get_collisionbox(obj) @@ -194,8 +198,8 @@ end function mcl_burning.extinguish(obj) if mcl_burning.is_burning(obj) then - local sound_id = mcl_burning.get(obj, "int", "sound_id") - 1 - minetest.sound_stop(sound_id) + --local sound_id = mcl_burning.get(obj, "int", "sound_id") - 1 + --minetest.sound_stop(sound_id) if obj:is_player() then local hud_id = mcl_burning.get(obj, "int", "hud_id") - 1 @@ -206,7 +210,7 @@ function mcl_burning.extinguish(obj) mcl_burning.set(obj, "float", "burn_time") mcl_burning.set(obj, "float", "damage_timer") mcl_burning.set(obj, "int", "hud_id") - mcl_burning.set(obj, "int", "sound_id") + --mcl_burning.set(obj, "int", "sound_id") end end diff --git a/mods/ENTITIES/mcl_item_entity/init.lua b/mods/ENTITIES/mcl_item_entity/init.lua index 7546bd01c..d1d337a9c 100644 --- a/mods/ENTITIES/mcl_item_entity/init.lua +++ b/mods/ENTITIES/mcl_item_entity/init.lua @@ -165,66 +165,6 @@ minetest.register_globalstep(function(dtime) end end) -local minigroups = { "shearsy", "swordy", "shearsy_wool", "swordy_cobweb" } -local basegroups = { "pickaxey", "axey", "shovely" } -local materials = { "wood", "gold", "stone", "iron", "diamond" } - --- Checks if the given node would drop its useful drop if dug by a tool --- with the given tool capabilities. Returns true if it will yield its useful --- drop, false otherwise. -local check_can_drop = function(node_name, tool_capabilities) - local handy = minetest.get_item_group(node_name, "handy") - local dig_immediate = minetest.get_item_group(node_name, "dig_immediate") - if handy == 1 or dig_immediate == 2 or dig_immediate == 3 then - return true - else - local toolgroupcaps - if tool_capabilities then - toolgroupcaps = tool_capabilities.groupcaps - else - return false - end - - -- Compare node groups with tool capabilities - for m=1, #minigroups do - local minigroup = minigroups[m] - local g = minetest.get_item_group(node_name, minigroup) - if g ~= 0 then - local plus = minigroup .. "_dig" - if toolgroupcaps[plus] then - return true - end - for e=1,5 do - local effplus = plus .. "_efficiency_" .. e - if toolgroupcaps[effplus] then - return true - end - end - end - end - for b=1, #basegroups do - local basegroup = basegroups[b] - local g = minetest.get_item_group(node_name, basegroup) - if g ~= 0 then - for m=g, #materials do - local plus = basegroup .. "_dig_"..materials[m] - if toolgroupcaps[plus] then - return true - end - for e=1,5 do - local effplus = plus .. "_efficiency_" .. e - if toolgroupcaps[effplus] then - return true - end - end - end - end - end - - return false - end -end - -- Stupid workaround to get drops from a drop table: -- Create a temporary table in minetest.registered_nodes that contains the proper drops, -- because unfortunately minetest.get_node_drops needs the drop table to be inside a registered node definition @@ -281,17 +221,20 @@ function minetest.handle_node_drops(pos, drops, digger) -- Check if node will yield its useful drop by the digger's tool local dug_node = minetest.get_node(pos) - local toolcaps + local tooldef local tool if digger ~= nil then tool = digger:get_wielded_item() - toolcaps = tool:get_tool_capabilities() + tooldef = minetest.registered_tools[tool:get_name()] - if not check_can_drop(dug_node.name, toolcaps) then + if not mcl_autogroup.can_harvest(dug_node.name, tool:get_name()) then return end end + local diggroups = tooldef and tooldef._mcl_diggroups + local shearsy_level = diggroups and diggroups.shearsy and diggroups.shearsy.level + --[[ Special node drops when dug by shears by reading _mcl_shears_drop or with a silk touch tool reading _mcl_silk_touch_drop from the node definition. Definition of _mcl_shears_drop / _mcl_silk_touch_drop: @@ -303,7 +246,7 @@ function minetest.handle_node_drops(pos, drops, digger) local silk_touch_drop = false local nodedef = minetest.registered_nodes[dug_node.name] - if toolcaps ~= nil and toolcaps.groupcaps and toolcaps.groupcaps.shearsy_dig and nodedef._mcl_shears_drop then + if shearsy_level and shearsy_level > 0 and nodedef._mcl_shears_drop then if nodedef._mcl_shears_drop == true then drops = { dug_node.name } else diff --git a/mods/ENTITIES/mcl_mobs/api.lua b/mods/ENTITIES/mcl_mobs/api.lua index 3b929a119..f8881d741 100644 --- a/mods/ENTITIES/mcl_mobs/api.lua +++ b/mods/ENTITIES/mcl_mobs/api.lua @@ -2826,7 +2826,7 @@ local falling = function(self, pos) end if mcl_portals ~= nil then - if mcl_portals.nether_portal_cooloff[self.object] then + if mcl_portals.nether_portal_cooloff(self.object) then return false -- mob has teleported through Nether portal - it's 99% not falling end end @@ -2856,6 +2856,18 @@ local falling = function(self, pos) self.object:set_acceleration({x = 0, y = 0, z = 0}) end + if minetest.registered_nodes[node_ok(pos).name].groups.lava then + + if self.floats_on_lava == 1 then + + self.object:set_acceleration({ + x = 0, + y = -self.fall_speed / (max(1, v.y) ^ 2), + z = 0 + }) + end + end + -- in water then float up if minetest.registered_nodes[node_ok(pos).name].groups.water then @@ -3773,6 +3785,7 @@ minetest.register_entity(name, { knock_back = def.knock_back ~= false, shoot_offset = def.shoot_offset or 0, floats = def.floats or 1, -- floats in water by default + floats_on_lava = def.floats_on_lava or 0, replace_rate = def.replace_rate, replace_what = def.replace_what, replace_with = def.replace_with, diff --git a/mods/ENTITIES/mobs_mc/horse.lua b/mods/ENTITIES/mobs_mc/horse.lua index a59ed80d4..4e588855f 100644 --- a/mods/ENTITIES/mobs_mc/horse.lua +++ b/mods/ENTITIES/mobs_mc/horse.lua @@ -450,7 +450,7 @@ mobs:spawn_specific("mobs_mc:donkey", mobs_mc.spawn.grassland_savanna, {"air"}, -- spawn eggs mobs:register_egg("mobs_mc:horse", S("Horse"), "mobs_mc_spawn_icon_horse.png", 0) ---mobs:register_egg("mobs_mc:skeleton_horse", S("Skeleton Horse"), "mobs_mc_spawn_icon_horse_skeleton.png", 0) +mobs:register_egg("mobs_mc:skeleton_horse", S("Skeleton Horse"), "mobs_mc_spawn_icon_horse_skeleton.png", 0) --mobs:register_egg("mobs_mc:zombie_horse", S("Zombie Horse"), "mobs_mc_spawn_icon_horse_zombie.png", 0) mobs:register_egg("mobs_mc:donkey", S("Donkey"), "mobs_mc_spawn_icon_donkey.png", 0) mobs:register_egg("mobs_mc:mule", S("Mule"), "mobs_mc_spawn_icon_mule.png", 0) diff --git a/mods/ENTITIES/mobs_mc/textures/mobs_mc_horse_skeleton.png b/mods/ENTITIES/mobs_mc/textures/mobs_mc_horse_skeleton.png new file mode 100644 index 000000000..615eb67a8 Binary files /dev/null and b/mods/ENTITIES/mobs_mc/textures/mobs_mc_horse_skeleton.png differ diff --git a/mods/ENTITIES/mobs_mc/villager.lua b/mods/ENTITIES/mobs_mc/villager.lua index 0021a1adb..a38c78719 100644 --- a/mods/ENTITIES/mobs_mc/villager.lua +++ b/mods/ENTITIES/mobs_mc/villager.lua @@ -960,7 +960,7 @@ mobs:register_mob("mobs_mc:villager", { "mobs_mc_villager_smith.png", --hat }, }, - visual_size = {x=3, y=3}, + visual_size = {x=2.75, y=2.75}, makes_footstep_sound = true, walk_velocity = 1.2, run_velocity = 2.4, diff --git a/mods/ENTITIES/mobs_mc/villager_evoker.lua b/mods/ENTITIES/mobs_mc/villager_evoker.lua index 226c82a32..abe0e9ca2 100644 --- a/mods/ENTITIES/mobs_mc/villager_evoker.lua +++ b/mods/ENTITIES/mobs_mc/villager_evoker.lua @@ -28,7 +28,7 @@ mobs:register_mob("mobs_mc:evoker", { "blank.png", --no hat -- TODO: Attack glow } }, - visual_size = {x=3, y=3}, + visual_size = {x=2.75, y=2.75}, makes_footstep_sound = true, damage = 6, walk_velocity = 0.2, diff --git a/mods/ENTITIES/mobs_mc/villager_illusioner.lua b/mods/ENTITIES/mobs_mc/villager_illusioner.lua index 30e9f6f36..0bbe2a5f6 100644 --- a/mods/ENTITIES/mobs_mc/villager_illusioner.lua +++ b/mods/ENTITIES/mobs_mc/villager_illusioner.lua @@ -36,7 +36,7 @@ mobs:register_mob("mobs_mc:illusioner", { -- TODO: more sounds distance = 16, }, - visual_size = {x=3, y=3}, + visual_size = {x=2.75, y=2.75}, walk_velocity = 0.6, run_velocity = 2, jump = true, diff --git a/mods/ENTITIES/mobs_mc/villager_vindicator.lua b/mods/ENTITIES/mobs_mc/villager_vindicator.lua index 3e611acdd..56b295066 100644 --- a/mods/ENTITIES/mobs_mc/villager_vindicator.lua +++ b/mods/ENTITIES/mobs_mc/villager_vindicator.lua @@ -30,7 +30,7 @@ mobs:register_mob("mobs_mc:vindicator", { -- TODO: Glow when attacking (mobs_mc_vindicator.png) }, }, - visual_size = {x=3, y=3}, + visual_size = {x=2.75, y=2.75}, makes_footstep_sound = true, damage = 13, reach = 2, diff --git a/mods/ENTITIES/mobs_mc/villager_zombie.lua b/mods/ENTITIES/mobs_mc/villager_zombie.lua index d7f2203e1..09539fa76 100644 --- a/mods/ENTITIES/mobs_mc/villager_zombie.lua +++ b/mods/ENTITIES/mobs_mc/villager_zombie.lua @@ -45,7 +45,7 @@ mobs:register_mob("mobs_mc:villager_zombie", { {"mobs_mc_zombie_smith.png"}, {"mobs_mc_zombie_villager.png"} }, - visual_size = {x=3, y=3}, + visual_size = {x=2.75, y=2.75}, makes_footstep_sound = true, damage = 3, reach = 2, diff --git a/mods/ENTITIES/mobs_mc/witch.lua b/mods/ENTITIES/mobs_mc/witch.lua index 05f5098e5..383cbd36f 100644 --- a/mods/ENTITIES/mobs_mc/witch.lua +++ b/mods/ENTITIES/mobs_mc/witch.lua @@ -25,7 +25,7 @@ mobs:register_mob("mobs_mc:witch", { textures = { {"mobs_mc_witch.png"}, }, - visual_size = {x=3, y=3}, + visual_size = {x=2.75, y=2.75}, makes_footstep_sound = true, damage = 2, reach = 2, diff --git a/mods/ENVIRONMENT/mcl_weather/weather_core.lua b/mods/ENVIRONMENT/mcl_weather/weather_core.lua index 365f6e549..d3772dc7e 100644 --- a/mods/ENVIRONMENT/mcl_weather/weather_core.lua +++ b/mods/ENVIRONMENT/mcl_weather/weather_core.lua @@ -38,6 +38,7 @@ mcl_weather.reg_weathers["none"] = { local storage = minetest.get_mod_storage() -- Save weather into mod storage, so it can be loaded after restarting the server local save_weather = function() + if not mcl_weather.end_time then return end storage:set_string("mcl_weather_state", mcl_weather.state) storage:set_int("mcl_weather_end_time", mcl_weather.end_time) minetest.log("verbose", "[mcl_weather] Weather data saved: state="..mcl_weather.state.." end_time="..mcl_weather.end_time) diff --git a/mods/ITEMS/REDSTONE/mcl_comparators/depends.txt b/mods/ITEMS/REDSTONE/mcl_comparators/depends.txt deleted file mode 100644 index 2cc05ce78..000000000 --- a/mods/ITEMS/REDSTONE/mcl_comparators/depends.txt +++ /dev/null @@ -1,4 +0,0 @@ -mesecons -mcl_sounds -doc? -screwdriver? diff --git a/mods/ITEMS/REDSTONE/mcl_comparators/mod.conf b/mods/ITEMS/REDSTONE/mcl_comparators/mod.conf index 28d8926a0..100e42814 100644 --- a/mods/ITEMS/REDSTONE/mcl_comparators/mod.conf +++ b/mods/ITEMS/REDSTONE/mcl_comparators/mod.conf @@ -1,2 +1,3 @@ name = mcl_comparators -depends = mcl_wip +depends = mcl_wip, mesecons, mcl_sounds +optional_depends = doc, screwdriver diff --git a/mods/ITEMS/REDSTONE/mcl_dispensers/depends.txt b/mods/ITEMS/REDSTONE/mcl_dispensers/depends.txt deleted file mode 100644 index 7b51f67cc..000000000 --- a/mods/ITEMS/REDSTONE/mcl_dispensers/depends.txt +++ /dev/null @@ -1,12 +0,0 @@ -mcl_init -mcl_formspec -mesecons -mcl_sounds -mcl_tnt -mcl_worlds -mcl_core -mcl_nether -mcl_armor_stand -mcl_armor -doc? -screwdriver? diff --git a/mods/ITEMS/REDSTONE/mcl_dispensers/mod.conf b/mods/ITEMS/REDSTONE/mcl_dispensers/mod.conf new file mode 100644 index 000000000..13cdb5f5a --- /dev/null +++ b/mods/ITEMS/REDSTONE/mcl_dispensers/mod.conf @@ -0,0 +1,3 @@ +name = mcl_dispensers +depends = mcl_init, mcl_formspec, mesecons, mcl_sounds, mcl_tnt, mcl_worlds, mcl_core, mcl_nether, mcl_armor_stand, mcl_armor +optional_depends = doc, screwdriver diff --git a/mods/ITEMS/REDSTONE/mcl_droppers/depends.txt b/mods/ITEMS/REDSTONE/mcl_droppers/depends.txt deleted file mode 100644 index cfd9772fe..000000000 --- a/mods/ITEMS/REDSTONE/mcl_droppers/depends.txt +++ /dev/null @@ -1,6 +0,0 @@ -mcl_init -mcl_formspec -mesecons -mcl_util -doc? -screwdriver? diff --git a/mods/ITEMS/REDSTONE/mcl_droppers/mod.conf b/mods/ITEMS/REDSTONE/mcl_droppers/mod.conf new file mode 100644 index 000000000..bbb1c19f2 --- /dev/null +++ b/mods/ITEMS/REDSTONE/mcl_droppers/mod.conf @@ -0,0 +1,3 @@ +name = mcl_droppers +depends = mcl_init, mcl_formspec, mesecons, mcl_util +optional_depends = doc, screwdriver diff --git a/mods/ITEMS/REDSTONE/mcl_observers/depends.txt b/mods/ITEMS/REDSTONE/mcl_observers/depends.txt deleted file mode 100644 index 95222145e..000000000 --- a/mods/ITEMS/REDSTONE/mcl_observers/depends.txt +++ /dev/null @@ -1,2 +0,0 @@ -mesecons -mcl_util diff --git a/mods/ITEMS/REDSTONE/mcl_observers/mod.conf b/mods/ITEMS/REDSTONE/mcl_observers/mod.conf new file mode 100644 index 000000000..fce00191a --- /dev/null +++ b/mods/ITEMS/REDSTONE/mcl_observers/mod.conf @@ -0,0 +1,2 @@ +name = mcl_observers +depends = mesecons, mcl_util diff --git a/mods/ITEMS/REDSTONE/mesecons/depends.txt b/mods/ITEMS/REDSTONE/mesecons/depends.txt deleted file mode 100644 index 812afabce..000000000 --- a/mods/ITEMS/REDSTONE/mesecons/depends.txt +++ /dev/null @@ -1,3 +0,0 @@ -mcl_sounds -mcl_core -doc? diff --git a/mods/ITEMS/REDSTONE/mesecons/mod.conf b/mods/ITEMS/REDSTONE/mesecons/mod.conf new file mode 100644 index 000000000..94be76509 --- /dev/null +++ b/mods/ITEMS/REDSTONE/mesecons/mod.conf @@ -0,0 +1,3 @@ +name = mesecons +depends = mcl_sounds, mcl_core +optional_depends = doc diff --git a/mods/ITEMS/REDSTONE/mesecons_alias/depends.txt b/mods/ITEMS/REDSTONE/mesecons_alias/depends.txt deleted file mode 100644 index acaa92412..000000000 --- a/mods/ITEMS/REDSTONE/mesecons_alias/depends.txt +++ /dev/null @@ -1 +0,0 @@ -mesecons diff --git a/mods/ITEMS/REDSTONE/mesecons_alias/mod.conf b/mods/ITEMS/REDSTONE/mesecons_alias/mod.conf new file mode 100644 index 000000000..533d54c80 --- /dev/null +++ b/mods/ITEMS/REDSTONE/mesecons_alias/mod.conf @@ -0,0 +1,2 @@ +name = mesecons_alias +depends = mesecons diff --git a/mods/ITEMS/REDSTONE/mesecons_button/depends.txt b/mods/ITEMS/REDSTONE/mesecons_button/depends.txt deleted file mode 100644 index 4fdbda79f..000000000 --- a/mods/ITEMS/REDSTONE/mesecons_button/depends.txt +++ /dev/null @@ -1,2 +0,0 @@ -mesecons -doc? diff --git a/mods/ITEMS/REDSTONE/mesecons_button/mod.conf b/mods/ITEMS/REDSTONE/mesecons_button/mod.conf new file mode 100644 index 000000000..be127362b --- /dev/null +++ b/mods/ITEMS/REDSTONE/mesecons_button/mod.conf @@ -0,0 +1,3 @@ +name = mesecons_button +depends = mesecons +optional_depends = doc diff --git a/mods/ITEMS/REDSTONE/mesecons_commandblock/depends.txt b/mods/ITEMS/REDSTONE/mesecons_commandblock/depends.txt deleted file mode 100644 index 95ac10fe5..000000000 --- a/mods/ITEMS/REDSTONE/mesecons_commandblock/depends.txt +++ /dev/null @@ -1,3 +0,0 @@ -mesecons -doc? -doc_items? diff --git a/mods/ITEMS/REDSTONE/mesecons_commandblock/mod.conf b/mods/ITEMS/REDSTONE/mesecons_commandblock/mod.conf new file mode 100644 index 000000000..4a743406c --- /dev/null +++ b/mods/ITEMS/REDSTONE/mesecons_commandblock/mod.conf @@ -0,0 +1,3 @@ +name = mesecons_commandblock +depends = mesecons +optional_depends = doc, doc_items diff --git a/mods/ITEMS/REDSTONE/mesecons_delayer/depends.txt b/mods/ITEMS/REDSTONE/mesecons_delayer/depends.txt deleted file mode 100644 index 14ced9309..000000000 --- a/mods/ITEMS/REDSTONE/mesecons_delayer/depends.txt +++ /dev/null @@ -1,3 +0,0 @@ -mesecons -doc? -screwdriver? diff --git a/mods/ITEMS/REDSTONE/mesecons_delayer/mod.conf b/mods/ITEMS/REDSTONE/mesecons_delayer/mod.conf new file mode 100644 index 000000000..3f8446239 --- /dev/null +++ b/mods/ITEMS/REDSTONE/mesecons_delayer/mod.conf @@ -0,0 +1,3 @@ +name = mesecons_delayer +depends = mesecons +optional_depends = doc, screwdriver diff --git a/mods/ITEMS/REDSTONE/mesecons_lightstone/depends.txt b/mods/ITEMS/REDSTONE/mesecons_lightstone/depends.txt deleted file mode 100644 index 4fdbda79f..000000000 --- a/mods/ITEMS/REDSTONE/mesecons_lightstone/depends.txt +++ /dev/null @@ -1,2 +0,0 @@ -mesecons -doc? diff --git a/mods/ITEMS/REDSTONE/mesecons_lightstone/mod.conf b/mods/ITEMS/REDSTONE/mesecons_lightstone/mod.conf new file mode 100644 index 000000000..95811bd27 --- /dev/null +++ b/mods/ITEMS/REDSTONE/mesecons_lightstone/mod.conf @@ -0,0 +1,3 @@ +name = mesecons_lightstone +depends = mesecons +optional_depends = doc diff --git a/mods/ITEMS/REDSTONE/mesecons_mvps/depends.txt b/mods/ITEMS/REDSTONE/mesecons_mvps/depends.txt deleted file mode 100644 index acaa92412..000000000 --- a/mods/ITEMS/REDSTONE/mesecons_mvps/depends.txt +++ /dev/null @@ -1 +0,0 @@ -mesecons diff --git a/mods/ITEMS/REDSTONE/mesecons_mvps/mod.conf b/mods/ITEMS/REDSTONE/mesecons_mvps/mod.conf new file mode 100644 index 000000000..3e347879f --- /dev/null +++ b/mods/ITEMS/REDSTONE/mesecons_mvps/mod.conf @@ -0,0 +1,2 @@ +name = mesecons_mvps +depends = mesecons diff --git a/mods/ITEMS/REDSTONE/mesecons_noteblock/depends.txt b/mods/ITEMS/REDSTONE/mesecons_noteblock/depends.txt deleted file mode 100644 index 77b6f4da3..000000000 --- a/mods/ITEMS/REDSTONE/mesecons_noteblock/depends.txt +++ /dev/null @@ -1,2 +0,0 @@ -mesecons -mcl_particles diff --git a/mods/ITEMS/REDSTONE/mesecons_noteblock/mod.conf b/mods/ITEMS/REDSTONE/mesecons_noteblock/mod.conf new file mode 100644 index 000000000..c388e7a26 --- /dev/null +++ b/mods/ITEMS/REDSTONE/mesecons_noteblock/mod.conf @@ -0,0 +1,2 @@ +name = mesecons_noteblock +depends = mesecons, mcl_particles diff --git a/mods/ITEMS/REDSTONE/mesecons_pistons/depends.txt b/mods/ITEMS/REDSTONE/mesecons_pistons/depends.txt deleted file mode 100644 index c19acf4b9..000000000 --- a/mods/ITEMS/REDSTONE/mesecons_pistons/depends.txt +++ /dev/null @@ -1,5 +0,0 @@ -mesecons -mesecons_mvps -mcl_mobitems -doc? -screwdriver? diff --git a/mods/ITEMS/REDSTONE/mesecons_pistons/mod.conf b/mods/ITEMS/REDSTONE/mesecons_pistons/mod.conf new file mode 100644 index 000000000..5a3f6c80f --- /dev/null +++ b/mods/ITEMS/REDSTONE/mesecons_pistons/mod.conf @@ -0,0 +1,3 @@ +name = mesecons_pistons +depends = mesecons, mesecons_mvps, mcl_mobitems +optional_depends = doc, screwdriver diff --git a/mods/ITEMS/REDSTONE/mesecons_pressureplates/depends.txt b/mods/ITEMS/REDSTONE/mesecons_pressureplates/depends.txt deleted file mode 100644 index 4fdbda79f..000000000 --- a/mods/ITEMS/REDSTONE/mesecons_pressureplates/depends.txt +++ /dev/null @@ -1,2 +0,0 @@ -mesecons -doc? diff --git a/mods/ITEMS/REDSTONE/mesecons_pressureplates/mod.conf b/mods/ITEMS/REDSTONE/mesecons_pressureplates/mod.conf new file mode 100644 index 000000000..0edd40e9a --- /dev/null +++ b/mods/ITEMS/REDSTONE/mesecons_pressureplates/mod.conf @@ -0,0 +1,3 @@ +name = mesecons_pressureplates +depends = mesecons +optional_depends = doc diff --git a/mods/ITEMS/REDSTONE/mesecons_solarpanel/depends.txt b/mods/ITEMS/REDSTONE/mesecons_solarpanel/depends.txt deleted file mode 100644 index 4fdbda79f..000000000 --- a/mods/ITEMS/REDSTONE/mesecons_solarpanel/depends.txt +++ /dev/null @@ -1,2 +0,0 @@ -mesecons -doc? diff --git a/mods/ITEMS/REDSTONE/mesecons_solarpanel/mod.conf b/mods/ITEMS/REDSTONE/mesecons_solarpanel/mod.conf new file mode 100644 index 000000000..9897b7488 --- /dev/null +++ b/mods/ITEMS/REDSTONE/mesecons_solarpanel/mod.conf @@ -0,0 +1,3 @@ +name = mesecons_solarpanel +depends = mesecons +optional_depends = doc diff --git a/mods/ITEMS/REDSTONE/mesecons_torch/depends.txt b/mods/ITEMS/REDSTONE/mesecons_torch/depends.txt deleted file mode 100644 index 9636f7bd5..000000000 --- a/mods/ITEMS/REDSTONE/mesecons_torch/depends.txt +++ /dev/null @@ -1,3 +0,0 @@ -mesecons -mcl_torches -doc? diff --git a/mods/ITEMS/REDSTONE/mesecons_torch/mod.conf b/mods/ITEMS/REDSTONE/mesecons_torch/mod.conf new file mode 100644 index 000000000..85586cad7 --- /dev/null +++ b/mods/ITEMS/REDSTONE/mesecons_torch/mod.conf @@ -0,0 +1,3 @@ +name = mesecons_torch +depends = mesecons, mcl_torches +optional_depends = doc diff --git a/mods/ITEMS/REDSTONE/mesecons_walllever/depends.txt b/mods/ITEMS/REDSTONE/mesecons_walllever/depends.txt deleted file mode 100644 index 4fdbda79f..000000000 --- a/mods/ITEMS/REDSTONE/mesecons_walllever/depends.txt +++ /dev/null @@ -1,2 +0,0 @@ -mesecons -doc? diff --git a/mods/ITEMS/REDSTONE/mesecons_walllever/mod.conf b/mods/ITEMS/REDSTONE/mesecons_walllever/mod.conf new file mode 100644 index 000000000..8512e9d6b --- /dev/null +++ b/mods/ITEMS/REDSTONE/mesecons_walllever/mod.conf @@ -0,0 +1,3 @@ +name = mesecons_walllever +depends = mesecons +optional_depends = doc diff --git a/mods/ITEMS/REDSTONE/mesecons_wires/depends.txt b/mods/ITEMS/REDSTONE/mesecons_wires/depends.txt deleted file mode 100644 index 4fdbda79f..000000000 --- a/mods/ITEMS/REDSTONE/mesecons_wires/depends.txt +++ /dev/null @@ -1,2 +0,0 @@ -mesecons -doc? diff --git a/mods/ITEMS/REDSTONE/mesecons_wires/mod.conf b/mods/ITEMS/REDSTONE/mesecons_wires/mod.conf new file mode 100644 index 000000000..15f2e0d32 --- /dev/null +++ b/mods/ITEMS/REDSTONE/mesecons_wires/mod.conf @@ -0,0 +1,3 @@ +name = mesecons_wires +depends = mesecons +optional_depends = doc diff --git a/mods/ITEMS/mcl_armor/armor.lua b/mods/ITEMS/mcl_armor/armor.lua index 943f57e9d..3537b2e31 100644 --- a/mods/ITEMS/mcl_armor/armor.lua +++ b/mods/ITEMS/mcl_armor/armor.lua @@ -151,8 +151,8 @@ armor.set_player_armor = function(self, player) if level then local texture = def.texture or item:gsub("%:", "_") local enchanted_addition = (mcl_enchanting.is_enchanted(item) and mcl_enchanting.overlay or "") - table.insert(textures, texture..".png"..enchanted_addition) - preview = "player.png^[opacity:0^"..texture.."_preview.png"..enchanted_addition..""..(preview and "^"..preview or "") + table.insert(textures, "("..texture..".png"..enchanted_addition..")") + preview = "(player.png^[opacity:0^"..texture.."_preview.png"..enchanted_addition..")"..(preview and "^"..preview or "") armor_level = armor_level + level items = items + 1 mcl_armor_points = mcl_armor_points + (def.groups["mcl_armor_points"] or 0) diff --git a/mods/ITEMS/mcl_bows/arrow.lua b/mods/ITEMS/mcl_bows/arrow.lua index 61cb26f33..cddae0869 100644 --- a/mods/ITEMS/mcl_bows/arrow.lua +++ b/mods/ITEMS/mcl_bows/arrow.lua @@ -16,23 +16,17 @@ local dir_to_pitch = function(dir) end local random_arrow_positions = function(positions, placement) - local min = 0 - local max = 0 if positions == 'x' then - min = -4 - max = 4 + return math.random(-4, 4) elseif positions == 'y' then - min = 0 - max = 10 + return math.random(0, 10) end if placement == 'front' and positions == 'z' then - min = 3 - max = 3 + return 3 elseif placement == 'back' and positions == 'z' then - min = -3 - max = -3 + return -3 end - return math.random(max, min) + return 0 end local mod_awards = minetest.get_modpath("awards") and minetest.get_modpath("mcl_achievements") @@ -304,8 +298,8 @@ ARROW_ENTITY.on_step = function(self, dtime) else self._attach_parent = 'Body' end - self._z_rotation = math.random(30, -30) - self._y_rotation = math.random(30, -30) + self._z_rotation = math.random(-30, 30) + self._y_rotation = math.random( -30, 30) self.object:set_attach(obj, self._attach_parent, {x=self._x_position,y=self._y_position,z=random_arrow_positions('z', placement)}, {x=0,y=self._rotation_station + self._y_rotation,z=self._z_rotation}) minetest.after(150, function() self.object:remove() @@ -337,8 +331,8 @@ ARROW_ENTITY.on_step = function(self, dtime) minetest.sound_play({name="mcl_bows_hit_other", gain=0.3}, {pos=self.object:get_pos(), max_hear_distance=16}, true) end end - mcl_burning.extinguish(self.object) if not obj:is_player() then + mcl_burning.extinguish(self.object) self.object:remove() end return diff --git a/mods/ITEMS/mcl_cauldrons/depends.txt b/mods/ITEMS/mcl_cauldrons/depends.txt deleted file mode 100644 index 2c344c60c..000000000 --- a/mods/ITEMS/mcl_cauldrons/depends.txt +++ /dev/null @@ -1,4 +0,0 @@ -mcl_core -mclx_core? -mcl_sounds -doc? diff --git a/mods/ITEMS/mcl_cauldrons/mod.conf b/mods/ITEMS/mcl_cauldrons/mod.conf index 1bedf9d73..4787d60f9 100644 --- a/mods/ITEMS/mcl_cauldrons/mod.conf +++ b/mods/ITEMS/mcl_cauldrons/mod.conf @@ -1 +1,3 @@ name = mcl_cauldrons +depends = mcl_core, mcl_sounds +optional_depends = mclx_core, doc diff --git a/mods/ITEMS/mcl_chests/depends.txt b/mods/ITEMS/mcl_chests/depends.txt deleted file mode 100644 index af11d5f6c..000000000 --- a/mods/ITEMS/mcl_chests/depends.txt +++ /dev/null @@ -1,8 +0,0 @@ -mcl_init -mcl_formspec -mcl_core -mcl_sounds -mcl_end -mesecons -doc? -screwdriver? diff --git a/mods/ITEMS/mcl_chests/mod.conf b/mods/ITEMS/mcl_chests/mod.conf new file mode 100644 index 000000000..0ff5129ca --- /dev/null +++ b/mods/ITEMS/mcl_chests/mod.conf @@ -0,0 +1,3 @@ +name = mcl_chests +depends = mcl_init, mcl_formspec, mcl_core, mcl_sounds, mcl_end, mesecons +optional_depends = doc, screwdriver diff --git a/mods/ITEMS/mcl_clock/depends.txt b/mods/ITEMS/mcl_clock/depends.txt deleted file mode 100644 index 514d78143..000000000 --- a/mods/ITEMS/mcl_clock/depends.txt +++ /dev/null @@ -1,4 +0,0 @@ -mcl_init -mcl_worlds -mesecons -doc? diff --git a/mods/ITEMS/mcl_clock/description.txt b/mods/ITEMS/mcl_clock/description.txt deleted file mode 100644 index 1b7157aad..000000000 --- a/mods/ITEMS/mcl_clock/description.txt +++ /dev/null @@ -1 +0,0 @@ -A fantasy clock item roughly shows the time of day. diff --git a/mods/ITEMS/mcl_clock/mod.conf b/mods/ITEMS/mcl_clock/mod.conf index ba0d83eaa..e358ff29a 100644 --- a/mods/ITEMS/mcl_clock/mod.conf +++ b/mods/ITEMS/mcl_clock/mod.conf @@ -1 +1,4 @@ name = mcl_clock +description = A fantasy clock item roughly shows the time of day. +depends = mcl_init, mcl_worlds, mesecons +optional_depends = doc diff --git a/mods/ITEMS/mcl_cocoas/init.lua b/mods/ITEMS/mcl_cocoas/init.lua index d0d96b300..f19f85154 100644 --- a/mods/ITEMS/mcl_cocoas/init.lua +++ b/mods/ITEMS/mcl_cocoas/init.lua @@ -19,7 +19,7 @@ function mcl_cocoas.place(itemstack, placer, pt, plantname) -- Am I right-clicking on something that has a custom on_rightclick set? if placer and not placer:get_player_control().sneak then if minetest.registered_nodes[under.name] and minetest.registered_nodes[under.name].on_rightclick then - return minetest.registered_nodes[under.name].on_rightclick(pointed_thing.under, under, placer, itemstack) or itemstack + return minetest.registered_nodes[under.name].on_rightclick(pt.under, under, placer, itemstack) or itemstack end end diff --git a/mods/ITEMS/mcl_colorblocks/depends.txt b/mods/ITEMS/mcl_colorblocks/depends.txt deleted file mode 100644 index c9db3b289..000000000 --- a/mods/ITEMS/mcl_colorblocks/depends.txt +++ /dev/null @@ -1,5 +0,0 @@ -mcl_core -mcl_sounds -mcl_dye -doc? -screwdriver? diff --git a/mods/ITEMS/mcl_colorblocks/description.txt b/mods/ITEMS/mcl_colorblocks/description.txt deleted file mode 100644 index ff77b29a6..000000000 --- a/mods/ITEMS/mcl_colorblocks/description.txt +++ /dev/null @@ -1 +0,0 @@ -Adds blocks which can be colored, namely hardened clay. diff --git a/mods/ITEMS/mcl_colorblocks/mod.conf b/mods/ITEMS/mcl_colorblocks/mod.conf index 2d6ffb1c2..dab0ce589 100644 --- a/mods/ITEMS/mcl_colorblocks/mod.conf +++ b/mods/ITEMS/mcl_colorblocks/mod.conf @@ -1 +1,4 @@ name = mcl_colorblocks +description = Adds blocks which can be colored, namely hardened clay. +depends = mcl_core, mcl_sounds, mcl_dye +optional_depends = doc, screwdriver diff --git a/mods/ITEMS/mcl_compass/depends.txt b/mods/ITEMS/mcl_compass/depends.txt deleted file mode 100644 index 53261d53c..000000000 --- a/mods/ITEMS/mcl_compass/depends.txt +++ /dev/null @@ -1,4 +0,0 @@ -mcl_core -mcl_worlds -mesecons -doc? diff --git a/mods/ITEMS/mcl_compass/description.txt b/mods/ITEMS/mcl_compass/description.txt deleted file mode 100644 index 221a9f6d9..000000000 --- a/mods/ITEMS/mcl_compass/description.txt +++ /dev/null @@ -1 +0,0 @@ -A compass item which points towards the world origin. diff --git a/mods/ITEMS/mcl_compass/mod.conf b/mods/ITEMS/mcl_compass/mod.conf index 8c9e0a652..41266222b 100644 --- a/mods/ITEMS/mcl_compass/mod.conf +++ b/mods/ITEMS/mcl_compass/mod.conf @@ -1 +1,4 @@ name = mcl_compass +description = A compass item which points towards the world origin. +depends = mcl_core, mcl_worlds, mesecons +optional_depends = doc diff --git a/mods/ITEMS/mcl_core/depends.txt b/mods/ITEMS/mcl_core/depends.txt deleted file mode 100644 index fb9861814..000000000 --- a/mods/ITEMS/mcl_core/depends.txt +++ /dev/null @@ -1,8 +0,0 @@ -mcl_init -mcl_sounds -mcl_particles -mcl_util -mcl_worlds -doc_items -doc? -mcl_enchanting diff --git a/mods/ITEMS/mcl_core/description.txt b/mods/ITEMS/mcl_core/description.txt deleted file mode 100644 index 96229f774..000000000 --- a/mods/ITEMS/mcl_core/description.txt +++ /dev/null @@ -1 +0,0 @@ -Core items of MineClone 2: Basic biome blocks (dirt, sand, stones, etc.), derived items, glass, sugar cane, cactus, barrier, mining tools, hand, craftitems, and misc. items which don't really fit anywhere else. diff --git a/mods/ITEMS/mcl_core/init.lua b/mods/ITEMS/mcl_core/init.lua index 520f158bd..897382e01 100644 --- a/mods/ITEMS/mcl_core/init.lua +++ b/mods/ITEMS/mcl_core/init.lua @@ -3,6 +3,19 @@ mcl_core = {} -- Repair percentage for toolrepair mcl_core.repair = 0.05 +mcl_autogroup.register_diggroup("handy") +mcl_autogroup.register_diggroup("pickaxey", { + levels = { "wood", "gold", "stone", "iron", "diamond" } +}) +mcl_autogroup.register_diggroup("axey") +mcl_autogroup.register_diggroup("shovely") +mcl_autogroup.register_diggroup("shearsy") +mcl_autogroup.register_diggroup("shearsy_wool") +mcl_autogroup.register_diggroup("shearsy_cobweb") +mcl_autogroup.register_diggroup("swordy") +mcl_autogroup.register_diggroup("swordy_cobweb") +mcl_autogroup.register_diggroup("hoey") + -- Load files local modpath = minetest.get_modpath("mcl_core") dofile(modpath.."/functions.lua") diff --git a/mods/ITEMS/mcl_core/mod.conf b/mods/ITEMS/mcl_core/mod.conf index 9227d607e..e204ace84 100644 --- a/mods/ITEMS/mcl_core/mod.conf +++ b/mods/ITEMS/mcl_core/mod.conf @@ -1 +1,4 @@ -name = mcl_core \ No newline at end of file +name = mcl_core +description = Core items of MineClone 2: Basic biome blocks (dirt, sand, stones, etc.), derived items, glass, sugar cane, cactus, barrier, mining tools, hand, craftitems, and misc. items which don't really fit anywhere else. +depends = mcl_autogroup, mcl_init, mcl_sounds, mcl_particles, mcl_util, mcl_worlds, doc_items, mcl_enchanting +optional_depends = doc diff --git a/mods/ITEMS/mcl_core/nodes_misc.lua b/mods/ITEMS/mcl_core/nodes_misc.lua index 305682244..083aa0b85 100644 --- a/mods/ITEMS/mcl_core/nodes_misc.lua +++ b/mods/ITEMS/mcl_core/nodes_misc.lua @@ -108,7 +108,7 @@ minetest.register_node("mcl_core:cobweb", { liquid_renewable = false, liquid_range = 0, walkable = false, - groups = {swordy_cobweb=1,shearsy=1, fake_liquid=1, disable_jump=1, deco_block=1, dig_by_piston=1, dig_by_water=1,destroy_by_lava_flow=1,}, + groups = {swordy_cobweb=1, shearsy_cobweb=1, fake_liquid=1, disable_jump=1, deco_block=1, dig_by_piston=1, dig_by_water=1,destroy_by_lava_flow=1,}, drop = "mcl_mobitems:string", _mcl_shears_drop = true, sounds = mcl_sounds.node_sound_leaves_defaults(), diff --git a/mods/ITEMS/mcl_core/nodes_trees.lua b/mods/ITEMS/mcl_core/nodes_trees.lua index 3a8aef8d0..197846ebc 100644 --- a/mods/ITEMS/mcl_core/nodes_trees.lua +++ b/mods/ITEMS/mcl_core/nodes_trees.lua @@ -108,7 +108,19 @@ local register_leaves = function(subname, description, longdesc, tiles, sapling, tiles = tiles, paramtype = "light", stack_max = 64, - groups = {handy=1,shearsy=1,swordy=1, leafdecay=leafdecay_distance, flammable=2, leaves=1, deco_block=1, dig_by_piston=1, fire_encouragement=30, fire_flammability=60}, + groups = { + handy=1, + hoey=1, + shearsy=1, + swordy=1, + leafdecay=leafdecay_distance, + flammable=2, + leaves=1, + deco_block=1, + dig_by_piston=1, + fire_encouragement=30, + fire_flammability=60 + }, drop = get_drops(0), _mcl_shears_drop = true, sounds = mcl_sounds.node_sound_leaves_defaults(), diff --git a/mods/ITEMS/mcl_doors/depends.txt b/mods/ITEMS/mcl_doors/depends.txt deleted file mode 100644 index e2ae3cf4b..000000000 --- a/mods/ITEMS/mcl_doors/depends.txt +++ /dev/null @@ -1,5 +0,0 @@ -mcl_core -mcl_sounds -doc? -screwdriver? -mesecons diff --git a/mods/ITEMS/mcl_doors/mod.conf b/mods/ITEMS/mcl_doors/mod.conf index d504e8497..ed2b094a8 100644 --- a/mods/ITEMS/mcl_doors/mod.conf +++ b/mods/ITEMS/mcl_doors/mod.conf @@ -1 +1,3 @@ name = mcl_doors +depends = mcl_core, mcl_sounds, mesecons +optional_depends = doc, screwdriver diff --git a/mods/ITEMS/mcl_dye/depends.txt b/mods/ITEMS/mcl_dye/depends.txt deleted file mode 100644 index 83185405e..000000000 --- a/mods/ITEMS/mcl_dye/depends.txt +++ /dev/null @@ -1,4 +0,0 @@ -mcl_core -mcl_flowers -mcl_mobitems -mcl_cocoas diff --git a/mods/ITEMS/mcl_dye/mod.conf b/mods/ITEMS/mcl_dye/mod.conf index 356b16434..fe93278fc 100644 --- a/mods/ITEMS/mcl_dye/mod.conf +++ b/mods/ITEMS/mcl_dye/mod.conf @@ -1 +1,2 @@ name = mcl_dye +depends = mcl_core, mcl_flowers, mcl_mobitems, mcl_cocoas diff --git a/mods/ITEMS/mcl_enchanting/enchantments.lua b/mods/ITEMS/mcl_enchanting/enchantments.lua index 893ce58d4..ca936c319 100644 --- a/mods/ITEMS/mcl_enchanting/enchantments.lua +++ b/mods/ITEMS/mcl_enchanting/enchantments.lua @@ -155,15 +155,7 @@ mcl_enchanting.enchantments.efficiency = { description = S("Increases mining speed."), curse = false, on_enchant = function(itemstack, level) - local tool_capabilities = itemstack:get_tool_capabilities() - local groupcaps = {} - for group, capability in pairs(tool_capabilities.groupcaps) do - local groupname = group .. "_efficiency_" .. level - capability.times = mcl_autogroup.digtimes[groupname] - groupcaps[groupname] = capability - end - tool_capabilities.groupcaps = groupcaps - itemstack:get_meta():set_tool_capabilities(tool_capabilities) + mcl_enchanting.update_groupcaps(itemstack) end, requires_tool = false, treasure = false, diff --git a/mods/ITEMS/mcl_enchanting/engine.lua b/mods/ITEMS/mcl_enchanting/engine.lua index 791527c5e..83149862a 100644 --- a/mods/ITEMS/mcl_enchanting/engine.lua +++ b/mods/ITEMS/mcl_enchanting/engine.lua @@ -219,6 +219,38 @@ function mcl_enchanting.enchantments_snippet(_, _, itemstack) end end +-- Returns the after_use callback function to use when registering an enchanted +-- item. The after_use callback is used to update the tool_capabilities of +-- efficiency enchanted tools with outdated digging times. +-- +-- It does this by calling apply_efficiency to reapply the efficiency +-- enchantment. That function is written to use hash values to only update the +-- tool if neccessary. +-- +-- This is neccessary for digging times of tools to be in sync when MineClone2 +-- or mods add new hardness values. +local function get_after_use_callback(itemdef) + if itemdef.after_use then + -- If the tool already has an after_use, make sure to call that + -- one too. + return function(itemstack, user, node, digparams) + itemdef.after_use(itemstack, user, node, digparams) + mcl_enchanting.update_groupcaps(itemstack) + end + end + + -- If the tool does not have after_use, add wear to the tool as if no + -- after_use was registered. + return function(itemstack, user, node, digparams) + if not minetest.is_creative_enabled(user) then + itemstack:add_wear(digparams.wear) + end + + local enchantments = mcl_enchanting.get_enchantments(itemstack) + mcl_enchanting.update_groupcaps(itemstack) + end +end + function mcl_enchanting.initialize() local register_tool_list = {} local register_item_list = {} @@ -236,6 +268,7 @@ function mcl_enchanting.initialize() new_def.groups.enchanted = 1 new_def.texture = itemdef.texture or itemname:gsub("%:", "_") new_def._mcl_enchanting_enchanted_tool = new_name + new_def.after_use = get_after_use_callback(itemdef) local register_list = register_item_list if itemdef.type == "tool" then register_list = register_tool_list diff --git a/mods/ITEMS/mcl_enchanting/groupcaps.lua b/mods/ITEMS/mcl_enchanting/groupcaps.lua new file mode 100644 index 000000000..216457d05 --- /dev/null +++ b/mods/ITEMS/mcl_enchanting/groupcaps.lua @@ -0,0 +1,63 @@ +local groupcaps_cache = {} + +-- Compute a hash value. +function compute_hash(value) + -- minetest.get_password_hash is quite fast, even if it uses a + -- cryptographic hashing function (SHA-1). It is written in C++ and it + -- is probably hard to write a faster hashing function in Lua. + return string.sub(minetest.get_password_hash("ryvnf", minetest.serialize(value)), 1, 8) +end + +-- Get the groupcaps and hash for an enchanted tool. If this function is called +-- repeatedly with the same values it will return data from a cache. +-- +-- Parameters: +-- toolname - Name of the tool +-- level - The efficiency level of the tool +-- +-- Returns a table with the following two fields: +-- values - The groupcaps table +-- hash - The hash of the groupcaps table +local function get_efficiency_groupcaps(toolname, level) + local toolcache = groupcaps_cache[toolname] + local level = level + + if not toolcache then + toolcache = {} + groupcaps_cache[toolname] = toolcache + end + + local levelcache = toolcache[level] + if not levelcache then + levelcache = {} + levelcache.values = mcl_autogroup.get_groupcaps(toolname, level) + levelcache.hash = compute_hash(levelcache.values) + toolcache[level] = levelcache + end + + return levelcache +end + +-- Update groupcaps of an enchanted tool. This function will be called +-- repeatedly to make sure the digging times stored in groupcaps stays in sync +-- when the digging times of nodes can change. +-- +-- To make it more efficient it will first check a hash value to determine if +-- the tool needs to be updated. +function mcl_enchanting.update_groupcaps(itemstack) + if not itemstack:get_tool_capabilities() then + return + end + + local name = itemstack:get_name() + local level = mcl_enchanting.get_enchantment(itemstack, "efficiency") + local groupcaps = get_efficiency_groupcaps(name, level) + local hash = itemstack:get_meta():get_string("groupcaps_hash") + + if not hash or hash ~= groupcaps.hash then + local tool_capabilities = itemstack:get_tool_capabilities() + tool_capabilities.groupcaps = groupcaps.values + itemstack:get_meta():set_tool_capabilities(tool_capabilities) + itemstack:get_meta():set_string("groupcaps_hash", groupcaps.hash) + end +end diff --git a/mods/ITEMS/mcl_enchanting/init.lua b/mods/ITEMS/mcl_enchanting/init.lua index 4918e3776..855e3bf33 100644 --- a/mods/ITEMS/mcl_enchanting/init.lua +++ b/mods/ITEMS/mcl_enchanting/init.lua @@ -59,6 +59,7 @@ mcl_enchanting = { } dofile(modpath .. "/engine.lua") +dofile(modpath .. "/groupcaps.lua") dofile(modpath .. "/enchantments.lua") minetest.register_chatcommand("enchant", { diff --git a/mods/ITEMS/mcl_end/end_crystal.lua b/mods/ITEMS/mcl_end/end_crystal.lua index 8686f1de0..b6b9fdd6a 100644 --- a/mods/ITEMS/mcl_end/end_crystal.lua +++ b/mods/ITEMS/mcl_end/end_crystal.lua @@ -85,14 +85,15 @@ minetest.register_craftitem("mcl_end:crystal", { on_place = function(itemstack, placer, pointed_thing) if pointed_thing.type == "node" then local pos = minetest.get_pointed_thing_position(pointed_thing) - local node = minetest.get_node(pos).name + local node = minetest.get_node(pos) + local node_name = node.name 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(pointed_thing.under, node, placer, itemstack) or itemstack + if minetest.registered_nodes[node_name] and minetest.registered_nodes[node_name].on_rightclick then + return minetest.registered_nodes[node_name].on_rightclick(pointed_thing.under, node, placer, itemstack) or itemstack end end if find_crystal(pos) then return itemstack end - if node == "mcl_core:obsidian" or node == "mcl_core:bedrock" then + if node_name == "mcl_core:obsidian" or node_name == "mcl_core:bedrock" then if not minetest.is_creative_enabled(placer:get_player_name()) then itemstack:take_item() end diff --git a/mods/ITEMS/mcl_farming/depends.txt b/mods/ITEMS/mcl_farming/depends.txt deleted file mode 100644 index 0ed4f3f58..000000000 --- a/mods/ITEMS/mcl_farming/depends.txt +++ /dev/null @@ -1,8 +0,0 @@ -mcl_core -mcl_sounds -mcl_wool -mcl_torches -mcl_weather -mcl_armor? -mobs_mc -doc? diff --git a/mods/ITEMS/mcl_farming/hoes.lua b/mods/ITEMS/mcl_farming/hoes.lua index 5a383d78a..a45b382ed 100644 --- a/mods/ITEMS/mcl_farming/hoes.lua +++ b/mods/ITEMS/mcl_farming/hoes.lua @@ -78,6 +78,9 @@ minetest.register_tool("mcl_farming:hoe_wood", { }, _repair_material = "group:wood", _mcl_toollike_wield = true, + _mcl_diggroups = { + hoey = { speed = 2, level = 1, uses = 60 } + }, }) minetest.register_craft({ @@ -118,6 +121,9 @@ minetest.register_tool("mcl_farming:hoe_stone", { }, _repair_material = "mcl_core:cobble", _mcl_toollike_wield = true, + _mcl_diggroups = { + hoey = { speed = 4, level = 3, uses = 132 } + }, }) minetest.register_craft({ @@ -154,6 +160,9 @@ minetest.register_tool("mcl_farming:hoe_iron", { }, _repair_material = "mcl_core:iron_ingot", _mcl_toollike_wield = true, + _mcl_diggroups = { + hoey = { speed = 6, level = 4, uses = 251 } + }, }) minetest.register_craft({ @@ -196,6 +205,9 @@ minetest.register_tool("mcl_farming:hoe_gold", { }, _repair_material = "mcl_core:gold_ingot", _mcl_toollike_wield = true, + _mcl_diggroups = { + hoey = { speed = 12, level = 2, uses = 33 } + }, }) minetest.register_craft({ @@ -240,6 +252,9 @@ minetest.register_tool("mcl_farming:hoe_diamond", { }, _repair_material = "mcl_core:diamond", _mcl_toollike_wield = true, + _mcl_diggroups = { + hoey = { speed = 8, level = 5, uses = 1562 } + }, }) minetest.register_craft({ diff --git a/mods/ITEMS/mcl_farming/mod.conf b/mods/ITEMS/mcl_farming/mod.conf index 4805e95db..73627923e 100644 --- a/mods/ITEMS/mcl_farming/mod.conf +++ b/mods/ITEMS/mcl_farming/mod.conf @@ -1 +1,3 @@ name = mcl_farming +depends = mcl_core, mcl_sounds, mcl_wool, mcl_torches, mcl_weather, mobs_mc +optional_depends = mcl_armor, doc diff --git a/mods/ITEMS/mcl_farming/textures/mcl_farming_pumpkin_face.png b/mods/ITEMS/mcl_farming/textures/mcl_farming_pumpkin_face.png index a2fd0fbf9..095b90cc6 100644 Binary files a/mods/ITEMS/mcl_farming/textures/mcl_farming_pumpkin_face.png and b/mods/ITEMS/mcl_farming/textures/mcl_farming_pumpkin_face.png differ diff --git a/mods/ITEMS/mcl_farming/wheat.lua b/mods/ITEMS/mcl_farming/wheat.lua index 9a8a9f65e..e3ee79ead 100644 --- a/mods/ITEMS/mcl_farming/wheat.lua +++ b/mods/ITEMS/mcl_farming/wheat.lua @@ -146,7 +146,7 @@ minetest.register_node("mcl_farming:hay_block", { paramtype2 = "facedir", is_ground_content = false, on_place = mcl_util.rotate_axis, - groups = {handy=1, flammable=2, fire_encouragement=60, fire_flammability=20, building_block=1, fall_damage_add_percent=-80}, + groups = {handy=1, hoey=1, flammable=2, fire_encouragement=60, fire_flammability=20, building_block=1, fall_damage_add_percent=-80}, sounds = mcl_sounds.node_sound_leaves_defaults(), on_rotate = on_rotate, _mcl_blast_resistance = 0.5, diff --git a/mods/ITEMS/mcl_fences/depends.txt b/mods/ITEMS/mcl_fences/depends.txt deleted file mode 100644 index 217875c56..000000000 --- a/mods/ITEMS/mcl_fences/depends.txt +++ /dev/null @@ -1,4 +0,0 @@ -mcl_core -mcl_sounds -doc? -screwdriver? diff --git a/mods/ITEMS/mcl_fences/mod.conf b/mods/ITEMS/mcl_fences/mod.conf index b5eafa90f..8b20dd169 100644 --- a/mods/ITEMS/mcl_fences/mod.conf +++ b/mods/ITEMS/mcl_fences/mod.conf @@ -1 +1,3 @@ name = mcl_fences +depends = mcl_core, mcl_sounds +optional_depends = doc, screwdriver diff --git a/mods/ITEMS/mcl_fire/init.lua b/mods/ITEMS/mcl_fire/init.lua index f11c683a6..95d76c45d 100644 --- a/mods/ITEMS/mcl_fire/init.lua +++ b/mods/ITEMS/mcl_fire/init.lua @@ -50,69 +50,69 @@ local alldirs= -- 3 exptime variants because the animation is not tied to particle expiration time. -- 3 colorized variants to imitate minecraft's local smoke_pdef_base = { - amount = 0.001, - time = 0, - -- minpos = vector.add(pos, { x = -0.45, y = -0.45, z = -0.45 }), - -- maxpos = vector.add(pos, { x = 0.45, y = 0.45, z = 0.45 }), - minvel = { x = -0.1, y = 0.3, z = -0.1 }, - maxvel = { x = 0.1, y = 1.6, z = 0.1 }, - -- minexptime = 3 exptime variants, - -- maxexptime = 3 exptime variants - minsize = 4.0, - maxsize = 4.5, - -- texture = "mcl_particles_smoke_anim.png^[colorize:#000000:(3 colourize variants)", - animation = { - type = "vertical_frames", - aspect_w = 8, - aspect_h = 8, - -- length = 3 exptime variants - }, - collisiondetection = true, + amount = 0.001, + time = 0, + -- minpos = vector.add(pos, { x = -0.45, y = -0.45, z = -0.45 }), + -- maxpos = vector.add(pos, { x = 0.45, y = 0.45, z = 0.45 }), + minvel = { x = -0.1, y = 0.3, z = -0.1 }, + maxvel = { x = 0.1, y = 1.6, z = 0.1 }, + -- minexptime = 3 exptime variants, + -- maxexptime = 3 exptime variants + minsize = 4.0, + maxsize = 4.5, + -- texture = "mcl_particles_smoke_anim.png^[colorize:#000000:(3 colourize variants)", + animation = { + type = "vertical_frames", + aspect_w = 8, + aspect_h = 8, + -- length = 3 exptime variants + }, + collisiondetection = true, } local smoke_pdef_cached = {} local spawn_smoke = function(pos) - local min = math.min - local new_minpos = vector.add(pos, { x = -0.45, y = -0.45, z = -0.45 }) - local new_maxpos = vector.add(pos, { x = 0.45, y = 0.45, z = 0.45 }) + local min = math.min + local new_minpos = vector.add(pos, { x = -0.45, y = -0.45, z = -0.45 }) + local new_maxpos = vector.add(pos, { x = 0.45, y = 0.45, z = 0.45 }) - -- populate the cache - if not next(smoke_pdef_cached) then - -- the last frame plays for 1/8 * N seconds, so we can take advantage of it - -- to have varying exptime for each variant. - local exptimes = { 0.75, 1.5, 4.0 } - local colorizes = { "199", "209", "243" } -- round(78%, 82%, 90% of 256) - 1 + -- populate the cache + if not next(smoke_pdef_cached) then + -- the last frame plays for 1/8 * N seconds, so we can take advantage of it + -- to have varying exptime for each variant. + local exptimes = { 0.75, 1.5, 4.0 } + local colorizes = { "199", "209", "243" } -- round(78%, 82%, 90% of 256) - 1 - local id = 1 - for _,exptime in ipairs(exptimes) do - for _,colorize in ipairs(colorizes) do - smoke_pdef_base.minpos = new_minpos - smoke_pdef_base.maxpos = new_maxpos - smoke_pdef_base.maxexptime = exptime - smoke_pdef_base.animation.length = exptime + 0.1 - -- minexptime must be set such that the last frame is actully rendered, - -- even if its very short. Larger exptime -> larger range - smoke_pdef_base.minexptime = min(exptime, (7.0/8.0 * (exptime + 0.1) + 0.1)) - smoke_pdef_base.texture = "mcl_particles_smoke_anim.png^[colorize:#000000:" ..colorize + local id = 1 + for _,exptime in ipairs(exptimes) do + for _,colorize in ipairs(colorizes) do + smoke_pdef_base.minpos = new_minpos + smoke_pdef_base.maxpos = new_maxpos + smoke_pdef_base.maxexptime = exptime + smoke_pdef_base.animation.length = exptime + 0.1 + -- minexptime must be set such that the last frame is actully rendered, + -- even if its very short. Larger exptime -> larger range + smoke_pdef_base.minexptime = min(exptime, (7.0/8.0 * (exptime + 0.1) + 0.1)) + smoke_pdef_base.texture = "mcl_particles_smoke_anim.png^[colorize:#000000:" ..colorize - smoke_pdef_cached[id] = table.copy(smoke_pdef_base) + smoke_pdef_cached[id] = table.copy(smoke_pdef_base) - mcl_particles.add_node_particlespawner(pos, smoke_pdef_cached[id], "high") + mcl_particles.add_node_particlespawner(pos, smoke_pdef_cached[id], "high") - id = id + 1 - end - end + id = id + 1 + end + end - -- cache already populated - else - for i, smoke_pdef in ipairs(smoke_pdef_cached) do - smoke_pdef.minpos = new_minpos - smoke_pdef.maxpos = new_maxpos - mcl_particles.add_node_particlespawner(pos, smoke_pdef, "high") - end - end + -- cache already populated + else + for i, smoke_pdef in ipairs(smoke_pdef_cached) do + smoke_pdef.minpos = new_minpos + smoke_pdef.maxpos = new_maxpos + mcl_particles.add_node_particlespawner(pos, smoke_pdef, "high") + end + end --[[ Old smoke pdef - local spawn_smoke = function(pos) + local spawn_smoke = function(pos) mcl_particles.add_node_particlespawner(pos, { amount = 0.1, time = 0, @@ -132,7 +132,7 @@ local spawn_smoke = function(pos) length = 2.1, }, }, "high") - -- ]] + -- ]] end diff --git a/mods/ITEMS/mcl_fishing/depends.txt b/mods/ITEMS/mcl_fishing/depends.txt deleted file mode 100644 index bbc3c6ad8..000000000 --- a/mods/ITEMS/mcl_fishing/depends.txt +++ /dev/null @@ -1,5 +0,0 @@ -mcl_core -mcl_sounds -mcl_loot -mcl_mobs -mcl_enchanting diff --git a/mods/ITEMS/mcl_fishing/description.txt b/mods/ITEMS/mcl_fishing/description.txt deleted file mode 100644 index 1befeab16..000000000 --- a/mods/ITEMS/mcl_fishing/description.txt +++ /dev/null @@ -1 +0,0 @@ -Adds fish and fishing poles to go fishing. diff --git a/mods/ITEMS/mcl_fishing/mod.conf b/mods/ITEMS/mcl_fishing/mod.conf index 3a02c5cfc..56a3305a0 100644 --- a/mods/ITEMS/mcl_fishing/mod.conf +++ b/mods/ITEMS/mcl_fishing/mod.conf @@ -1 +1,3 @@ name = mcl_fishing +description = Adds fish and fishing poles to go fishing. +depends = mcl_core, mcl_sounds, mcl_loot, mcl_mobs, mcl_enchanting diff --git a/mods/ITEMS/mcl_furnaces/depends.txt b/mods/ITEMS/mcl_furnaces/depends.txt deleted file mode 100644 index ca05945f1..000000000 --- a/mods/ITEMS/mcl_furnaces/depends.txt +++ /dev/null @@ -1,9 +0,0 @@ -mcl_init -mcl_formspec -mcl_core -mcl_sounds -mcl_craftguide -mcl_achievements -mcl_particles -doc? -screwdriver? diff --git a/mods/ITEMS/mcl_furnaces/init.lua b/mods/ITEMS/mcl_furnaces/init.lua index d3877d90b..63b4bbc7b 100644 --- a/mods/ITEMS/mcl_furnaces/init.lua +++ b/mods/ITEMS/mcl_furnaces/init.lua @@ -161,6 +161,12 @@ local function on_metadata_inventory_take(pos, listname, index, stack, player) end end +local function on_metadata_inventory_move(pos, from_list, from_index, to_list, to_index, count, player) + if from_list == "dst" then + give_xp(pos, player) + end +end + local function spawn_flames(pos, param2) local minrelpos, maxrelpos local dir = minetest.facedir_to_dir(param2) @@ -477,10 +483,12 @@ minetest.register_node("mcl_furnaces:furnace", { give_xp(pos) end, - on_metadata_inventory_move = function(pos) + on_metadata_inventory_move = function(pos, from_list, from_index, to_list, to_index, count, player) -- Reset accumulated game time when player works with furnace: furnace_reset_delta_time(pos) minetest.get_node_timer(pos):start(1.0) + + on_metadata_inventory_move(pos, from_list, from_index, to_list, to_index, count, player) end, on_metadata_inventory_put = function(pos) -- Reset accumulated game time when player works with furnace: @@ -494,9 +502,7 @@ minetest.register_node("mcl_furnaces:furnace", { -- start timer function, it will helpful if player clears dst slot minetest.get_node_timer(pos):start(1.0) - if listname == "dst" then - give_xp(pos, player) - end + on_metadata_inventory_take(pos, listname, index, stack, player) end, allow_metadata_inventory_put = allow_metadata_inventory_put, @@ -552,6 +558,7 @@ minetest.register_node("mcl_furnaces:furnace_active", { allow_metadata_inventory_put = allow_metadata_inventory_put, allow_metadata_inventory_move = allow_metadata_inventory_move, allow_metadata_inventory_take = allow_metadata_inventory_take, + on_metadata_inventory_move = on_metadata_inventory_move, on_metadata_inventory_take = on_metadata_inventory_take, on_receive_fields = receive_fields, _mcl_blast_resistance = 3.5, diff --git a/mods/ITEMS/mcl_furnaces/mod.conf b/mods/ITEMS/mcl_furnaces/mod.conf index 32f1ed8e8..fe0b9c208 100644 --- a/mods/ITEMS/mcl_furnaces/mod.conf +++ b/mods/ITEMS/mcl_furnaces/mod.conf @@ -1 +1,3 @@ name = mcl_furnaces +depends = mcl_init, mcl_formspec, mcl_core, mcl_sounds, mcl_craftguide, mcl_achievements, mcl_particles +optional_depends = doc, screwdriver diff --git a/mods/ITEMS/mcl_heads/depends.txt b/mods/ITEMS/mcl_heads/depends.txt deleted file mode 100644 index 01846722d..000000000 --- a/mods/ITEMS/mcl_heads/depends.txt +++ /dev/null @@ -1,4 +0,0 @@ -mcl_sounds -mcl_armor? -screwdriver? -doc? diff --git a/mods/ITEMS/mcl_heads/description.txt b/mods/ITEMS/mcl_heads/description.txt deleted file mode 100644 index b169ba796..000000000 --- a/mods/ITEMS/mcl_heads/description.txt +++ /dev/null @@ -1 +0,0 @@ -Small decorative head blocks. diff --git a/mods/ITEMS/mcl_heads/mod.conf b/mods/ITEMS/mcl_heads/mod.conf index 0dab90077..e2fe34f63 100644 --- a/mods/ITEMS/mcl_heads/mod.conf +++ b/mods/ITEMS/mcl_heads/mod.conf @@ -1 +1,4 @@ name = mcl_heads +description = Small decorative head blocks. +depends = mcl_sounds +optional_depends = mcl_armor, screwdriver, doc diff --git a/mods/ITEMS/mcl_hoppers/depends.txt b/mods/ITEMS/mcl_hoppers/depends.txt deleted file mode 100644 index 67a60d4df..000000000 --- a/mods/ITEMS/mcl_hoppers/depends.txt +++ /dev/null @@ -1,6 +0,0 @@ -mcl_core -mcl_formspec -mcl_sounds -mcl_util -doc? -screwdriver? diff --git a/mods/ITEMS/mcl_hoppers/description.txt b/mods/ITEMS/mcl_hoppers/description.txt deleted file mode 100644 index 4430809ac..000000000 --- a/mods/ITEMS/mcl_hoppers/description.txt +++ /dev/null @@ -1 +0,0 @@ -It's just a clone of Minecraft hoppers, functions nearly identical to them minus mesecons making them stop and the way they're placed. diff --git a/mods/ITEMS/mcl_hoppers/mod.conf b/mods/ITEMS/mcl_hoppers/mod.conf new file mode 100644 index 000000000..c89292f6b --- /dev/null +++ b/mods/ITEMS/mcl_hoppers/mod.conf @@ -0,0 +1,4 @@ +name = mcl_hoppers +description = It's just a clone of Minecraft hoppers, functions nearly identical to them minus mesecons making them stop and the way they're placed. +depends = mcl_core, mcl_formspec, mcl_sounds, mcl_util +optional_depends = doc, screwdriver diff --git a/mods/ITEMS/mcl_itemframes/depends.txt b/mods/ITEMS/mcl_itemframes/depends.txt deleted file mode 100644 index 0b5088e3c..000000000 --- a/mods/ITEMS/mcl_itemframes/depends.txt +++ /dev/null @@ -1,3 +0,0 @@ -mcl_core -mcl_sounds -screwdriver? diff --git a/mods/ITEMS/mcl_itemframes/mod.conf b/mods/ITEMS/mcl_itemframes/mod.conf new file mode 100644 index 000000000..39f4370aa --- /dev/null +++ b/mods/ITEMS/mcl_itemframes/mod.conf @@ -0,0 +1,3 @@ +name = mcl_itemframes +depends = mcl_core, mcl_sounds +optional_depends = screwdriver diff --git a/mods/ITEMS/mcl_mobitems/depends.txt b/mods/ITEMS/mcl_mobitems/depends.txt deleted file mode 100644 index 73d023f65..000000000 --- a/mods/ITEMS/mcl_mobitems/depends.txt +++ /dev/null @@ -1,2 +0,0 @@ -mcl_core -mcl_hunger diff --git a/mods/ITEMS/mcl_mobitems/mod.conf b/mods/ITEMS/mcl_mobitems/mod.conf index bd534323a..dc85b6b01 100644 --- a/mods/ITEMS/mcl_mobitems/mod.conf +++ b/mods/ITEMS/mcl_mobitems/mod.conf @@ -1 +1,2 @@ name = mcl_mobitems +depends = mcl_core, mcl_hunger diff --git a/mods/ITEMS/mcl_mobspawners/depends.txt b/mods/ITEMS/mcl_mobspawners/depends.txt deleted file mode 100644 index dc1a03b82..000000000 --- a/mods/ITEMS/mcl_mobspawners/depends.txt +++ /dev/null @@ -1,2 +0,0 @@ -mcl_sounds -mcl_mobs diff --git a/mods/ITEMS/mcl_mobspawners/mod.conf b/mods/ITEMS/mcl_mobspawners/mod.conf index 36112bf36..1759e3408 100644 --- a/mods/ITEMS/mcl_mobspawners/mod.conf +++ b/mods/ITEMS/mcl_mobspawners/mod.conf @@ -1 +1,2 @@ name = mcl_mobspawners +depends = mcl_sounds, mcl_mobs diff --git a/mods/ITEMS/mcl_monster_eggs/depends.txt b/mods/ITEMS/mcl_monster_eggs/depends.txt deleted file mode 100644 index d867036e5..000000000 --- a/mods/ITEMS/mcl_monster_eggs/depends.txt +++ /dev/null @@ -1,2 +0,0 @@ -mcl_sounds -mobs_mc diff --git a/mods/ITEMS/mcl_monster_eggs/description.txt b/mods/ITEMS/mcl_monster_eggs/description.txt deleted file mode 100644 index ae7cab253..000000000 --- a/mods/ITEMS/mcl_monster_eggs/description.txt +++ /dev/null @@ -1 +0,0 @@ -Adds infested blocks: Blocks which which disguise themselves as stone blocks and spawn a silverfish when broken. diff --git a/mods/ITEMS/mcl_monster_eggs/mod.conf b/mods/ITEMS/mcl_monster_eggs/mod.conf new file mode 100644 index 000000000..b29601864 --- /dev/null +++ b/mods/ITEMS/mcl_monster_eggs/mod.conf @@ -0,0 +1,3 @@ +name = mcl_monster_eggs +description = Adds infested blocks: Blocks which which disguise themselves as stone blocks and spawn a silverfish when broken. +depends = mcl_sounds, mobs_mc diff --git a/mods/ITEMS/mcl_mushrooms/depends.txt b/mods/ITEMS/mcl_mushrooms/depends.txt deleted file mode 100644 index 7ddb9b8f8..000000000 --- a/mods/ITEMS/mcl_mushrooms/depends.txt +++ /dev/null @@ -1,3 +0,0 @@ -mcl_sounds -mcl_util -doc? diff --git a/mods/ITEMS/mcl_mushrooms/mod.conf b/mods/ITEMS/mcl_mushrooms/mod.conf index 64bbd8ca4..20f7bef16 100644 --- a/mods/ITEMS/mcl_mushrooms/mod.conf +++ b/mods/ITEMS/mcl_mushrooms/mod.conf @@ -1 +1,3 @@ name = mcl_mushrooms +depends = mcl_sounds, mcl_util +optional_depends = doc diff --git a/mods/ITEMS/mcl_nether/depends.txt b/mods/ITEMS/mcl_nether/depends.txt deleted file mode 100644 index 96f253aa0..000000000 --- a/mods/ITEMS/mcl_nether/depends.txt +++ /dev/null @@ -1,8 +0,0 @@ -mcl_core -mcl_sounds -mcl_util -walkover -mcl_death_messages? -doc_items -doc? -screwdriver? diff --git a/mods/ITEMS/mcl_nether/init.lua b/mods/ITEMS/mcl_nether/init.lua index 7c8dd56a5..30fc17148 100644 --- a/mods/ITEMS/mcl_nether/init.lua +++ b/mods/ITEMS/mcl_nether/init.lua @@ -176,7 +176,7 @@ minetest.register_node("mcl_nether:nether_wart_block", { stack_max = 64, tiles = {"mcl_nether_nether_wart_block.png"}, is_ground_content = false, - groups = {handy=1, building_block=1}, + groups = {handy=1, hoey=1, building_block=1}, sounds = mcl_sounds.node_sound_leaves_defaults( { footstep={name="default_dirt_footstep", gain=0.7}, diff --git a/mods/ITEMS/mcl_nether/mod.conf b/mods/ITEMS/mcl_nether/mod.conf index 2b6c641af..807bf311e 100644 --- a/mods/ITEMS/mcl_nether/mod.conf +++ b/mods/ITEMS/mcl_nether/mod.conf @@ -1 +1,3 @@ name = mcl_nether +depends = mcl_core, mcl_sounds, mcl_util, walkover, doc_items +optional_depends = mcl_death_messages, doc, screwdriver diff --git a/mods/ITEMS/mcl_ocean/depends.txt b/mods/ITEMS/mcl_ocean/depends.txt deleted file mode 100644 index 66908e83d..000000000 --- a/mods/ITEMS/mcl_ocean/depends.txt +++ /dev/null @@ -1,6 +0,0 @@ -mcl_core -mcl_sounds -mcl_dye -doc? -doc_items? -screwdriver? diff --git a/mods/ITEMS/mcl_ocean/description.txt b/mods/ITEMS/mcl_ocean/description.txt deleted file mode 100644 index bff01f614..000000000 --- a/mods/ITEMS/mcl_ocean/description.txt +++ /dev/null @@ -1 +0,0 @@ -Ocean-related blocks and items (for the ocean temple). diff --git a/mods/ITEMS/mcl_ocean/kelp.lua b/mods/ITEMS/mcl_ocean/kelp.lua index 2e0dfe1a5..3c6e32422 100644 --- a/mods/ITEMS/mcl_ocean/kelp.lua +++ b/mods/ITEMS/mcl_ocean/kelp.lua @@ -275,7 +275,7 @@ minetest.register_node("mcl_ocean:dried_kelp_block", { description = S("Dried Kelp Block"), _doc_items_longdesc = S("A decorative block that serves as a great furnace fuel."), tiles = { "mcl_ocean_dried_kelp_top.png", "mcl_ocean_dried_kelp_bottom.png", "mcl_ocean_dried_kelp_side.png" }, - groups = { handy = 1, building_block = 1, flammable = 2, fire_encouragement = 30, fire_flammability = 60 }, + groups = { handy = 1, hoey = 1, building_block = 1, flammable = 2, fire_encouragement = 30, fire_flammability = 60 }, sounds = mcl_sounds.node_sound_leaves_defaults(), paramtype2 = "facedir", on_place = mcl_util.rotate_axis, diff --git a/mods/ITEMS/mcl_ocean/mod.conf b/mods/ITEMS/mcl_ocean/mod.conf index 664d8e1e8..9b639a7b0 100644 --- a/mods/ITEMS/mcl_ocean/mod.conf +++ b/mods/ITEMS/mcl_ocean/mod.conf @@ -1,2 +1,4 @@ name = mcl_ocean description = Includes various ocean nodes +depends = mcl_core, mcl_sounds, mcl_dye +optional_depends = doc, doc_items, screwdriver diff --git a/mods/ITEMS/mcl_portals/depends.txt b/mods/ITEMS/mcl_portals/depends.txt deleted file mode 100644 index f794e5f9c..000000000 --- a/mods/ITEMS/mcl_portals/depends.txt +++ /dev/null @@ -1,9 +0,0 @@ -mcl_init -mcl_worlds -mcl_core -mcl_nether -mcl_end -mcl_particles -mcl_spawn -awards? -doc? diff --git a/mods/ITEMS/mcl_portals/description.txt b/mods/ITEMS/mcl_portals/description.txt deleted file mode 100644 index fe84531f3..000000000 --- a/mods/ITEMS/mcl_portals/description.txt +++ /dev/null @@ -1 +0,0 @@ -Adds buildable portals to the Nether and End dimensions. diff --git a/mods/ITEMS/mcl_portals/mod.conf b/mods/ITEMS/mcl_portals/mod.conf index e82fbe6c1..d99344a76 100644 --- a/mods/ITEMS/mcl_portals/mod.conf +++ b/mods/ITEMS/mcl_portals/mod.conf @@ -1 +1,4 @@ name = mcl_portals +description = Adds buildable portals to the Nether and End dimensions. +depends = mcl_nether, mcl_end, mcl_particles, mcl_spawn +optional_depends = awards, doc diff --git a/mods/ITEMS/mcl_portals/portal_nether.lua b/mods/ITEMS/mcl_portals/portal_nether.lua index ff9df2b4d..f67980bbf 100644 --- a/mods/ITEMS/mcl_portals/portal_nether.lua +++ b/mods/ITEMS/mcl_portals/portal_nether.lua @@ -1,83 +1,213 @@ local S = minetest.get_translator("mcl_portals") --- Parameters +-- Localize functions for better performance +local abs = math.abs +local ceil = math.ceil +local floor = math.floor +local max = math.max +local min = math.min +local random = math.random +local dist = vector.distance +local add = vector.add +local mul = vector.multiply +local sub = vector.subtract -local OVERWORLD_TO_NETHER_SCALE = 8 -local LIMIT = math.min(math.abs(mcl_vars.mapgen_edge_min), math.abs(mcl_vars.mapgen_edge_max)) +-- Setup +local W_MIN, W_MAX = 4, 23 +local H_MIN, H_MAX = 5, 23 +local N_MIN, N_MAX = 6, (W_MAX-2) * (H_MAX-2) +local TRAVEL_X, TRAVEL_Y, TRAVEL_Z = 8, 1, 8 +local LIM_MIN, LIM_MAX = mcl_vars.mapgen_edge_min, mcl_vars.mapgen_edge_max +local PLAYER_COOLOFF, MOB_COOLOFF = 3, 14 -- for this many seconds they won't teleported again +local TOUCH_CHATTER_TIME = 1 -- prevent multiple teleportation attempts caused by multiple portal touches, for this number of seconds +local CHATTER_US = TOUCH_CHATTER_TIME * 1000000 +local DELAY = 3 -- seconds before teleporting in Nether portal in Survival mode (4 minus ABM interval time) +local DISTANCE_MAX = 128 +local PORTAL = "mcl_portals:portal" +local OBSIDIAN = "mcl_core:obsidian" +local O_Y_MIN, O_Y_MAX = max(mcl_vars.mg_overworld_min, -31), min(mcl_vars.mg_overworld_max_official, 2048) +local N_Y_MIN, N_Y_MAX = mcl_vars.mg_bedrock_nether_bottom_min, mcl_vars.mg_bedrock_nether_top_max +local O_DY, N_DY = O_Y_MAX - O_Y_MIN + 1, N_Y_MAX - N_Y_MIN + 1 --- Portal frame sizes -local FRAME_SIZE_X_MIN = 4 -local FRAME_SIZE_Y_MIN = 5 -local FRAME_SIZE_X_MAX = 23 -local FRAME_SIZE_Y_MAX = 23 - -local PORTAL_NODES_MIN = 5 -local PORTAL_NODES_MAX = (FRAME_SIZE_X_MAX - 2) * (FRAME_SIZE_Y_MAX - 2) - -local TELEPORT_COOLOFF = 3 -- after player was teleported, for this many seconds they won't teleported again -local MOB_TELEPORT_COOLOFF = 14 -- after mob was teleported, for this many seconds they won't teleported again -local TOUCH_CHATTER_TIME = 1 -- prevent multiple teleportation attempts caused by multiple portal touches, for this number of seconds -local TOUCH_CHATTER_TIME_US = TOUCH_CHATTER_TIME * 1000000 -local TELEPORT_DELAY = 3 -- seconds before teleporting in Nether portal (4 minus ABM interval time) -local DESTINATION_EXPIRES = 60 * 1000000 -- cached destination expires after this number of microseconds have passed without using the same origin portal - -local PORTAL_SEARCH_HALF_CHUNK = 40 -- greater values may slow down the teleportation -local PORTAL_SEARCH_ALTITUDE = 128 - -local PORTAL_ALPHA = 192 -if minetest.features.use_texture_alpha_string_modes then - PORTAL_ALPHA = nil -end +-- Alpha and particles +local ALPHA = minetest.features.use_texture_alpha_string_modes and 192 +local node_particles_allowed = minetest.settings:get("mcl_node_particles") or "none" +local node_particles_levels = { none=0, low=1, medium=2, high=3 } +local PARTICLES = node_particles_levels[node_particles_allowed] -- Table of objects (including players) which recently teleported by a -- Nether portal. Those objects have a brief cooloff period before they -- can teleport again. This prevents annoying back-and-forth teleportation. -mcl_portals.nether_portal_cooloff = {} -local touch_chatter_prevention = {} +local cooloff = {} +function mcl_portals.nether_portal_cooloff(object) + return cooloff[object] +end -local overworld_ymin = math.max(mcl_vars.mg_overworld_min, -31) -local overworld_ymax = math.min(mcl_vars.mg_overworld_max_official, 63) -local nether_ymin = mcl_vars.mg_bedrock_nether_bottom_min -local nether_ymax = mcl_vars.mg_bedrock_nether_top_max -local overworld_dy = overworld_ymax - overworld_ymin + 1 -local nether_dy = nether_ymax - nether_ymin + 1 +local chatter = {} -local node_particles_allowed = minetest.settings:get("mcl_node_particles") or "none" -local node_particles_levels = { - high = 3, - medium = 2, - low = 1, - none = 0, +local queue = {} +local chunks = {} + +local storage = minetest.get_mod_storage() +local exits = {} +local keys = minetest.deserialize(storage:get_string("nether_exits_keys") or "return {}") or {} +for _, key in pairs(keys) do + local n = tonumber(key) + if n then + exits[key] = minetest.deserialize(storage:get_string("nether_exits_"..key) or "return {}") or {} + end +end +minetest.register_on_shutdown(function() + local keys={} + for key, data in pairs(exits) do + storage:set_string("nether_exits_"..tostring(key), minetest.serialize(data)) + keys[#keys+1] = key + end + storage:set_string("nether_exits_keys", minetest.serialize(keys)) +end) + +mcl_portals.get_node = function(pos) + if mcl_mapgen_core and mcl_mapgen_core.get_node then + mcl_portals.get_node = mcl_mapgen_core.get_node + end + return minetest.get_node(pos) +end +local set_node = minetest.set_node +local registered_nodes = minetest.registered_nodes +local is_protected = minetest.is_protected +local find_nodes_in_area = minetest.find_nodes_in_area +local find_nodes_in_area_under_air = minetest.find_nodes_in_area_under_air +local log = minetest.log +local pos_to_string = minetest.pos_to_string +local is_area_protected = minetest.is_area_protected +local get_us_time = minetest.get_us_time + +local limits = { + nether = { + pmin = {x=LIM_MIN, y = N_Y_MIN, z = LIM_MIN}, + pmax = {x=LIM_MAX, y = N_Y_MAX, z = LIM_MAX}, + }, + overworld = { + pmin = {x=LIM_MIN, y = O_Y_MIN, z = LIM_MIN}, + pmax = {x=LIM_MAX, y = O_Y_MAX, z = LIM_MAX}, + }, } -local node_particles_allowed_level = node_particles_levels[node_particles_allowed] + +-- This function registers exits from Nether portals. +-- Incoming verification performed: two nodes must be portal nodes, and an obsidian below them. +-- If the verification passes - position adds to the table and saves to mod storage on exit. +local function add_exit(p) + local get_node = mcl_portals.get_node + if not p or not p.y or not p.z or not p.x then return end + local x, y, z = floor(p.x), floor(p.y), floor(p.z) + local p = {x = x, y = y, z = z} + if get_node({x=x,y=y-1,z=z}).name ~= OBSIDIAN or get_node(p).name ~= PORTAL or get_node({x=x,y=y+1,z=z}).name ~= PORTAL then return end + local k = floor(z/256) * 256 + floor(x/256) + if not exits[k] then + exits[k]={} + end + local e = exits[k] + for i = 1, #e do + local t = e[i] + if t.x == p.x and t.y == p.y and t.z == p.z then + return + end + end + e[#e+1] = p + log("action", "[mcl_portals] Exit added at " .. pos_to_string(p)) +end + +-- This function removes Nether portals exits. +local function remove_exit(p) + if not p or not p.y or not p.z or not p.x then return end + local x, y, z = floor(p.x), floor(p.y), floor(p.z) + local k = floor(z/256) * 256 + floor(x/256) + if not exits[k] then return end + local p = {x = x, y = y, z = z} + local e = exits[k] + if e then + for i, t in pairs(e) do + if t and t.x == x and t.y == y and t.z == z then + e[i] = nil + log("action", "[mcl_portals] Nether portal removed from " .. pos_to_string(p)) + return + end + end + end +end + +-- This functon searches Nether portal nodes whitin distance specified +local function find_exit(p, dx, dy, dz) + if not p or not p.y or not p.z or not p.x then return end + local dx, dy, dz = dx or DISTANCE_MAX, dy or DISTANCE_MAX, dz or DISTANCE_MAX + if dx < 1 or dy < 1 or dz < 1 then return false end + local x, y, z = floor(p.x), floor(p.y), floor(p.z) + local x1, y1, z1, x2, y2, z2 = x-dx+1, y-dy+1, z-dz+1, x+dx-1, y+dy-1, z+dz-1 + local k1x, k2x = floor(x1/256), floor(x2/256) + local k1z, k2z = floor(z1/256), floor(z2/256) + + local t, d + for kx = k1x, k2x do for kz = k1z, k2z do + local k = kz*256 + kx + local e = exits[k] + if e then + for _, t0 in pairs(e) do + local d0 = dist(p, t0) + if not d or d>d0 then + d = d0 + t = t0 + if d==0 then return t end + end + end + end + end end + + if t and abs(t.x-p.x) <= dx and abs(t.y-p.y) <= dy and abs(t.z-p.z) <= dz then + return t + end +end --- Functions +-- Ping-Pong the coordinate for Fast Travelling, https://git.minetest.land/Wuzzy/MineClone2/issues/795#issuecomment-11058 +local function ping_pong(x, m, l1, l2) + if x < 0 then + return l1 + abs(((x*m+l1) % (l1*4)) - (l1*2)), floor(x*m/l1/2) + ((ceil(x*m/l1)+1)%2) * ((x*m)%l1)/l1 + end + return l2 - abs(((x*m+l2) % (l2*4)) - (l2*2)), floor(x*m/l2/2) + (floor(x*m/l2)%2) * ((x*m)%l2)/l2 +end --- Ping-Pong fast travel, https://git.minetest.land/Wuzzy/MineClone2/issues/795#issuecomment-11058 -local function nether_to_overworld(x) - return LIMIT - math.abs(((x * OVERWORLD_TO_NETHER_SCALE + LIMIT) % (LIMIT*4)) - (LIMIT*2)) +local function get_target(p) + if p and p.y and p.x and p.z then + local x, z = p.x, p.z + local y, d = mcl_worlds.y_to_layer(p.y) + local o1, o2 -- y offset + if y then + if d=="nether" then + x, o1 = ping_pong(x, TRAVEL_X, LIM_MIN, LIM_MAX) + z, o2 = ping_pong(z, TRAVEL_Z, LIM_MIN, LIM_MAX) + y = floor(y * TRAVEL_Y + (o1+o2) / 16 * LIM_MAX) + y = min(max(y + mcl_vars.mg_overworld_min, mcl_vars.mg_overworld_min), mcl_vars.mg_overworld_max) + elseif d=="overworld" then + x, y, z = floor(x / TRAVEL_X + 0.5), floor(y / TRAVEL_Y + 0.5), floor(z / TRAVEL_Z + 0.5) + y = min(max(y + mcl_vars.mg_nether_min, mcl_vars.mg_nether_min), mcl_vars.mg_nether_max) + end + return {x=x, y=y, z=z}, d + end + end end -- Destroy portal if pos (portal frame or portal node) got destroyed -local function destroy_nether_portal(pos) - local meta = minetest.get_meta(pos) - local node = minetest.get_node(pos) +local function destroy_nether_portal(pos, node) + if not node then return end local nn, orientation = node.name, node.param2 - local obsidian = nn == "mcl_core:obsidian" + local obsidian = nn == OBSIDIAN - local has_meta = minetest.string_to_pos(meta:get_string("portal_frame1")) - if has_meta then - meta:set_string("portal_frame1", "") - meta:set_string("portal_frame2", "") - meta:set_string("portal_target", "") - meta:set_string("portal_time", "") - end + local get_node = mcl_portals.get_node local check_remove = function(pos, orientation) - local node = minetest.get_node(pos) - if node and (node.name == "mcl_portals:portal" and (orientation == nil or (node.param2 == orientation))) then - minetest.log("action", "[mcl_portal] Destroying Nether portal at " .. minetest.pos_to_string(pos)) - return minetest.remove_node(pos) + local node = get_node(pos) + if node and (node.name == PORTAL and (orientation == nil or (node.param2 == orientation))) then + minetest.remove_node(pos) + remove_exit(pos) end end if obsidian then -- check each of 6 sides of it and destroy every portal: @@ -89,9 +219,6 @@ local function destroy_nether_portal(pos) check_remove({x = pos.x, y = pos.y + 1, z = pos.z}) return end - if not has_meta then -- no meta means repeated call: function calls on every node destruction - return - end if orientation == 0 then check_remove({x = pos.x - 1, y = pos.y, z = pos.z}, 0) check_remove({x = pos.x + 1, y = pos.y, z = pos.z}, 0) @@ -103,7 +230,7 @@ local function destroy_nether_portal(pos) check_remove({x = pos.x, y = pos.y + 1, z = pos.z}) end -minetest.register_node("mcl_portals:portal", { +minetest.register_node(PORTAL, { description = S("Nether Portal"), _doc_items_longdesc = S("A Nether portal teleports creatures and objects to the hot and dangerous Nether dimension (and back!). Enter at your own risk!"), _doc_items_usagehelp = S("Stand in the portal for a moment to activate the teleportation. Entering a Nether portal for the first time will also create a new portal in the other dimension. If a Nether portal has been built in the Nether, it will lead to the Overworld. A Nether portal is destroyed if the any of the obsidian which surrounds it is destroyed, or if it was caught in an explosion."), @@ -143,7 +270,7 @@ minetest.register_node("mcl_portals:portal", { drop = "", light_source = 11, post_effect_color = {a = 180, r = 51, g = 7, b = 89}, - alpha = PORTAL_ALPHA, + alpha = ALPHA, node_box = { type = "fixed", fixed = { @@ -152,398 +279,269 @@ minetest.register_node("mcl_portals:portal", { }, groups = { creative_breakable = 1, portal = 1, not_in_creative_inventory = 1 }, sounds = mcl_sounds.node_sound_glass_defaults(), - on_destruct = destroy_nether_portal, + after_destruct = destroy_nether_portal, _mcl_hardness = -1, _mcl_blast_resistance = 0, }) -local function find_target_y(x, y, z, y_min, y_max) - local y_org = math.max(math.min(y, y_max), y_min) - local node = minetest.get_node_or_nil({x = x, y = y, z = z}) - if node == nil then - return y_org +local function light_frame(x1, y1, z1, x2, y2, z2, name) + local orientation = 0 + if x1 == x2 then + orientation = 1 end - while node.name ~= "air" and y < y_max do - y = y + 1 - node = minetest.get_node_or_nil({x = x, y = y, z = z}) - if node == nil then - break - end - end - if node then - if node.name ~= "air" then - y = y_org - end - end - while node == nil and y > y_min do - y = y - 1 - node = minetest.get_node_or_nil({x = x, y = y, z = z}) - end - if y == y_max and node ~= nil then -- try reverse direction who knows what they built there... - while node.name ~= "air" and y > y_min do - y = y - 1 - node = minetest.get_node_or_nil({x = x, y = y, z = z}) - if node == nil then - break - end - end - end - if node == nil then - return y_org - end - while node.name == "air" and y > y_min do - y = y - 1 - node = minetest.get_node_or_nil({x = x, y = y, z = z}) - while node == nil and y > y_min do - y = y - 1 - node = minetest.get_node_or_nil({x = x, y = y, z = z}) - end - if node == nil then - return y_org - end - end - if y == y_min then - return y_org - end - return math.max(math.min(y, y_max), y_min) -end - -local function find_nether_target_y(x, y, z) - local target_y = find_target_y(x, y, z, nether_ymin + 4, nether_ymax - 25) + 1 - minetest.log("verbose", "[mcl_portal] Found Nether target altitude: " .. tostring(target_y) .. " for pos. " .. minetest.pos_to_string({x = x, y = y, z = z})) - return target_y -end - -local function find_overworld_target_y(x, y, z) - local target_y = find_target_y(x, y, z, overworld_ymin + 4, overworld_ymax - 25) + 1 - local node = minetest.get_node({x = x, y = target_y - 1, z = z}) - if not node then - return target_y - end - local nn = node.name - if nn ~= "air" and minetest.get_item_group(nn, "water") == 0 then - target_y = target_y + 1 - end - minetest.log("verbose", "[mcl_portal] Found Overworld target altitude: " .. tostring(target_y) .. " for pos. " .. minetest.pos_to_string({x = x, y = y, z = z})) - return target_y -end - - -local function update_target(pos, target, time_str) - local stack = {{x = pos.x, y = pos.y, z = pos.z}} - while #stack > 0 do - local i = #stack - local meta = minetest.get_meta(stack[i]) - if meta:get_string("portal_time") == time_str then - stack[i] = nil -- Already updated, skip it - else - local node = minetest.get_node(stack[i]) - local portal = node.name == "mcl_portals:portal" - if not portal then - stack[i] = nil - else - local x, y, z = stack[i].x, stack[i].y, stack[i].z - meta:set_string("portal_time", time_str) - meta:set_string("portal_target", target) - stack[i].y = y - 1 - stack[i + 1] = {x = x, y = y + 1, z = z} - if node.param2 == 0 then - stack[i + 2] = {x = x - 1, y = y, z = z} - stack[i + 3] = {x = x + 1, y = y, z = z} + local pos = {} + for x = x1 - 1 + orientation, x2 + 1 - orientation do + pos.x = x + for z = z1 - orientation, z2 + orientation do + pos.z = z + for y = y1 - 1, y2 + 1 do + pos.y = y + local frame = (x < x1) or (x > x2) or (y < y1) or (y > y2) or (z < z1) or (z > z2) + if frame then + set_node(pos, {name = OBSIDIAN}) else - stack[i + 2] = {x = x, y = y, z = z - 1} - stack[i + 3] = {x = x, y = y, z = z + 1} + set_node(pos, {name = PORTAL, param2 = orientation}) + add_exit({x=pos.x, y=pos.y-1, z=pos.z}) end end end end end -local function ecb_setup_target_portal(blockpos, action, calls_remaining, param) - -- param.: srcx, srcy, srcz, dstx, dsty, dstz, srcdim, ax1, ay1, az1, ax2, ay2, az2 +--Build arrival portal +function build_nether_portal(pos, width, height, orientation, name) + local width, height, orientation = width or W_MIN - 2, height or H_MIN - 2, orientation or random(0, 1) - local portal_search = function(target, p1, p2) - local portal_nodes = minetest.find_nodes_in_area(p1, p2, "mcl_portals:portal") - local portal_pos = false - if portal_nodes and #portal_nodes > 0 then - -- Found some portal(s), use nearest: - portal_pos = {x = portal_nodes[1].x, y = portal_nodes[1].y, z = portal_nodes[1].z} - local nearest_distance = vector.distance(target, portal_pos) - for n = 2, #portal_nodes do - local distance = vector.distance(target, portal_nodes[n]) - if distance < nearest_distance then - portal_pos = {x = portal_nodes[n].x, y = portal_nodes[n].y, z = portal_nodes[n].z} - nearest_distance = distance - end - end - end -- here we have the best portal_pos - return portal_pos - end + light_frame(pos.x, pos.y, pos.z, pos.x + (1 - orientation) * (width - 1), pos.y + height - 1, pos.z + orientation * (width - 1)) - if calls_remaining <= 0 then - minetest.log("action", "[mcl_portal] Area for destination Nether portal emerged!") - local src_pos = {x = param.srcx, y = param.srcy, z = param.srcz} - local dst_pos = {x = param.dstx, y = param.dsty, z = param.dstz} - local meta = minetest.get_meta(src_pos) - local portal_pos = portal_search(dst_pos, {x = param.ax1, y = param.ay1, z = param.az1}, {x = param.ax2, y = param.ay2, z = param.az2}) + local get_node = mcl_portals.get_node - if portal_pos == false then - minetest.log("verbose", "[mcl_portal] No portal in area " .. minetest.pos_to_string({x = param.ax1, y = param.ay1, z = param.az1}) .. "-" .. minetest.pos_to_string({x = param.ax2, y = param.ay2, z = param.az2})) - -- Need to build arrival portal: - local org_dst_y = dst_pos.y - if param.srcdim == "overworld" then - dst_pos.y = find_nether_target_y(dst_pos.x, dst_pos.y, dst_pos.z) - else - dst_pos.y = find_overworld_target_y(dst_pos.x, dst_pos.y, dst_pos.z) - end - if math.abs(org_dst_y - dst_pos.y) >= PORTAL_SEARCH_ALTITUDE / 2 then - portal_pos = portal_search(dst_pos, - {x = dst_pos.x - PORTAL_SEARCH_HALF_CHUNK, y = math.floor(dst_pos.y - PORTAL_SEARCH_ALTITUDE / 2), z = dst_pos.z - PORTAL_SEARCH_HALF_CHUNK}, - {x = dst_pos.x + PORTAL_SEARCH_HALF_CHUNK, y = math.ceil(dst_pos.y + PORTAL_SEARCH_ALTITUDE / 2), z = dst_pos.z + PORTAL_SEARCH_HALF_CHUNK} - ) - end - if portal_pos == false then - minetest.log("verbose", "[mcl_portal] 2nd attempt: No portal in area " .. minetest.pos_to_string({x = dst_pos.x - PORTAL_SEARCH_HALF_CHUNK, y = math.floor(dst_pos.y - PORTAL_SEARCH_ALTITUDE / 2), z = dst_pos.z - PORTAL_SEARCH_HALF_CHUNK}) .. "-" .. minetest.pos_to_string({x = dst_pos.x + PORTAL_SEARCH_HALF_CHUNK, y = math.ceil(dst_pos.y + PORTAL_SEARCH_ALTITUDE / 2), z = dst_pos.z + PORTAL_SEARCH_HALF_CHUNK})) - local width, height = 2, 3 - portal_pos = mcl_portals.build_nether_portal(dst_pos, width, height) + -- Build obsidian platform: + for x = pos.x - orientation, pos.x + orientation + (width - 1) * (1 - orientation), 1 + orientation do + for z = pos.z - 1 + orientation, pos.z + 1 - orientation + (width - 1) * orientation, 2 - orientation do + local pp = {x = x, y = pos.y - 1, z = z} + local pp_1 = {x = x, y = pos.y - 2, z = z} + local nn = get_node(pp).name + local nn_1 = get_node(pp_1).name + if ((nn=="air" and nn_1 == "air") or not registered_nodes[nn].is_ground_content) and not is_protected(pp, name) then + set_node(pp, {name = OBSIDIAN}) end end + end - local target_meta = minetest.get_meta(portal_pos) - local p3 = minetest.string_to_pos(target_meta:get_string("portal_frame1")) - local p4 = minetest.string_to_pos(target_meta:get_string("portal_frame2")) - if p3 and p4 then - portal_pos = vector.divide(vector.add(p3, p4), 2.0) - portal_pos.y = math.min(p3.y, p4.y) - portal_pos = vector.round(portal_pos) - local node = minetest.get_node(portal_pos) - if node and node.name ~= "mcl_portals:portal" then - portal_pos = {x = p3.x, y = p3.y, z = p3.z} - if minetest.get_node(portal_pos).name == "mcl_core:obsidian" then - -- Old-version portal: - if p4.z == p3.z then - portal_pos = {x = p3.x + 1, y = p3.y + 1, z = p3.z} - else - portal_pos = {x = p3.x, y = p3.y + 1, z = p3.z + 1} + log("action", "[mcl_portals] Destination Nether portal generated at "..pos_to_string(pos).."!") + + return pos +end + +function mcl_portals.spawn_nether_portal(pos, rot, pr, name) + if not pos then return end + local o = 0 + if rot then + if rot == "270" or rot=="90" then + o = 1 + elseif rot == "random" then + o = random(0,1) + end + end + build_nether_portal(pos, nil, nil, o, name) +end + +-- Teleportation cooloff for some seconds, to prevent back-and-forth teleportation +local function stop_teleport_cooloff(o) + cooloff[o] = nil + chatter[o] = nil +end + +local function teleport_cooloff(obj) + cooloff[obj] = true + if obj:is_player() then + minetest.after(PLAYER_COOLOFF, stop_teleport_cooloff, obj) + else + minetest.after(MOB_COOLOFF, stop_teleport_cooloff, obj) + end +end + +local function finalize_teleport(obj, exit) + if not obj or not exit or not exit.x or not exit.y or not exit.z then return end + + local objpos = obj:get_pos() + if not objpos then return end + + local is_player = obj:is_player() + local name + if is_player then + name = obj:get_player_name() + end + local y, dim = mcl_worlds.y_to_layer(exit.y) + + + -- If player stands, player is at ca. something+0.5 which might cause precision problems, so we used ceil for objpos.y + objpos = {x = floor(objpos.x+0.5), y = ceil(objpos.y), z = floor(objpos.z+0.5)} + if mcl_portals.get_node(objpos).name ~= PORTAL then return end + + -- Enable teleportation cooloff for some seconds, to prevent back-and-forth teleportation + teleport_cooloff(obj) + + -- Teleport + obj:set_pos(exit) + + if is_player then + mcl_worlds.dimension_change(obj, dim) + minetest.sound_play("mcl_portals_teleport", {pos=exit, gain=0.5, max_hear_distance = 16}, true) + log("action", "[mcl_portals] player "..name.." teleported to Nether portal at "..pos_to_string(exit)..".") + else + log("action", "[mcl_portals] entity teleported to Nether portal at "..pos_to_string(exit)..".") + end +end + +local function create_portal_2(pos1, name, obj) + local orientation = 0 + local pos2 = {x = pos1.x + 3, y = pos1.y + 3, z = pos1.z + 3} + local nodes = find_nodes_in_area(pos1, pos2, {"air"}) + if #nodes == 64 then + orientation = random(0,1) + else + pos2.x = pos2.x - 1 + nodes = find_nodes_in_area(pos1, pos2, {"air"}) + if #nodes == 48 then + orientation = 1 + end + end + local exit = build_nether_portal(pos1, W_MIN-2, H_MIN-2, orientation, name) + finalize_teleport(obj, exit) + local cn = mcl_vars.get_chunk_number(pos1) + chunks[cn] = nil + if queue[cn] then + for next_obj, _ in pairs(queue[cn]) do + if next_obj ~= obj then + finalize_teleport(next_obj, exit) + end + end + queue[cn] = nil + end +end + +local function get_lava_level(pos, pos1, pos2) + if pos.y > -1000 then + return max(min(mcl_vars.mg_lava_overworld_max, pos2.y-1), pos1.y+1) + end + return max(min(mcl_vars.mg_lava_nether_max, pos2.y-1), pos1.y+1) +end + +local function ecb_scan_area_2(blockpos, action, calls_remaining, param) + if calls_remaining and calls_remaining > 0 then return end + local pos, pos1, pos2, name, obj = param.pos, param.pos1, param.pos2, param.name or "", param.obj + local pos0, distance + local lava = get_lava_level(pos, pos1, pos2) + + local nodes = find_nodes_in_area_under_air(pos1, pos2, {"group:building_block"}) + if nodes then + local nc = #nodes + if nc > 0 then + log("action", "[mcl_portals] Area for destination Nether portal emerged! Found " .. tostring(nc) .. " nodes under the air around "..pos_to_string(pos)) + for i=1,nc do + local node = nodes[i] + local node1 = {x=node.x, y=node.y+1, z=node.z } + local node2 = {x=node.x+2, y=node.y+3, z=node.z+2} + local nodes2 = find_nodes_in_area(node1, node2, {"air"}) + if nodes2 then + local nc2 = #nodes2 + log("action", "[mcl_portals] nc2=" .. tostring(nc2)) + if nc2 == 27 and not is_area_protected(node, node2, name) then + local distance0 = dist(pos, node) + if distance0 < 2 then + log("action", "[mcl_portals] found space at pos "..pos_to_string(node).." - creating a portal") + create_portal_2(node1, name, obj) + return + end + if not distance or (distance0 < distance) or (distance0 < distance-1 and node.y > lava and pos0.y < lava) then + log("action", "[mcl_portals] found distance "..tostring(distance0).." at pos "..pos_to_string(node)) + distance = distance0 + pos0 = {x=node1.x, y=node1.y, z=node1.z} + end end end end end - local time_str = tostring(minetest.get_us_time()) - local target = minetest.pos_to_string(portal_pos) - - update_target(src_pos, target, time_str) end -end - -local function nether_portal_get_target_position(src_pos) - local _, current_dimension = mcl_worlds.y_to_layer(src_pos.y) - local x, y, z, y_min, y_max = 0, 0, 0, 0, 0 - if current_dimension == "nether" then - x = math.floor(nether_to_overworld(src_pos.x) + 0.5) - z = math.floor(nether_to_overworld(src_pos.z) + 0.5) - y = math.floor((math.min(math.max(src_pos.y, nether_ymin), nether_ymax) - nether_ymin) / nether_dy * overworld_dy + overworld_ymin + 0.5) - y_min = overworld_ymin - y_max = overworld_ymax - else -- overworld: - x = math.floor(src_pos.x / OVERWORLD_TO_NETHER_SCALE + 0.5) - z = math.floor(src_pos.z / OVERWORLD_TO_NETHER_SCALE + 0.5) - y = math.floor((math.min(math.max(src_pos.y, overworld_ymin), overworld_ymax) - overworld_ymin) / overworld_dy * nether_dy + nether_ymin + 0.5) - y_min = nether_ymin - y_max = nether_ymax + if distance then -- several nodes of air might be better than lava lake, right? + log("action", "[mcl_portals] using backup pos "..pos_to_string(pos0).." to create a portal") + create_portal_2(pos0, name, obj) + return end - return x, y, z, current_dimension, y_min, y_max -end - -local function find_or_create_portal(src_pos) - local x, y, z, cdim, y_min, y_max = nether_portal_get_target_position(src_pos) - local pos1 = {x = x - PORTAL_SEARCH_HALF_CHUNK, y = math.max(y_min, math.floor(y - PORTAL_SEARCH_ALTITUDE / 2)), z = z - PORTAL_SEARCH_HALF_CHUNK} - local pos2 = {x = x + PORTAL_SEARCH_HALF_CHUNK, y = math.min(y_max, math.ceil(y + PORTAL_SEARCH_ALTITUDE / 2)), z = z + PORTAL_SEARCH_HALF_CHUNK} - if pos1.y == y_min then - pos2.y = math.min(y_max, pos1.y + PORTAL_SEARCH_ALTITUDE) + log("action", "[mcl_portals] found no space, reverting to target pos "..pos_to_string(pos).." - creating a portal") + if pos.y < lava then + pos.y = lava + 1 else - if pos2.y == y_max then - pos1.y = math.max(y_min, pos2.y - PORTAL_SEARCH_ALTITUDE) - end + pos.y = pos.y + 1 end - minetest.emerge_area(pos1, pos2, ecb_setup_target_portal, {srcx=src_pos.x, srcy=src_pos.y, srcz=src_pos.z, dstx=x, dsty=y, dstz=z, srcdim=cdim, ax1=pos1.x, ay1=pos1.y, az1=pos1.z, ax2=pos2.x, ay2=pos2.y, az2=pos2.z}) + create_portal_2(pos, name, obj) end -local function emerge_target_area(src_pos) - local x, y, z, cdim, y_min, y_max = nether_portal_get_target_position(src_pos) - local pos1 = {x = x - PORTAL_SEARCH_HALF_CHUNK, y = math.max(y_min + 2, math.floor(y - PORTAL_SEARCH_ALTITUDE / 2)), z = z - PORTAL_SEARCH_HALF_CHUNK} - local pos2 = {x = x + PORTAL_SEARCH_HALF_CHUNK, y = math.min(y_max - 2, math.ceil(y + PORTAL_SEARCH_ALTITUDE / 2)), z = z + PORTAL_SEARCH_HALF_CHUNK} - minetest.emerge_area(pos1, pos2) - pos1 = {x = x - 1, y = y_min, z = z - 1} - pos2 = {x = x + 1, y = y_max, z = z + 1} - minetest.emerge_area(pos1, pos2) +local function create_portal(pos, limit1, limit2, name, obj) + local cn = mcl_vars.get_chunk_number(pos) + if chunks[cn] then + local q = queue[cn] or {} + q[obj] = true + queue[cn] = q + return + end + chunks[cn] = true + + -- we need to emerge the area here, but currently (mt5.4/mcl20.71) map generation is slow + -- so we'll emerge single chunk only: 5x5x5 blocks, 80x80x80 nodes maximum + + local pos1 = add(mul(mcl_vars.pos_to_chunk(pos), mcl_vars.chunk_size_in_nodes), mcl_vars.central_chunk_offset_in_nodes) + local pos2 = add(pos1, mcl_vars.chunk_size_in_nodes - 1) + + if limit1 and limit1.x and limit1.y and limit1.z then + pos1 = {x = max(min(limit1.x, pos.x), pos1.x), y = max(min(limit1.y, pos.y), pos1.y), z = max(min(limit1.z, pos.z), pos1.z)} + end + if limit2 and limit2.x and limit2.y and limit2.z then + pos2 = {x = min(max(limit2.x, pos.x), pos2.x), y = min(max(limit2.y, pos.y), pos2.y), z = min(max(limit2.z, pos.z), pos2.z)} + end + + minetest.emerge_area(pos1, pos2, ecb_scan_area_2, {pos = vector.new(pos), pos1 = pos1, pos2 = pos2, name=name, obj=obj}) end local function available_for_nether_portal(p) - local nn = minetest.get_node(p).name - local obsidian = nn == "mcl_core:obsidian" + local nn = mcl_portals.get_node(p).name + local obsidian = nn == OBSIDIAN if nn ~= "air" and minetest.get_item_group(nn, "fire") ~= 1 then return false, obsidian end return true, obsidian end -local function light_frame(x1, y1, z1, x2, y2, z2, build_frame) - local build_frame = build_frame or false - local orientation = 0 - if x1 == x2 then - orientation = 1 - end - local disperse = 50 - local pass = 1 - while true do - local protection = false - - for x = x1 - 1 + orientation, x2 + 1 - orientation do - for z = z1 - orientation, z2 + orientation do - for y = y1 - 1, y2 + 1 do - local frame = (x < x1) or (x > x2) or (y < y1) or (y > y2) or (z < z1) or (z > z2) - if frame then - if build_frame then - if pass == 1 then - if minetest.is_protected({x = x, y = y, z = z}, "") then - protection = true - local offset_x = math.random(-disperse, disperse) - local offset_z = math.random(-disperse, disperse) - disperse = disperse + math.random(25, 177) - if disperse > 5000 then - return nil - end - x1, z1 = x1 + offset_x, z1 + offset_z - x2, z2 = x2 + offset_x, z2 + offset_z - local _, dimension = mcl_worlds.y_to_layer(y1) - local height = math.abs(y2 - y1) - y1 = (y1 + y2) / 2 - if dimension == "nether" then - y1 = find_nether_target_y(math.min(x1, x2), y1, math.min(z1, z2)) - else - y1 = find_overworld_target_y(math.min(x1, x2), y1, math.min(z1, z2)) - end - y2 = y1 + height - break - end - else - minetest.set_node({x = x, y = y, z = z}, {name = "mcl_core:obsidian"}) - end - end - else - if not build_frame or pass == 2 then - local node = minetest.get_node({x = x, y = y, z = z}) - minetest.set_node({x = x, y = y, z = z}, {name = "mcl_portals:portal", param2 = orientation}) - end - end - if not frame and pass == 2 then - local meta = minetest.get_meta({x = x, y = y, z = z}) - -- Portal frame corners - meta:set_string("portal_frame1", minetest.pos_to_string({x = x1, y = y1, z = z1})) - meta:set_string("portal_frame2", minetest.pos_to_string({x = x2, y = y2, z = z2})) - -- Portal target coordinates - meta:set_string("portal_target", "") - -- Portal last teleportation time - meta:set_string("portal_time", tostring(0)) - end - end - if protection then - break - end - end - if protection then - break - end - end - if build_frame == false or pass == 2 then - break - end - if build_frame and not protection and pass == 1 then - pass = 2 - end - end - emerge_target_area({x = x1, y = y1, z = z1}) - return {x = x1, y = y1, z = z1} -end - ---Build arrival portal -function mcl_portals.build_nether_portal(pos, width, height, orientation) - local height = height or FRAME_SIZE_Y_MIN - 2 - local width = width or FRAME_SIZE_X_MIN - 2 - local orientation = orientation or math.random(0, 1) - - if orientation == 0 then - minetest.load_area({x = pos.x - 3, y = pos.y - 1, z = pos.z - width * 2}, {x = pos.x + width + 2, y = pos.y + height + 2, z = pos.z + width * 2}) - else - minetest.load_area({x = pos.x - width * 2, y = pos.y - 1, z = pos.z - 3}, {x = pos.x + width * 2, y = pos.y + height + 2, z = pos.z + width + 2}) - end - - pos = light_frame(pos.x, pos.y, pos.z, pos.x + (1 - orientation) * (width - 1), pos.y + height - 1, pos.z + orientation * (width - 1), true) - - -- Clear some space around: - for x = pos.x - math.random(2 + (width-2)*( orientation), 5 + (2*width-5)*( orientation)), pos.x + width*(1-orientation) + math.random(2+(width-2)*( orientation), 4 + (2*width-4)*( orientation)) do - for z = pos.z - math.random(2 + (width-2)*(1-orientation), 5 + (2*width-5)*(1-orientation)), pos.z + width*( orientation) + math.random(2+(width-2)*(1-orientation), 4 + (2*width-4)*(1-orientation)) do - for y = pos.y - 1, pos.y + height + math.random(1,6) do - local nn = minetest.get_node({x = x, y = y, z = z}).name - if nn ~= "mcl_core:obsidian" and nn ~= "mcl_portals:portal" and minetest.registered_nodes[nn].is_ground_content and not minetest.is_protected({x = x, y = y, z = z}, "") then - minetest.remove_node({x = x, y = y, z = z}) - end - end - end - end - - -- Build obsidian platform: - for x = pos.x - orientation, pos.x + orientation + (width - 1) * (1 - orientation), 1 + orientation do - for z = pos.z - 1 + orientation, pos.z + 1 - orientation + (width - 1) * orientation, 2 - orientation do - local pp = {x = x, y = pos.y - 1, z = z} - local nn = minetest.get_node(pp).name - if not minetest.registered_nodes[nn].is_ground_content and not minetest.is_protected(pp, "") then - minetest.set_node(pp, {name = "mcl_core:obsidian"}) - end - end - end - - minetest.log("action", "[mcl_portal] Destination Nether portal generated at "..minetest.pos_to_string(pos).."!") - - return pos -end - local function check_and_light_shape(pos, orientation) local stack = {{x = pos.x, y = pos.y, z = pos.z}} local node_list = {} + local index_list = {} local node_counter = 0 -- Search most low node from the left (pos1) and most right node from the top (pos2) local pos1 = {x = pos.x, y = pos.y, z = pos.z} local pos2 = {x = pos.x, y = pos.y, z = pos.z} - local wrong_portal_nodes_clean_up = function(node_list) - for i = 1, #node_list do - local meta = minetest.get_meta(node_list[i]) - meta:set_string("portal_time", "") - end - return false - end - + local kx, ky, kz = pos.x - 1999, pos.y - 1999, pos.z - 1999 while #stack > 0 do local i = #stack - local meta = minetest.get_meta(stack[i]) - local target = meta:get_string("portal_time") - if target and target == "-2" then + local x, y, z = stack[i].x, stack[i].y, stack[i].z + local k = (x-kx)*16000000 + (y-ky)*4000 + z-kz + if index_list[k] then stack[i] = nil -- Already checked, skip it else local good, obsidian = available_for_nether_portal(stack[i]) if obsidian then stack[i] = nil else - if (not good) or (node_counter >= PORTAL_NODES_MAX) then - return wrong_portal_nodes_clean_up(node_list) + if (not good) or (node_counter >= N_MAX) then + return false end - local x, y, z = stack[i].x, stack[i].y, stack[i].z - meta:set_string("portal_time", "-2") node_counter = node_counter + 1 node_list[node_counter] = {x = x, y = y, z = z} + index_list[k] = true stack[i].y = y - 1 stack[i + 1] = {x = x, y = y + 1, z = z} if orientation == 0 then @@ -563,24 +561,19 @@ local function check_and_light_shape(pos, orientation) end end - if node_counter < PORTAL_NODES_MIN then - return wrong_portal_nodes_clean_up(node_list) + if node_counter < N_MIN then + return false end -- Limit rectangles width and height - if math.abs(pos2.x - pos1.x + pos2.z - pos1.z) + 3 > FRAME_SIZE_X_MAX or math.abs(pos2.y - pos1.y) + 3 > FRAME_SIZE_Y_MAX then - return wrong_portal_nodes_clean_up(node_list) + if abs(pos2.x - pos1.x + pos2.z - pos1.z) + 3 > W_MAX or abs(pos2.y - pos1.y) + 3 > H_MAX then + return false end for i = 1, node_counter do local node_pos = node_list[i] - local node = minetest.get_node(node_pos) - minetest.set_node(node_pos, {name = "mcl_portals:portal", param2 = orientation}) - local meta = minetest.get_meta(node_pos) - meta:set_string("portal_frame1", minetest.pos_to_string(pos1)) - meta:set_string("portal_frame2", minetest.pos_to_string(pos2)) - meta:set_string("portal_time", tostring(0)) - meta:set_string("portal_target", "") + minetest.set_node(node_pos, {name = PORTAL, param2 = orientation}) + add_exit(node_pos) end return true end @@ -596,7 +589,7 @@ function mcl_portals.light_nether_portal(pos) if dim ~= "overworld" and dim ~= "nether" then return false end - local orientation = math.random(0, 1) + local orientation = random(0, 1) for orientation_iteration = 1, 2 do if check_and_light_shape(pos, orientation) then return true @@ -606,126 +599,50 @@ function mcl_portals.light_nether_portal(pos) return false end -local function update_portal_time(pos, time_str) - local stack = {{x = pos.x, y = pos.y, z = pos.z}} - while #stack > 0 do - local i = #stack - local meta = minetest.get_meta(stack[i]) - if meta:get_string("portal_time") == time_str then - stack[i] = nil -- Already updated, skip it - else - local node = minetest.get_node(stack[i]) - local portal = node.name == "mcl_portals:portal" - if not portal then - stack[i] = nil - else - local x, y, z = stack[i].x, stack[i].y, stack[i].z - meta:set_string("portal_time", time_str) - stack[i].y = y - 1 - stack[i + 1] = {x = x, y = y + 1, z = z} - if node.param2 == 0 then - stack[i + 2] = {x = x - 1, y = y, z = z} - stack[i + 3] = {x = x + 1, y = y, z = z} - else - stack[i + 2] = {x = x, y = y, z = z - 1} - stack[i + 3] = {x = x, y = y, z = z + 1} - end - end - end - end -end - -local function prepare_target(pos) - local meta, us_time = minetest.get_meta(pos), minetest.get_us_time() - local portal_time = tonumber(meta:get_string("portal_time")) or 0 - local delta_time_us = us_time - portal_time - local pos1, pos2 = minetest.string_to_pos(meta:get_string("portal_frame1")), minetest.string_to_pos(meta:get_string("portal_frame2")) - if delta_time_us <= DESTINATION_EXPIRES then - -- Destination point must be still cached according to https://minecraft.gamepedia.com/Nether_portal - return update_portal_time(pos, tostring(us_time)) - end - -- No cached destination point - find_or_create_portal(pos) -end - --- Teleportation cooloff for some seconds, to prevent back-and-forth teleportation -local function stop_teleport_cooloff(o) - mcl_portals.nether_portal_cooloff[o] = false - touch_chatter_prevention[o] = nil -end - -local function teleport_cooloff(obj) - if obj:is_player() then - minetest.after(TELEPORT_COOLOFF, stop_teleport_cooloff, obj) - else - minetest.after(MOB_TELEPORT_COOLOFF, stop_teleport_cooloff, obj) - end -end - -- Teleport function local function teleport_no_delay(obj, pos) local is_player = obj:is_player() - if (not obj:get_luaentity()) and (not is_player) then - return - end + if (not is_player and not obj:get_luaentity()) or cooloff[obj] then return end local objpos = obj:get_pos() - if objpos == nil then - return - end + if not objpos then return end - if mcl_portals.nether_portal_cooloff[obj] then - return - end - -- If player stands, player is at ca. something+0.5 - -- which might cause precision problems, so we used ceil. - objpos.y = math.ceil(objpos.y) + -- If player stands, player is at ca. something+0.5 which might cause precision problems, so we used ceil for objpos.y + objpos = {x = floor(objpos.x+0.5), y = ceil(objpos.y), z = floor(objpos.z+0.5)} + if mcl_portals.get_node(objpos).name ~= PORTAL then return end - if minetest.get_node(objpos).name ~= "mcl_portals:portal" then - return - end - - local meta = minetest.get_meta(pos) - local delta_time = minetest.get_us_time() - (tonumber(meta:get_string("portal_time")) or 0) - local target = minetest.string_to_pos(meta:get_string("portal_target")) - if delta_time > DESTINATION_EXPIRES or target == nil then - -- Area not ready yet - retry after a second - return minetest.after(1, teleport_no_delay, obj, pos) - end - - -- Enable teleportation cooloff for some seconds, to prevent back-and-forth teleportation - teleport_cooloff(obj) - mcl_portals.nether_portal_cooloff[obj] = true - - -- Teleport - obj:set_pos(target) + local target, dim = get_target(objpos) + if not target then return end + local name if is_player then - mcl_worlds.dimension_change(obj, mcl_worlds.pos_to_dimension(target)) - minetest.sound_play("mcl_portals_teleport", {pos=target, gain=0.5, max_hear_distance = 16}, true) - local name = obj:get_player_name() - minetest.log("action", "[mcl_portal] "..name.." teleported to Nether portal at "..minetest.pos_to_string(target)..".") + name = obj:get_player_name() + end + + local exit = find_exit(target) + if exit then + finalize_teleport(obj, exit) + else + -- need to create arrival portal + create_portal(target, limits[dim].pmin, limits[dim].pmax, name, obj) end end local function prevent_portal_chatter(obj) - local time_us = minetest.get_us_time() - local chatter = touch_chatter_prevention[obj] or 0 - touch_chatter_prevention[obj] = time_us + local time_us = get_us_time() + local ch = chatter[obj] or 0 + chatter[obj] = time_us minetest.after(TOUCH_CHATTER_TIME, function(o) - if not o or not touch_chatter_prevention[o] then - return - end - if minetest.get_us_time() - touch_chatter_prevention[o] >= TOUCH_CHATTER_TIME_US then - touch_chatter_prevention[o] = nil + if o and chatter[o] and get_us_time() - chatter[o] >= CHATTER_US then + chatter[o] = nil end end, obj) - return time_us - chatter > TOUCH_CHATTER_TIME_US + return time_us - ch > CHATTER_US end local function animation(player, playername) - local chatter = touch_chatter_prevention[player] or 0 - if mcl_portals.nether_portal_cooloff[player] or minetest.get_us_time() - chatter < TOUCH_CHATTER_TIME_US then + local ch = chatter[player] or 0 + if cooloff[player] or get_us_time() - ch < CHATTER_US then local pos = player:get_pos() if not pos then return @@ -756,36 +673,35 @@ local function teleport(obj, portal_pos) name = obj:get_player_name() animation(obj, name) end - -- Call prepare_target() first because it might take a long - prepare_target(portal_pos) - -- Prevent quick back-and-forth teleportation - if not mcl_portals.nether_portal_cooloff[obj] then - local creative_enabled = minetest.is_creative_enabled(name) - if creative_enabled then - return teleport_no_delay(obj, portal_pos) - end - minetest.after(TELEPORT_DELAY, teleport_no_delay, obj, portal_pos) + + if cooloff[obj] then return end + + if minetest.is_creative_enabled(name) then + teleport_no_delay(obj, portal_pos) + return end + + minetest.after(DELAY, teleport_no_delay, obj, portal_pos) end minetest.register_abm({ label = "Nether portal teleportation and particles", - nodenames = {"mcl_portals:portal"}, + nodenames = {PORTAL}, interval = 1, chance = 1, action = function(pos, node) local o = node.param2 -- orientation - local d = math.random(0, 1) -- direction - local time = math.random() * 1.9 + 0.5 + local d = random(0, 1) -- direction + local time = random() * 1.9 + 0.5 local velocity, acceleration if o == 1 then - velocity = {x = math.random() * 0.7 + 0.3, y = math.random() - 0.5, z = math.random() - 0.5} - acceleration = {x = math.random() * 1.1 + 0.3, y = math.random() - 0.5, z = math.random() - 0.5} + velocity = {x = random() * 0.7 + 0.3, y = random() - 0.5, z = random() - 0.5} + acceleration = {x = random() * 1.1 + 0.3, y = random() - 0.5, z = random() - 0.5} else - velocity = {x = math.random() - 0.5, y = math.random() - 0.5, z = math.random() * 0.7 + 0.3} - acceleration = {x = math.random() - 0.5, y = math.random() - 0.5, z = math.random() * 1.1 + 0.3} + velocity = {x = random() - 0.5, y = random() - 0.5, z = random() * 0.7 + 0.3} + acceleration = {x = random() - 0.5, y = random() - 0.5, z = random() * 1.1 + 0.3} end - local distance = vector.add(vector.multiply(velocity, time), vector.multiply(acceleration, time * time / 2)) + local distance = add(mul(velocity, time), mul(acceleration, time * time / 2)) if d == 1 then if o == 1 then distance.x = -distance.x @@ -797,11 +713,11 @@ minetest.register_abm({ acceleration.z = -acceleration.z end end - distance = vector.subtract(pos, distance) + distance = sub(pos, distance) for _, obj in pairs(minetest.get_objects_inside_radius(pos, 15)) do if obj:is_player() then minetest.add_particlespawner({ - amount = node_particles_allowed_level + 1, + amount = PARTICLES + 1, minpos = distance, maxpos = distance, minvel = velocity, @@ -830,14 +746,14 @@ minetest.register_abm({ --[[ ITEM OVERRIDES ]] -local longdesc = minetest.registered_nodes["mcl_core:obsidian"]._doc_items_longdesc +local longdesc = registered_nodes[OBSIDIAN]._doc_items_longdesc longdesc = longdesc .. "\n" .. S("Obsidian is also used as the frame of Nether portals.") local usagehelp = S("To open a Nether portal, place an upright frame of obsidian with a width of at least 4 blocks and a height of 5 blocks, leaving only air in the center. After placing this frame, light a fire in the obsidian frame. Nether portals only work in the Overworld and the Nether.") -minetest.override_item("mcl_core:obsidian", { +minetest.override_item(OBSIDIAN, { _doc_items_longdesc = longdesc, _doc_items_usagehelp = usagehelp, - on_destruct = destroy_nether_portal, + after_destruct = destroy_nether_portal, _on_ignite = function(user, pointed_thing) local x, y, z = pointed_thing.under.x, pointed_thing.under.y, pointed_thing.under.z -- Check empty spaces around obsidian and light all frames found: @@ -846,9 +762,9 @@ minetest.override_item("mcl_core:obsidian", { mcl_portals.light_nether_portal({x = x, y = y - 1, z = z}) or mcl_portals.light_nether_portal({x = x, y = y + 1, z = z}) or mcl_portals.light_nether_portal({x = x, y = y, z = z - 1}) or mcl_portals.light_nether_portal({x = x, y = y, z = z + 1}) if portals_placed then - minetest.log("action", "[mcl_portal] Nether portal activated at "..minetest.pos_to_string({x=x,y=y,z=z})..".") + log("action", "[mcl_portals] Nether portal activated at "..pos_to_string({x=x,y=y,z=z})..".") if minetest.get_modpath("doc") then - doc.mark_entry_as_revealed(user:get_player_name(), "nodes", "mcl_portals:portal") + doc.mark_entry_as_revealed(user:get_player_name(), "nodes", PORTAL) -- Achievement for finishing a Nether portal TO the Nether local dim = mcl_worlds.pos_to_dimension({x=x, y=y, z=z}) diff --git a/mods/ITEMS/mcl_signs/depends.txt b/mods/ITEMS/mcl_signs/depends.txt deleted file mode 100644 index f123382f8..000000000 --- a/mods/ITEMS/mcl_signs/depends.txt +++ /dev/null @@ -1,3 +0,0 @@ -mcl_sounds? -mcl_core? -doc? diff --git a/mods/ITEMS/mcl_signs/mod.conf b/mods/ITEMS/mcl_signs/mod.conf index 8346bbcb4..1af689d7b 100644 --- a/mods/ITEMS/mcl_signs/mod.conf +++ b/mods/ITEMS/mcl_signs/mod.conf @@ -1 +1,2 @@ name = mcl_signs +optional_depends = mcl_sounds, mcl_core, doc diff --git a/mods/ITEMS/mcl_sponges/depends.txt b/mods/ITEMS/mcl_sponges/depends.txt deleted file mode 100644 index 10e9d2909..000000000 --- a/mods/ITEMS/mcl_sponges/depends.txt +++ /dev/null @@ -1,3 +0,0 @@ -mcl_sounds -mcl_core? -mclx_core? diff --git a/mods/ITEMS/mcl_sponges/description.txt b/mods/ITEMS/mcl_sponges/description.txt deleted file mode 100644 index 80f47c25f..000000000 --- a/mods/ITEMS/mcl_sponges/description.txt +++ /dev/null @@ -1 +0,0 @@ -A sponge which sucks in water (WIP). diff --git a/mods/ITEMS/mcl_sponges/init.lua b/mods/ITEMS/mcl_sponges/init.lua index 4a2107f88..b832c01c6 100644 --- a/mods/ITEMS/mcl_sponges/init.lua +++ b/mods/ITEMS/mcl_sponges/init.lua @@ -48,7 +48,7 @@ minetest.register_node("mcl_sponges:sponge", { buildable_to = false, stack_max = 64, sounds = mcl_sounds.node_sound_dirt_defaults(), - groups = {handy=1, building_block=1}, + groups = {handy=1, hoey=1, building_block=1}, on_place = function(itemstack, placer, pointed_thing) local pn = placer:get_player_name() if pointed_thing.type ~= "node" then @@ -107,7 +107,7 @@ minetest.register_node("mcl_sponges:sponge_wet", { buildable_to = false, stack_max = 64, sounds = mcl_sounds.node_sound_dirt_defaults(), - groups = {handy=1, building_block=1}, + groups = {handy=1, hoey=1, building_block=1}, _mcl_blast_resistance = 0.6, _mcl_hardness = 0.6, }) diff --git a/mods/ITEMS/mcl_sponges/mod.conf b/mods/ITEMS/mcl_sponges/mod.conf index 71a459c10..d833493b3 100644 --- a/mods/ITEMS/mcl_sponges/mod.conf +++ b/mods/ITEMS/mcl_sponges/mod.conf @@ -1 +1,4 @@ name = mcl_sponges +description = A sponge which sucks in water (WIP). +depends = mcl_sounds +optional_depends = mcl_core, mclx_core diff --git a/mods/ITEMS/mcl_stairs/depends.txt b/mods/ITEMS/mcl_stairs/depends.txt deleted file mode 100644 index 96e184bd9..000000000 --- a/mods/ITEMS/mcl_stairs/depends.txt +++ /dev/null @@ -1,5 +0,0 @@ -mcl_core -mcl_sounds -mcl_nether -mcl_end -mcl_ocean diff --git a/mods/ITEMS/mcl_stairs/mod.conf b/mods/ITEMS/mcl_stairs/mod.conf index 4540a7981..a357c2c79 100644 --- a/mods/ITEMS/mcl_stairs/mod.conf +++ b/mods/ITEMS/mcl_stairs/mod.conf @@ -1 +1,2 @@ name = mcl_stairs +depends = mcl_core, mcl_sounds, mcl_nether, mcl_end, mcl_ocean diff --git a/mods/ITEMS/mcl_throwing/depends.txt b/mods/ITEMS/mcl_throwing/depends.txt deleted file mode 100644 index 2787220ee..000000000 --- a/mods/ITEMS/mcl_throwing/depends.txt +++ /dev/null @@ -1,4 +0,0 @@ -mcl_core? -mcl_mobitems? -doc? -mcl_fishing diff --git a/mods/ITEMS/mcl_throwing/mod.conf b/mods/ITEMS/mcl_throwing/mod.conf index 117ca80a7..4bfc2efb5 100644 --- a/mods/ITEMS/mcl_throwing/mod.conf +++ b/mods/ITEMS/mcl_throwing/mod.conf @@ -1 +1,3 @@ name = mcl_throwing +depends = mcl_fishing +optional_depends = mcl_core, mcl_mobitems, doc diff --git a/mods/ITEMS/mcl_tnt/depends.txt b/mods/ITEMS/mcl_tnt/depends.txt deleted file mode 100644 index 6a2354764..000000000 --- a/mods/ITEMS/mcl_tnt/depends.txt +++ /dev/null @@ -1,7 +0,0 @@ -mcl_explosions -mcl_particles -mcl_sounds? -mcl_mobitems? -mcl_death_messages? -doc_identifier? -mesecons? diff --git a/mods/ITEMS/mcl_tnt/mod.conf b/mods/ITEMS/mcl_tnt/mod.conf index 96d4584cf..9d75a788c 100644 --- a/mods/ITEMS/mcl_tnt/mod.conf +++ b/mods/ITEMS/mcl_tnt/mod.conf @@ -1 +1,3 @@ name = mcl_tnt +depends = mcl_explosions, mcl_particles +optional_depends = mcl_sounds, mcl_mobitems, mcl_death_messages, doc_identifier, mesecons diff --git a/mods/ITEMS/mcl_tools/depends.txt b/mods/ITEMS/mcl_tools/depends.txt deleted file mode 100644 index 5ce101eda..000000000 --- a/mods/ITEMS/mcl_tools/depends.txt +++ /dev/null @@ -1,2 +0,0 @@ -mcl_sounds -_mcl_autogroup diff --git a/mods/ITEMS/mcl_tools/init.lua b/mods/ITEMS/mcl_tools/init.lua index d40b8e01b..bc6bed09f 100644 --- a/mods/ITEMS/mcl_tools/init.lua +++ b/mods/ITEMS/mcl_tools/init.lua @@ -6,14 +6,7 @@ local S = minetest.get_translator("mcl_tools") -- Tool definition -- ---[[ Maximum drop level definitions: -- 0: Hand -- 1: Wood / Shears -- 2: Gold -- 3: Stone -- 4: Iron -- 5: Diamond - +--[[ dig_speed_class group: - 1: Painfully slow - 2: Very slow @@ -26,25 +19,18 @@ dig_speed_class group: -- The hand local groupcaps, hand_range, hand_groups + if minetest.is_creative_enabled("") then -- Instant breaking in creative mode - groupcaps = { - creative_breakable = {times={[1]=0}, uses=0}, - } - -- mcl_autogroup provides the creative digging times for all digging groups - for k,v in pairs(mcl_autogroup.creativetimes) do - groupcaps[k] = { times = v, uses = 0 } - end + groupcaps = { creative_breakable = { times = {0}, uses = 0 } } hand_range = 10 hand_groups = { dig_speed_class = 7 } else - groupcaps = { - handy_dig = {times=mcl_autogroup.digtimes.handy_dig, uses=0}, - } + groupcaps = {} hand_range = 4 hand_groups = { dig_speed_class = 1 } end -minetest.register_item(":", { +minetest.register_tool(":", { type = "none", _doc_items_longdesc = S("You use your bare hand whenever you are not wielding any item. With your hand you can mine most blocks, but this is the slowest method and only the weakest blocks will yield their useful drop. The hand also deals minor damage by punching. Using the hand is often a last resort, as proper mining tools and weapons are much better.").."\n".. S("When you are wielding an item which is not a mining tool or a weapon, it will behave as if it were the hand when you start mining or punching.").."\n".. @@ -61,6 +47,18 @@ minetest.register_item(":", { damage_groups = {fleshy=1}, }, groups = hand_groups, + _mcl_diggroups = { + handy = { speed = 1, level = 1, uses = 0 }, + axey = { speed = 1, level = 1, uses = 0 }, + shovely = { speed = 1, level = 1, uses = 0 }, + hoey = { speed = 1, level = 1, uses = 0 }, + pickaxey = { speed = 1, level = 0, uses = 0 }, + swordy = { speed = 1, level = 0, uses = 0 }, + swordy_cobweb = { speed = 1, level = 0, uses = 0 }, + shearsy = { speed = 1, level = 0, uses = 0 }, + shearsy_wool = { speed = 1, level = 0, uses = 0 }, + shearsy_cobweb = { speed = 1, level = 0, uses = 0 }, + } }) -- Help texts @@ -86,15 +84,15 @@ minetest.register_tool("mcl_tools:pick_wood", { -- 1/1.2 full_punch_interval = 0.83333333, max_drop_level=1, - groupcaps={ - pickaxey_dig_wood = {times=mcl_autogroup.digtimes.pickaxey_dig_wood, uses=60, maxlevel=0}, - }, damage_groups = {fleshy=2}, punch_attack_uses = 30, }, sound = { breaks = "default_tool_breaks" }, _repair_material = "group:wood", _mcl_toollike_wield = true, + _mcl_diggroups = { + pickaxey = { speed = 2, level = 1, uses = 60 } + }, }) minetest.register_tool("mcl_tools:pick_stone", { description = S("Stone Pickaxe"), @@ -106,15 +104,15 @@ minetest.register_tool("mcl_tools:pick_stone", { -- 1/1.2 full_punch_interval = 0.83333333, max_drop_level=3, - groupcaps={ - pickaxey_dig_stone = {times=mcl_autogroup.digtimes.pickaxey_dig_stone, uses=132, maxlevel=0}, - }, damage_groups = {fleshy=3}, punch_attack_uses = 66, }, sound = { breaks = "default_tool_breaks" }, _repair_material = "mcl_core:cobble", _mcl_toollike_wield = true, + _mcl_diggroups = { + pickaxey = { speed = 4, level = 3, uses = 132 } + }, }) minetest.register_tool("mcl_tools:pick_iron", { description = S("Iron Pickaxe"), @@ -126,15 +124,15 @@ minetest.register_tool("mcl_tools:pick_iron", { -- 1/1.2 full_punch_interval = 0.83333333, max_drop_level=4, - groupcaps={ - pickaxey_dig_iron = {times=mcl_autogroup.digtimes.pickaxey_dig_iron , uses=251, maxlevel=0}, - }, damage_groups = {fleshy=4}, punch_attack_uses = 126, }, sound = { breaks = "default_tool_breaks" }, _repair_material = "mcl_core:iron_ingot", _mcl_toollike_wield = true, + _mcl_diggroups = { + pickaxey = { speed = 6, level = 4, uses = 251 } + }, }) minetest.register_tool("mcl_tools:pick_gold", { description = S("Golden Pickaxe"), @@ -146,15 +144,15 @@ minetest.register_tool("mcl_tools:pick_gold", { -- 1/1.2 full_punch_interval = 0.83333333, max_drop_level=2, - groupcaps={ - pickaxey_dig_gold = {times=mcl_autogroup.digtimes.pickaxey_dig_gold , uses=33, maxlevel=0}, - }, damage_groups = {fleshy=2}, punch_attack_uses = 17, }, sound = { breaks = "default_tool_breaks" }, _repair_material = "mcl_core:gold_ingot", _mcl_toollike_wield = true, + _mcl_diggroups = { + pickaxey = { speed = 12, level = 2, uses = 33 } + }, }) minetest.register_tool("mcl_tools:pick_diamond", { description = S("Diamond Pickaxe"), @@ -166,37 +164,17 @@ minetest.register_tool("mcl_tools:pick_diamond", { -- 1/1.2 full_punch_interval = 0.83333333, max_drop_level=5, - groupcaps={ - pickaxey_dig_diamond = {times=mcl_autogroup.digtimes.pickaxey_dig_diamond, uses=1562, maxlevel=0}, - }, damage_groups = {fleshy=5}, punch_attack_uses = 781, }, sound = { breaks = "default_tool_breaks" }, _repair_material = "mcl_core:diamond", _mcl_toollike_wield = true, + _mcl_diggroups = { + pickaxey = { speed = 8, level = 5, uses = 1562 } + }, }) -local get_shovel_dig_group = function(itemstack) - local itemstring = itemstack:get_name() - local efficiency_level = mcl_enchanting.get_enchantment(itemstack, "efficiency") - local postfix = efficiency_level > 0 and "_efficiency_" .. efficiency_level or "" - if itemstring:find("mcl_tools:shovel_wood") == 1 then - return "shovely_dig_wood" .. postfix - elseif itemstring:find("mcl_tools:shovel_stone") == 1 then - return "shovely_dig_stone" .. postfix - elseif itemstring:find("mcl_tools:shovel_iron") == 1 then - return "shovely_dig_iron" .. postfix - elseif itemstring:find("mcl_tools:shovel_gold") == 1 then - return "shovely_dig_gold" .. postfix - elseif itemstring:find("mcl_tools:shovel_diamond") == 1 then - return "shovely_dig_diamond" .. postfix - else - -- Fallback - return "shovely_dig_wood" - end -end - local make_grass_path = function(itemstack, placer, pointed_thing) -- Use pointed node's on_rightclick function first, if present local node = minetest.get_node(pointed_thing.under) @@ -221,15 +199,9 @@ local make_grass_path = function(itemstack, placer, pointed_thing) end if not minetest.is_creative_enabled(placer:get_player_name()) then - -- Add wear, as if digging a level 0 shovely node + -- Add wear (as if digging a shovely node) local toolname = itemstack:get_name() - local def = minetest.registered_items[toolname] - local group = get_shovel_dig_group(itemstack) - local toolcaps = itemstack:get_tool_capabilities() - local base_uses = toolcaps.groupcaps[group].uses - local maxlevel = toolcaps.groupcaps[group].maxlevel - local uses = base_uses * math.pow(3, maxlevel) - local wear = math.ceil(65535 / uses) + local wear = mcl_autogroup.get_wear(toolname, "shovely") itemstack:add_wear(wear) end minetest.sound_play({name="default_grass_footstep", gain=1}, {pos = above}, true) @@ -258,12 +230,7 @@ if minetest.get_modpath("mcl_farming") then if not minetest.is_creative_enabled(placer:get_player_name()) then -- Add wear (as if digging a shearsy node) local toolname = itemstack:get_name() - local def = minetest.registered_items[toolname] - local group = get_shovel_dig_group(toolname) - local base_uses = def.tool_capabilities.groupcaps["shearsy_dig"].uses - local maxlevel = def.tool_capabilities.groupcaps["shearsy_dig"].maxlevel - local uses = base_uses * math.pow(3, maxlevel) - local wear = math.ceil(65535 / uses) + local wear = mcl_autogroup.get_wear(toolname, "shearsy") itemstack:add_wear(wear) end minetest.sound_play({name="default_grass_footstep", gain=1}, {pos = above}, true) @@ -288,9 +255,6 @@ minetest.register_tool("mcl_tools:shovel_wood", { tool_capabilities = { full_punch_interval = 1, max_drop_level=1, - groupcaps={ - shovely_dig_wood = {times=mcl_autogroup.digtimes.shovely_dig_wood, uses=60, maxlevel=0}, - }, damage_groups = {fleshy=2}, punch_attack_uses = 30, }, @@ -298,6 +262,9 @@ minetest.register_tool("mcl_tools:shovel_wood", { sound = { breaks = "default_tool_breaks" }, _repair_material = "group:wood", _mcl_toollike_wield = true, + _mcl_diggroups = { + shovely = { speed = 2, level = 1, uses = 60 } + }, }) minetest.register_tool("mcl_tools:shovel_stone", { description = S("Stone Shovel"), @@ -309,9 +276,6 @@ minetest.register_tool("mcl_tools:shovel_stone", { tool_capabilities = { full_punch_interval = 1, max_drop_level=3, - groupcaps={ - shovely_dig_stone = {times=mcl_autogroup.digtimes.shovely_dig_stone, uses=132, maxlevel=0}, - }, damage_groups = {fleshy=3}, punch_attack_uses = 66, }, @@ -319,6 +283,9 @@ minetest.register_tool("mcl_tools:shovel_stone", { sound = { breaks = "default_tool_breaks" }, _repair_material = "mcl_core:cobble", _mcl_toollike_wield = true, + _mcl_diggroups = { + shovely = { speed = 4, level = 3, uses = 132 } + }, }) minetest.register_tool("mcl_tools:shovel_iron", { description = S("Iron Shovel"), @@ -330,9 +297,6 @@ minetest.register_tool("mcl_tools:shovel_iron", { tool_capabilities = { full_punch_interval = 1, max_drop_level=4, - groupcaps={ - shovely_dig_iron = {times=mcl_autogroup.digtimes.shovely_dig_iron, uses=251, maxlevel=0}, - }, damage_groups = {fleshy=4}, punch_attack_uses = 126, }, @@ -340,6 +304,9 @@ minetest.register_tool("mcl_tools:shovel_iron", { sound = { breaks = "default_tool_breaks" }, _repair_material = "mcl_core:iron_ingot", _mcl_toollike_wield = true, + _mcl_diggroups = { + shovely = { speed = 6, level = 4, uses = 251 } + }, }) minetest.register_tool("mcl_tools:shovel_gold", { description = S("Golden Shovel"), @@ -351,9 +318,6 @@ minetest.register_tool("mcl_tools:shovel_gold", { tool_capabilities = { full_punch_interval = 1, max_drop_level=2, - groupcaps={ - shovely_dig_gold = {times=mcl_autogroup.digtimes.shovely_dig_gold, uses=33, maxlevel=0}, - }, damage_groups = {fleshy=2}, punch_attack_uses = 17, }, @@ -361,6 +325,9 @@ minetest.register_tool("mcl_tools:shovel_gold", { sound = { breaks = "default_tool_breaks" }, _repair_material = "mcl_core:gold_ingot", _mcl_toollike_wield = true, + _mcl_diggroups = { + shovely = { speed = 12, level = 2, uses = 33 } + }, }) minetest.register_tool("mcl_tools:shovel_diamond", { description = S("Diamond Shovel"), @@ -372,9 +339,6 @@ minetest.register_tool("mcl_tools:shovel_diamond", { tool_capabilities = { full_punch_interval = 1, max_drop_level=5, - groupcaps={ - shovely_dig_diamond = {times=mcl_autogroup.digtimes.shovely_dig_diamond, uses=1562, maxlevel=0}, - }, damage_groups = {fleshy=5}, punch_attack_uses = 781, }, @@ -382,6 +346,9 @@ minetest.register_tool("mcl_tools:shovel_diamond", { sound = { breaks = "default_tool_breaks" }, _repair_material = "mcl_core:diamond", _mcl_toollike_wield = true, + _mcl_diggroups = { + shovely = { speed = 8, level = 5, uses = 1562 } + }, }) -- Axes @@ -395,15 +362,15 @@ minetest.register_tool("mcl_tools:axe_wood", { tool_capabilities = { full_punch_interval = 1.25, max_drop_level=1, - groupcaps={ - axey_dig_wood = {times=mcl_autogroup.digtimes.axey_dig_wood, uses=60, maxlevel=0}, - }, damage_groups = {fleshy=7}, punch_attack_uses = 30, }, sound = { breaks = "default_tool_breaks" }, _repair_material = "group:wood", _mcl_toollike_wield = true, + _mcl_diggroups = { + axey = { speed = 2, level = 1, uses = 60 } + }, }) minetest.register_tool("mcl_tools:axe_stone", { description = S("Stone Axe"), @@ -414,15 +381,15 @@ minetest.register_tool("mcl_tools:axe_stone", { tool_capabilities = { full_punch_interval = 1.25, max_drop_level=3, - groupcaps={ - axey_dig_stone = {times=mcl_autogroup.digtimes.axey_dig_stone, uses=132, maxlevel=0}, - }, damage_groups = {fleshy=9}, punch_attack_uses = 66, }, sound = { breaks = "default_tool_breaks" }, _repair_material = "mcl_core:cobble", _mcl_toollike_wield = true, + _mcl_diggroups = { + axey = { speed = 4, level = 3, uses = 132 } + }, }) minetest.register_tool("mcl_tools:axe_iron", { description = S("Iron Axe"), @@ -434,15 +401,15 @@ minetest.register_tool("mcl_tools:axe_iron", { -- 1/0.9 full_punch_interval = 1.11111111, max_drop_level=4, - groupcaps={ - axey_dig_iron = {times=mcl_autogroup.digtimes.axey_dig_iron, uses=251, maxlevel=0}, - }, damage_groups = {fleshy=9}, punch_attack_uses = 126, }, sound = { breaks = "default_tool_breaks" }, _repair_material = "mcl_core:iron_ingot", _mcl_toollike_wield = true, + _mcl_diggroups = { + axey = { speed = 6, level = 4, uses = 251 } + }, }) minetest.register_tool("mcl_tools:axe_gold", { description = S("Golden Axe"), @@ -453,15 +420,15 @@ minetest.register_tool("mcl_tools:axe_gold", { tool_capabilities = { full_punch_interval = 1.0, max_drop_level=2, - groupcaps={ - axey_dig_gold= {times=mcl_autogroup.digtimes.axey_dig_gold, uses=33, maxlevel=0}, - }, damage_groups = {fleshy=7}, punch_attack_uses = 17, }, sound = { breaks = "default_tool_breaks" }, _repair_material = "mcl_core:gold_ingot", _mcl_toollike_wield = true, + _mcl_diggroups = { + axey = { speed = 12, level = 2, uses = 33 } + }, }) minetest.register_tool("mcl_tools:axe_diamond", { description = S("Diamond Axe"), @@ -472,15 +439,15 @@ minetest.register_tool("mcl_tools:axe_diamond", { tool_capabilities = { full_punch_interval = 1.0, max_drop_level=5, - groupcaps={ - axey_dig_diamond = {times=mcl_autogroup.digtimes.axey_dig_diamond, uses=1562, maxlevel=0}, - }, damage_groups = {fleshy=9}, punch_attack_uses = 781, }, sound = { breaks = "default_tool_breaks" }, _repair_material = "mcl_core:diamond", _mcl_toollike_wield = true, + _mcl_diggroups = { + axey = { speed = 8, level = 5, uses = 1562 } + }, }) -- Swords @@ -494,16 +461,16 @@ minetest.register_tool("mcl_tools:sword_wood", { tool_capabilities = { full_punch_interval = 0.625, max_drop_level=1, - groupcaps={ - swordy_dig = {times=mcl_autogroup.digtimes.swordy_dig , uses=60, maxlevel=0}, - swordy_cobweb_dig = {times=mcl_autogroup.digtimes.swordy_cobweb_dig , uses=60, maxlevel=0}, - }, damage_groups = {fleshy=4}, punch_attack_uses = 60, }, sound = { breaks = "default_tool_breaks" }, _repair_material = "group:wood", _mcl_toollike_wield = true, + _mcl_diggroups = { + swordy = { speed = 2, level = 1, uses = 60 }, + swordy_cobweb = { speed = 2, level = 1, uses = 60 } + }, }) minetest.register_tool("mcl_tools:sword_stone", { description = S("Stone Sword"), @@ -514,16 +481,16 @@ minetest.register_tool("mcl_tools:sword_stone", { tool_capabilities = { full_punch_interval = 0.625, max_drop_level=3, - groupcaps={ - swordy_dig = {times=mcl_autogroup.digtimes.swordy_dig , uses=132, maxlevel=0}, - swordy_cobweb_dig = {times=mcl_autogroup.digtimes.swordy_cobweb_dig , uses=132, maxlevel=0}, - }, damage_groups = {fleshy=5}, punch_attack_uses = 132, }, sound = { breaks = "default_tool_breaks" }, _repair_material = "mcl_core:cobble", _mcl_toollike_wield = true, + _mcl_diggroups = { + swordy = { speed = 4, level = 3, uses = 132 }, + swordy_cobweb = { speed = 4, level = 3, uses = 132 } + }, }) minetest.register_tool("mcl_tools:sword_iron", { description = S("Iron Sword"), @@ -534,16 +501,16 @@ minetest.register_tool("mcl_tools:sword_iron", { tool_capabilities = { full_punch_interval = 0.625, max_drop_level=4, - groupcaps={ - swordy_dig = {times=mcl_autogroup.digtimes.swordy_dig, uses=251, maxlevel=0}, - swordy_cobweb_dig = {times=mcl_autogroup.digtimes.swordy_cobweb_dig , uses=251, maxlevel=0}, - }, damage_groups = {fleshy=6}, punch_attack_uses = 251, }, sound = { breaks = "default_tool_breaks" }, _repair_material = "mcl_core:iron_ingot", _mcl_toollike_wield = true, + _mcl_diggroups = { + swordy = { speed = 6, level = 4, uses = 251 }, + swordy_cobweb = { speed = 6, level = 4, uses = 251 } + }, }) minetest.register_tool("mcl_tools:sword_gold", { description = S("Golden Sword"), @@ -554,16 +521,16 @@ minetest.register_tool("mcl_tools:sword_gold", { tool_capabilities = { full_punch_interval = 0.625, max_drop_level=2, - groupcaps={ - swordy_dig = {times=mcl_autogroup.digtimes.swordy_dig, uses=33, maxlevel=0}, - swordy_cobweb_dig = {times=mcl_autogroup.digtimes.swordy_cobweb_dig, uses=33, maxlevel=0}, - }, damage_groups = {fleshy=4}, punch_attack_uses = 33, }, sound = { breaks = "default_tool_breaks" }, _repair_material = "mcl_core:gold_ingot", _mcl_toollike_wield = true, + _mcl_diggroups = { + swordy = { speed = 12, level = 2, uses = 33 }, + swordy_cobweb = { speed = 12, level = 2, uses = 33 } + }, }) minetest.register_tool("mcl_tools:sword_diamond", { description = S("Diamond Sword"), @@ -574,16 +541,16 @@ minetest.register_tool("mcl_tools:sword_diamond", { tool_capabilities = { full_punch_interval = 0.625, max_drop_level=5, - groupcaps={ - swordy_dig = {times=mcl_autogroup.digtimes.swordy_dig, uses=1562, maxlevel=0}, - swordy_cobweb_dig = {times=mcl_autogroup.digtimes.swordy_cobweb_dig, uses=1562, maxlevel=0}, - }, damage_groups = {fleshy=7}, punch_attack_uses = 1562, }, sound = { breaks = "default_tool_breaks" }, _repair_material = "mcl_core:diamond", _mcl_toollike_wield = true, + _mcl_diggroups = { + swordy = { speed = 8, level = 5, uses = 1562 }, + swordy_cobweb = { speed = 8, level = 5, uses = 1562 } + }, }) --Shears @@ -598,14 +565,15 @@ minetest.register_tool("mcl_tools:shears", { tool_capabilities = { full_punch_interval = 0.5, max_drop_level=1, - groupcaps={ - shearsy_dig = {times=mcl_autogroup.digtimes.shearsy_dig, uses=238, maxlevel=0}, - shearsy_wool_dig = {times=mcl_autogroup.digtimes.shearsy_wool_dig, uses=238, maxlevel=0}, - } }, on_place = carve_pumpkin, sound = { breaks = "default_tool_breaks" }, _mcl_toollike_wield = true, + _mcl_diggroups = { + shearsy = { speed = 1.5, level = 1, uses = 238 }, + shearsy_wool = { speed = 5, level = 1, uses = 238 }, + shearsy_cobweb = { speed = 15, level = 1, uses = 238 } + }, }) diff --git a/mods/ITEMS/mcl_tools/mod.conf b/mods/ITEMS/mcl_tools/mod.conf index fb522b423..f40547c26 100644 --- a/mods/ITEMS/mcl_tools/mod.conf +++ b/mods/ITEMS/mcl_tools/mod.conf @@ -1 +1,2 @@ name = mcl_tools +depends = mcl_sounds diff --git a/mods/ITEMS/mcl_torches/depends.txt b/mods/ITEMS/mcl_torches/depends.txt deleted file mode 100644 index d15228bce..000000000 --- a/mods/ITEMS/mcl_torches/depends.txt +++ /dev/null @@ -1,4 +0,0 @@ -mcl_core -mcl_sounds -mcl_particles -doc? diff --git a/mods/ITEMS/mcl_torches/description.txt b/mods/ITEMS/mcl_torches/description.txt deleted file mode 100644 index 1ce04a366..000000000 --- a/mods/ITEMS/mcl_torches/description.txt +++ /dev/null @@ -1 +0,0 @@ -Mesh-based torches - three dimensional torches for minetest. diff --git a/mods/ITEMS/mcl_torches/mod.conf b/mods/ITEMS/mcl_torches/mod.conf index ec9cfb624..b383df2a7 100644 --- a/mods/ITEMS/mcl_torches/mod.conf +++ b/mods/ITEMS/mcl_torches/mod.conf @@ -1 +1,4 @@ name = mcl_torches +description = Mesh-based torches - three dimensional torches for minetest. +depends = mcl_core, mcl_sounds, mcl_particles +optional_depends = doc diff --git a/mods/ITEMS/mcl_totems/depends.txt b/mods/ITEMS/mcl_totems/depends.txt deleted file mode 100644 index 9b7650e03..000000000 --- a/mods/ITEMS/mcl_totems/depends.txt +++ /dev/null @@ -1 +0,0 @@ -mobs_mc diff --git a/mods/ITEMS/mcl_totems/mod.conf b/mods/ITEMS/mcl_totems/mod.conf new file mode 100644 index 000000000..70c5844c6 --- /dev/null +++ b/mods/ITEMS/mcl_totems/mod.conf @@ -0,0 +1,2 @@ +name = mcl_totems +depends = mobs_mc diff --git a/mods/ITEMS/mcl_walls/depends.txt b/mods/ITEMS/mcl_walls/depends.txt deleted file mode 100644 index de1f8a39b..000000000 --- a/mods/ITEMS/mcl_walls/depends.txt +++ /dev/null @@ -1,6 +0,0 @@ -mcl_core -mcl_end -mcl_ocean -mcl_nether -mcl_sounds -doc? diff --git a/mods/ITEMS/mcl_walls/mod.conf b/mods/ITEMS/mcl_walls/mod.conf new file mode 100644 index 000000000..8839312de --- /dev/null +++ b/mods/ITEMS/mcl_walls/mod.conf @@ -0,0 +1,3 @@ +name = mcl_walls +depends = mcl_core, mcl_end, mcl_ocean, mcl_nether, mcl_sounds +optional_depends = doc diff --git a/mods/ITEMS/mcl_wool/depends.txt b/mods/ITEMS/mcl_wool/depends.txt deleted file mode 100644 index 9699080ad..000000000 --- a/mods/ITEMS/mcl_wool/depends.txt +++ /dev/null @@ -1,2 +0,0 @@ -mcl_sounds -doc? diff --git a/mods/ITEMS/mcl_wool/mod.conf b/mods/ITEMS/mcl_wool/mod.conf index 2a4f86800..b7e9a4dab 100644 --- a/mods/ITEMS/mcl_wool/mod.conf +++ b/mods/ITEMS/mcl_wool/mod.conf @@ -1 +1,3 @@ name = mcl_wool +depends = mcl_sounds +optional_depends = doc diff --git a/mods/ITEMS/mclx_fences/depends.txt b/mods/ITEMS/mclx_fences/depends.txt deleted file mode 100644 index 640669f2a..000000000 --- a/mods/ITEMS/mclx_fences/depends.txt +++ /dev/null @@ -1 +0,0 @@ -mcl_fences diff --git a/mods/ITEMS/mclx_fences/description.txt b/mods/ITEMS/mclx_fences/description.txt deleted file mode 100644 index 57005b4cf..000000000 --- a/mods/ITEMS/mclx_fences/description.txt +++ /dev/null @@ -1 +0,0 @@ -Additional fences and fence gates diff --git a/mods/ITEMS/mclx_fences/mod.conf b/mods/ITEMS/mclx_fences/mod.conf index b53158aad..a4795159d 100644 --- a/mods/ITEMS/mclx_fences/mod.conf +++ b/mods/ITEMS/mclx_fences/mod.conf @@ -1 +1,3 @@ name = mclx_fences +description = Additional fences and fence gates +depends = mcl_fences diff --git a/mods/ITEMS/mclx_stairs/depends.txt b/mods/ITEMS/mclx_stairs/depends.txt deleted file mode 100644 index 49805c174..000000000 --- a/mods/ITEMS/mclx_stairs/depends.txt +++ /dev/null @@ -1,8 +0,0 @@ -mcl_ocean -mcl_core -mcl_sounds -mcl_nether -mcl_end -mcl_colorblocks -mcl_stairs -doc? diff --git a/mods/ITEMS/mclx_stairs/description.txt b/mods/ITEMS/mclx_stairs/description.txt deleted file mode 100644 index 896be59b9..000000000 --- a/mods/ITEMS/mclx_stairs/description.txt +++ /dev/null @@ -1 +0,0 @@ -Additional stairs and slabs not found in Minecraft 1.11 diff --git a/mods/ITEMS/mclx_stairs/mod.conf b/mods/ITEMS/mclx_stairs/mod.conf index 9d514a88c..b3aecd806 100644 --- a/mods/ITEMS/mclx_stairs/mod.conf +++ b/mods/ITEMS/mclx_stairs/mod.conf @@ -1 +1,4 @@ name = mclx_stairs +description = Additional stairs and slabs not found in Minecraft 1.11 +depends = mcl_ocean, mcl_core, mcl_sounds, mcl_nether, mcl_end, mcl_colorblocks, mcl_stairs +optional_depends = doc diff --git a/mods/ITEMS/xpanes/depends.txt b/mods/ITEMS/xpanes/depends.txt deleted file mode 100644 index 812afabce..000000000 --- a/mods/ITEMS/xpanes/depends.txt +++ /dev/null @@ -1,3 +0,0 @@ -mcl_sounds -mcl_core -doc? diff --git a/mods/ITEMS/xpanes/mod.conf b/mods/ITEMS/xpanes/mod.conf new file mode 100644 index 000000000..ba2147663 --- /dev/null +++ b/mods/ITEMS/xpanes/mod.conf @@ -0,0 +1,3 @@ +name = xpanes +depends = mcl_sounds, mcl_core +optional_depends = doc diff --git a/mods/MAPGEN/mcl_biomes/init.lua b/mods/MAPGEN/mcl_biomes/init.lua index ffb6ae628..66de6c13a 100644 --- a/mods/MAPGEN/mcl_biomes/init.lua +++ b/mods/MAPGEN/mcl_biomes/init.lua @@ -2043,7 +2043,7 @@ local function register_dimension_ores() }) -- Nether quartz - if minetest.settings:get("mcl_generate_ores") == "true" then + if minetest.settings:get_bool("mcl_generate_ores", true) then minetest.register_ore({ ore_type = "scatter", ore = "mcl_nether:quartz_ore", diff --git a/mods/MAPGEN/mcl_mapgen_core/init.lua b/mods/MAPGEN/mcl_mapgen_core/init.lua index 2986664f6..496b2e222 100644 --- a/mods/MAPGEN/mcl_mapgen_core/init.lua +++ b/mods/MAPGEN/mcl_mapgen_core/init.lua @@ -29,7 +29,7 @@ local function add_chunk(pos) end prev = d end - chunks[#chunks] = {n, n} + chunks[#chunks+1] = {n, n} end function mcl_mapgen_core.is_generated(pos) local n = mcl_vars.get_chunk_number(pos) -- unsigned int @@ -1790,6 +1790,8 @@ local generate_nether_decorations = function(minp, maxp, seed) return end + minetest.log("action", "[mcl_mapgen_core] Nether decorations " .. minetest.pos_to_string(minp) .. " ... " .. minetest.pos_to_string(maxp)) + -- TODO: Generate everything based on Perlin noise instead of PseudoRandom local bpos @@ -1847,6 +1849,7 @@ local generate_nether_decorations = function(minp, maxp, seed) end minetest.register_on_generated(function(minp, maxp, blockseed) + minetest.log("action", "[mcl_mapgen_core] Generating chunk " .. minetest.pos_to_string(minp) .. " ... " .. minetest.pos_to_string(maxp)) add_chunk(minp) local p1, p2 = {x=minp.x, y=minp.y, z=minp.z}, {x=maxp.x, y=maxp.y, z=maxp.z} if lvm > 0 then @@ -2132,24 +2135,32 @@ local function basic(vm, data, data2, emin, emax, area, minp, maxp, blockseed) -- * Replace water with Nether lava. -- * Replace stone, sand dirt in v6 so the Nether works in v6. elseif minp.y <= mcl_vars.mg_nether_max and maxp.y >= mcl_vars.mg_nether_min then - local nodes if mg_name == "v6" then - nodes = minetest.find_nodes_in_area(minp, maxp, {"mcl_core:water_source", "mcl_core:stone", "mcl_core:sand", "mcl_core:dirt"}) - else - nodes = minetest.find_nodes_in_area(minp, maxp, {"mcl_core:water_source"}) - end - for n=1, #nodes do - local p_pos = area:index(nodes[n].x, nodes[n].y, nodes[n].z) - if data[p_pos] == c_water then - data[p_pos] = c_nether_lava - lvm_used = true - elseif data[p_pos] == c_stone then - data[p_pos] = c_netherrack - lvm_used = true - elseif data[p_pos] == c_sand or data[p_pos] == c_dirt then - data[p_pos] = c_soul_sand - lvm_used = true + local nodes = minetest.find_nodes_in_area(minp, maxp, {"mcl_core:water_source", "mcl_core:stone", "mcl_core:sand", "mcl_core:dirt"}) + for n=1, #nodes do + local p_pos = area:index(nodes[n].x, nodes[n].y, nodes[n].z) + if data[p_pos] == c_water then + data[p_pos] = c_nether_lava + lvm_used = true + elseif data[p_pos] == c_stone then + data[p_pos] = c_netherrack + lvm_used = true + elseif data[p_pos] == c_sand or data[p_pos] == c_dirt then + data[p_pos] = c_soul_sand + lvm_used = true + end end + else + minetest.emerge_area(minp, maxp, function(blockpos, action, calls_remaining, param) + if calls_remaining > 0 then return end + -- local nodes = minetest.find_nodes_in_area(param.minp, param.maxp, {"mcl_core:water_source"}) + local nodes = minetest.find_nodes_in_area(param.minp, param.maxp, {"group:water"}) + local sn=(mcl_observers and mcl_observers.swap_node) or minetest.swap_node + local l = {name="mcl_nether:nether_lava_source"} + for _, n in pairs(nodes) do + sn(n, l) + end + end, {minp=vector.new(minp), maxp=vector.new(maxp)}) end -- End block fixes: diff --git a/mods/MAPGEN/mcl_structures/init.lua b/mods/MAPGEN/mcl_structures/init.lua index 96c620c99..0d6bc62ab 100644 --- a/mods/MAPGEN/mcl_structures/init.lua +++ b/mods/MAPGEN/mcl_structures/init.lua @@ -534,7 +534,7 @@ end -- Debug command minetest.register_chatcommand("spawnstruct", { - params = "desert_temple | desert_well | igloo | witch_hut | boulder | ice_spike_small | ice_spike_large | fossil | end_exit_portal | end_portal_shrine | dungeon", + params = "desert_temple | desert_well | igloo | witch_hut | boulder | ice_spike_small | ice_spike_large | fossil | end_exit_portal | end_portal_shrine | nether_portal | dungeon", description = S("Generate a pre-defined structure near your position."), privs = {debug = true}, func = function(name, param) @@ -570,6 +570,8 @@ minetest.register_chatcommand("spawnstruct", { mcl_structures.generate_end_portal_shrine(pos, rot, pr) elseif param == "dungeon" and mcl_dungeons and mcl_dungeons.spawn_dungeon then mcl_dungeons.spawn_dungeon(pos, rot, pr) + elseif param == "nether_portal" and mcl_portals and mcl_portals.spawn_nether_portal then + mcl_portals.spawn_nether_portal(pos, rot, pr, name) elseif param == "" then message = S("Error: No structure type given. Please use “/spawnstruct ”.") errord = true diff --git a/mods/PLAYER/wieldview/init.lua b/mods/PLAYER/wieldview/init.lua index dea44b2a2..48f3f99bd 100644 --- a/mods/PLAYER/wieldview/init.lua +++ b/mods/PLAYER/wieldview/init.lua @@ -72,7 +72,7 @@ minetest.register_on_joinplayer(function(player) minetest.after(0, function(player) wieldview:update_wielded_item(player) local itementity = minetest.add_entity(player:get_pos(), "wieldview:wieldnode") - itementity:set_attach(player, "Hand_Right", vector.new(0, 0, 0), vector.new(15, 45, 0)) + itementity:set_attach(player, "Hand_Right", vector.new(0, 1, 0), vector.new(90, 0, 45)) itementity:get_luaentity().wielder = name end, player) end) @@ -106,14 +106,18 @@ minetest.register_entity("wieldview:wieldnode", { if player then local wielded = player:get_wielded_item() local itemstring = wielded:get_name() + if self.itemstring ~= itemstring then local def = minetest.registered_items[itemstring] self.object:set_properties({glow = def and def.light_source or 0}) + + -- wield item as cubic if armor.textures[self.wielder].wielditem == "blank.png" then self.object:set_properties({textures = {itemstring}}) - else + else -- wield item as flat self.object:set_properties({textures = {""}}) end + self.itemstring = itemstring end else diff --git a/mods/PLAYER/wieldview/transform.lua b/mods/PLAYER/wieldview/transform.lua index 854f608ab..a19956796 100644 --- a/mods/PLAYER/wieldview/transform.lua +++ b/mods/PLAYER/wieldview/transform.lua @@ -1,37 +1,10 @@ -- Wielded Item Transformations - http://dev.minetest.net/texture wieldview.transform = { - ["mcl_core:torch"]="R270", - ["mesecons_torch:mesecon_torch_on"]="R270", - ["mcl_core:sapling"]="R270", - ["mcl_core:junglesapling"]="R270", - ["mcl_core:darksapling"]="R270", - ["mcl_core:acaciasapling"]="R270", - ["mcl_core:birchsapling"]="R270", - ["mcl_core:sprucesapling"]="R270", - ["mcl_core:deadbush"]="R270", - ["mcl_flowers:dandelion"]="R270", - ["mcl_flowers:tulip_orange"]="R270", - ["mcl_flowers:tulip_white"]="R270", - ["mcl_flowers:tulip_pink"]="R270", - ["mcl_flowers:tulip_red"]="R270", - ["mcl_flowers:allium"]="R270", - ["mcl_flowers:azure_bluet"]="R270", - ["mcl_flowers:poppy"]="R270", - ["mcl_flowers:blue_orchid"]="R270", - ["mcl_flowers:oxeye_daisy"]="R270", - ["mcl_flowers:fern"]="R270", - ["mcl_flowers:tallgrass"]="R270", - ["mcl_potions:glass_bottle"]="R270", - ["mcl_potions:water"]="R270", - ["mcl_potions:awkward"]="R270", - ["mcl_potions:thick"]="R270", - ["mcl_potions:mundane"]="R270", - - ["screwdriver:screwdriver"]="R270", - ["screwdriver:screwdriver1"]="R270", - ["screwdriver:screwdriver2"]="R270", - ["screwdriver:screwdriver3"]="R270", - ["screwdriver:screwdriver4"]="R270", + ["screwdriver:screwdriver"]="R90", + ["screwdriver:screwdriver1"]="R90", + ["screwdriver:screwdriver2"]="R90", + ["screwdriver:screwdriver3"]="R90", + ["screwdriver:screwdriver4"]="R90", }