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..c8475d0bd 100644 --- a/mods/CORE/_mcl_autogroup/init.lua +++ b/mods/CORE/_mcl_autogroup/init.lua @@ -1,169 +1,361 @@ ---[[ 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 + + 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) + if not groupcaps_def then + return + end + + 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 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] = {} + +-- 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..014a30d1e 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 @@ -174,3 +175,86 @@ minetest.craftitemdef_default.stack_max = 64 -- Set random seed for all other mods (Remember to make sure no other mod calls this function) math.randomseed(os.time()) +local chunks = {} -- intervals of chunks generated +function mcl_vars.add_chunk(pos) + local n = mcl_vars.get_chunk_number(pos) -- unsigned int + local prev + for i, d in pairs(chunks) do + if n <= d[2] then -- we've found it + if (n == d[2]) or (n >= d[1]) then return end -- already here + if n == d[1]-1 then -- right before: + if prev and (prev[2] == n-1) then + prev[2] = d[2] + table.remove(chunks, i) + return + end + d[1] = n + return + end + if prev and (prev[2] == n-1) then --join to previous + prev[2] = n + return + end + table.insert(chunks, i, {n, n}) -- insert new interval before i + return + end + prev = d + end + chunks[#chunks+1] = {n, n} +end +function mcl_vars.is_generated(pos) + local n = mcl_vars.get_chunk_number(pos) -- unsigned int + for i, d in pairs(chunks) do + if n <= d[2] then + return (n >= d[1]) + end + end + return false +end + +-- "Trivial" (actually NOT) function to just read the node and some stuff to not just return "ignore", like mt 5.4 does. +-- p: Position, if it's wrong, {name="error"} node will return. +-- force: optional (default: false) - Do the maximum to still read the node within us_timeout. +-- us_timeout: optional (default: 244 = 0.000244 s = 1/80/80/80), set it at least to 3000000 to let mapgen to finish its job. +-- +-- returns node definition, eg. {name="air"}. Unfortunately still can return {name="ignore"}. +function mcl_vars.get_node(p, force, us_timeout) + -- check initial circumstances + if not p or not p.x or not p.y or not p.z then return {name="error"} end + + -- try common way + local node = minetest.get_node(p) + if node.name ~= "ignore" then + return node + end + + -- copy table to get sure it won't changed by other threads + local pos = {x=p.x,y=p.y,z=p.z} + + -- try LVM + minetest.get_voxel_manip():read_from_map(pos, pos) + node = minetest.get_node(pos) + if node.name ~= "ignore" or not force then + return node + end + + -- all ways failed - need to emerge (or forceload if generated) + local us_timeout = us_timeout or 244 + if mcl_vars.is_generated(pos) then + minetest.chat_send_all("IMPOSSIBLE! Please report this to MCL2 issue tracker!") + minetest.forceload_block(pos) + else + minetest.emerge_area(pos, pos) + end + + local t = minetest.get_us_time() + + node = minetest.get_node(pos) + + while (not node or node.name == "ignore") and (minetest.get_us_time() - t < us_timeout) do + node = minetest.get_node(pos) + end + + return node + -- it still can return "ignore", LOL, even if force = true, but only after time out +end 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/CORE/walkover/init.lua b/mods/CORE/walkover/init.lua index 4ef164303..220157c8b 100644 --- a/mods/CORE/walkover/init.lua +++ b/mods/CORE/walkover/init.lua @@ -22,7 +22,7 @@ minetest.register_on_mods_loaded(function() end end for _,func in ipairs(walkover.registered_globals) do --cache registered globals - table.insert(registered_globals, value) + table.insert(registered_globals, func) end end) @@ -30,7 +30,7 @@ local timer = 0 minetest.register_globalstep(function(dtime) timer = timer + dtime; if timer >= 0.3 then - for _,player in ipairs(get_connected_players()) do + for _,player in pairs(get_connected_players()) do local pp = player:get_pos() pp.y = ceil(pp.y) local loc = vector_add(pp, {x=0,y=-1,z=0}) diff --git a/mods/ENTITIES/mcl_boats/init.lua b/mods/ENTITIES/mcl_boats/init.lua index 168e76b70..38e73565b 100644 --- a/mods/ENTITIES/mcl_boats/init.lua +++ b/mods/ENTITIES/mcl_boats/init.lua @@ -1,6 +1,6 @@ local S = minetest.get_translator("mcl_boats") -local boat_visual_size = {x = 3, y = 3, z = 3} +local boat_visual_size = {x = 1, y = 1, z = 1} local paddling_speed = 22 local boat_y_offset = 0.35 local boat_y_offset_ground = boat_y_offset + 0.6 @@ -12,9 +12,7 @@ local function is_group(pos, group) return minetest.get_item_group(nn, group) ~= 0 end -local function is_water(pos) - return is_group(pos, "water") -end +local is_water = flowlib.is_water local function is_ice(pos) return is_group(pos, "ice") @@ -163,6 +161,8 @@ function boat.get_staticdata(self) end function boat.on_death(self, killer) + mcl_burning.extinguish(self.object) + if killer and killer:is_player() and minetest.is_creative_enabled(killer:get_player_name()) then local inv = killer:get_inventory() if not inv:contains_item("main", self._itemstring) then @@ -188,6 +188,8 @@ function boat.on_punch(self, puncher, time_from_last_punch, tool_capabilities, d end function boat.on_step(self, dtime, moveresult) + mcl_burning.tick(self.object, dtime) + self._v = get_v(self.object:get_velocity()) * get_sign(self._v) local v_factor = 1 local v_slowdown = 0.02 @@ -223,7 +225,7 @@ function boat.on_step(self, dtime, moveresult) self._regen_timer = regen_timer if moveresult and moveresult.collides then - for _, collision in ipairs(moveresult.collisions) do + for _, collision in pairs(moveresult.collisions) do local pos = collision.node_pos if collision.type == "node" and minetest.get_item_group(minetest.get_node(pos).name, "dig_by_boat") > 0 then minetest.dig_node(pos) @@ -243,7 +245,7 @@ function boat.on_step(self, dtime, moveresult) else local ctrl = self._passenger:get_player_control() if ctrl and ctrl.sneak then - detach_player(self._passenger, true) + detach_object(self._passenger, true) self._passenger = nil end end @@ -305,7 +307,7 @@ function boat.on_step(self, dtime, moveresult) self._animation = 0 end - for _, obj in ipairs(minetest.get_objects_inside_radius(self.object:get_pos(), 1.3)) do + for _, obj in pairs(minetest.get_objects_inside_radius(self.object:get_pos(), 1.3)) do local entity = obj:get_luaentity() if entity and entity._cmi_is_mob then attach_object(self, obj) diff --git a/mods/ENTITIES/mcl_boats/mod.conf b/mods/ENTITIES/mcl_boats/mod.conf index 251459186..a5d6cc8cb 100644 --- a/mods/ENTITIES/mcl_boats/mod.conf +++ b/mods/ENTITIES/mcl_boats/mod.conf @@ -1,7 +1,7 @@ name = mcl_boats author = PilzAdam description = Adds drivable boats. -depends = mcl_player +depends = mcl_player, flowlib optional_depends = mcl_core, doc_identifier diff --git a/mods/ENTITIES/mcl_boats/models/mcl_boats_boat.b3d b/mods/ENTITIES/mcl_boats/models/mcl_boats_boat.b3d index e53bc4129..6c9c31469 100644 Binary files a/mods/ENTITIES/mcl_boats/models/mcl_boats_boat.b3d and b/mods/ENTITIES/mcl_boats/models/mcl_boats_boat.b3d differ diff --git a/mods/ENTITIES/mcl_burning/api.lua b/mods/ENTITIES/mcl_burning/api.lua index 1a3365d14..b08a0fb70 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_entity_flame_animated.png^[opacity:180^[verticalframe:" .. mcl_burning.animation_frames .. ":" .. 1, 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 @@ -267,7 +271,7 @@ function mcl_burning.fire_entity_step(self, dtime) if not parent or not mcl_burning.is_burning(parent) then do_remove = true else - for _, other in ipairs(minetest.get_objects_inside_radius(obj:get_pos(), 0)) do + for _, other in pairs(minetest.get_objects_inside_radius(obj:get_pos(), 0)) do local luaentity = obj:get_luaentity() if luaentity and luaentity.name == "mcl_burning:fire" and not luaentity.doing_step and not luaentity.removed then do_remove = true diff --git a/mods/ENTITIES/mcl_burning/init.lua b/mods/ENTITIES/mcl_burning/init.lua index 61ed12837..672036c78 100644 --- a/mods/ENTITIES/mcl_burning/init.lua +++ b/mods/ENTITIES/mcl_burning/init.lua @@ -22,7 +22,7 @@ minetest.register_entity("mcl_burning:fire", { }) minetest.register_globalstep(function(dtime) - for _, player in ipairs(minetest.get_connected_players()) do + for _, player in pairs(minetest.get_connected_players()) do mcl_burning.tick(player, dtime) end end) diff --git a/mods/ENTITIES/mcl_falling_nodes/init.lua b/mods/ENTITIES/mcl_falling_nodes/init.lua index 1ffc87b34..6e69f8911 100644 --- a/mods/ENTITIES/mcl_falling_nodes/init.lua +++ b/mods/ENTITIES/mcl_falling_nodes/init.lua @@ -1,5 +1,8 @@ local S = minetest.get_translator("mcl_falling_nodes") local dmes = minetest.get_modpath("mcl_death_messages") ~= nil +local has_mcl_armor = minetest.get_modpath("mcl_armor") + +local is_creative_enabled = minetest.is_creative_enabled local get_falling_depth = function(self) if not self._startpos then @@ -13,9 +16,8 @@ local deal_falling_damage = function(self, dtime) if minetest.get_item_group(self.node.name, "falling_node_damage") == 0 then return end - -- Cause damage to any player it hits. + -- Cause damage to any entity it hits. -- Algorithm based on MC anvils. - -- TODO: Support smashing other objects, too. local pos = self.object:get_pos() if not self._startpos then -- Fallback @@ -23,30 +25,39 @@ local deal_falling_damage = function(self, dtime) end local objs = minetest.get_objects_inside_radius(pos, 1) for _,v in ipairs(objs) do - local hp = v:get_hp() - if v:is_player() and hp ~= 0 then - if not self._hit_players then - self._hit_players = {} - end + if v:is_player() then + local hp = v:get_hp() local name = v:get_player_name() - local hit = false - for _,v in ipairs(self._hit_players) do - if name == v then - hit = true + if hp ~= 0 then + if not self._hit_players then + self._hit_players = {} end - end - if not hit then - table.insert(self._hit_players, name) - local way = self._startpos.y - pos.y - local damage = (way - 1) * 2 - damage = math.min(40, math.max(0, damage)) - if damage >= 1 then - hp = hp - damage - if hp < 0 then - hp = 0 + local hit = false + for _,v in ipairs(self._hit_players) do + if name == v then + hit = true end - if v:is_player() then - -- TODO: Reduce damage if wearing a helmet + end + if not hit then + table.insert(self._hit_players, name) + local way = self._startpos.y - pos.y + local damage = (way - 1) * 2 + damage = math.min(40, math.max(0, damage)) + if damage >= 1 then + hp = hp - damage + if hp < 0 then + hp = 0 + end + -- Reduce damage if wearing a helmet + local inv = v:get_inventory() + local helmet = inv:get_stack("armor", 2) + if has_mcl_armor and not helmet:is_empty() then + hp = hp/4*3 + if not is_creative_enabled(name) then + helmet:add_wear(65535/helmet:get_definition().groups.mcl_armor_uses) --TODO: be sure damage is exactly like mc (informations are missing in the mc wiki) + inv:set_stack("armor", 2, helmet) + end + end local msg if minetest.get_item_group(self.node.name, "anvil") ~= 0 then msg = S("@1 was smashed by a falling anvil.", v:get_player_name()) @@ -56,8 +67,35 @@ local deal_falling_damage = function(self, dtime) if dmes then mcl_death_messages.player_damage(v, msg) end + v:set_hp(hp, { type = "punch", from = "mod" }) + end + end + end + else + local hp = v:get_luaentity().health + if hp and hp ~= 0 then + if not self._hit_mobs then + self._hit_mobs = {} + end + local hit = false + for _,mob in ipairs(self._hit_mobs) do + if v == mob then + hit = true + end + end + --TODO: reduce damage for mobs then they will be able to wear armor + if not hit then + table.insert(self._hit_mobs, v) + local way = self._startpos.y - pos.y + local damage = (way - 1) * 2 + damage = math.min(40, math.max(0, damage)) + if damage >= 1 then + hp = hp - damage + if hp < 0 then + hp = 0 + end + v:get_luaentity().health = hp end - v:set_hp(hp, { type = "punch", from = "mod" }) end end end diff --git a/mods/ENTITIES/mcl_item_entity/init.lua b/mods/ENTITIES/mcl_item_entity/init.lua index e5863abbc..95b90e546 100644 --- a/mods/ENTITIES/mcl_item_entity/init.lua +++ b/mods/ENTITIES/mcl_item_entity/init.lua @@ -1,3 +1,7 @@ +local has_awards = minetest.get_modpath("awards") + +mcl_item_entity = {} + --basic settings local item_drop_settings = {} --settings table item_drop_settings.age = 1.0 --how old a dropped item (_insta_collect==false) has to be before collecting @@ -16,16 +20,33 @@ local get_gravity = function() return tonumber(minetest.settings:get("movement_gravity")) or 9.81 end +local registered_pickup_achievement = {} + +--TODO: remove limitation of 1 award per itemname +function mcl_item_entity.register_pickup_achievement(itemname, award) + if not has_awards then + minetest.log("warning", "[mcl_item_entity] Trying to register pickup achievement ["..award.."] for ["..itemname.."] while awards missing") + elseif registered_pickup_achievement[itemname] then + minetest.log("error", "[mcl_item_entity] Trying to register already existing pickup achievement ["..award.."] for ["..itemname.."]") + else + registered_pickup_achievement[itemname] = award + end +end + +mcl_item_entity.register_pickup_achievement("tree", "mcl:mineWood") +mcl_item_entity.register_pickup_achievement("mcl_mobitems:blaze_rod", "mcl:blazeRod") +mcl_item_entity.register_pickup_achievement("mcl_mobitems:leather", "mcl:killCow") +mcl_item_entity.register_pickup_achievement("mcl_core:diamond", "mcl:diamonds") + local check_pickup_achievements = function(object, player) - local itemname = ItemStack(object:get_luaentity().itemstring):get_name() - if minetest.get_item_group(itemname, "tree") ~= 0 then - awards.unlock(player:get_player_name(), "mcl:mineWood") - elseif itemname == "mcl_mobitems:blaze_rod" then - awards.unlock(player:get_player_name(), "mcl:blazeRod") - elseif itemname == "mcl_mobitems:leather" then - awards.unlock(player:get_player_name(), "mcl:killCow") - elseif itemname == "mcl_core:diamond" then - awards.unlock(player:get_player_name(), "mcl:diamonds") + if has_awards then + local itemname = ItemStack(object:get_luaentity().itemstring):get_name() + local playername = player:get_player_name() + for name,award in pairs(registered_pickup_achievement) do + if itemname == name or minetest.get_item_group(itemname, name) ~= 0 then + awards.unlock(playername, award) + end + end end end @@ -54,14 +75,14 @@ local disable_physics = function(object, luaentity, ignore_check, reset_movement end minetest.register_globalstep(function(dtime) - for _,player in ipairs(minetest.get_connected_players()) do + for _,player in pairs(minetest.get_connected_players()) do if player:get_hp() > 0 or not minetest.settings:get_bool("enable_damage") then local pos = player:get_pos() local inv = player:get_inventory() local checkpos = {x=pos.x,y=pos.y + item_drop_settings.player_collect_height,z=pos.z} --magnet and collection - for _,object in ipairs(minetest.get_objects_inside_radius(checkpos, item_drop_settings.xp_radius_magnet)) do + for _,object in pairs(minetest.get_objects_inside_radius(checkpos, item_drop_settings.xp_radius_magnet)) do if not object:is_player() and vector.distance(checkpos, object:get_pos()) < item_drop_settings.radius_magnet and object:get_luaentity() and object:get_luaentity().name == "__builtin:item" and object:get_luaentity()._magnet_timer and (object:get_luaentity()._insta_collect or (object:get_luaentity().age > item_drop_settings.age)) then object:get_luaentity()._magnet_timer = object:get_luaentity()._magnet_timer + dtime local collected = false @@ -165,66 +186,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 +242,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 +267,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 @@ -785,7 +749,7 @@ minetest.register_entity(":__builtin:item", { if self.physical_state then local own_stack = ItemStack(self.object:get_luaentity().itemstring) -- Merge with close entities of the same item - for _, object in ipairs(minetest.get_objects_inside_radius(p, 0.8)) do + for _, object in pairs(minetest.get_objects_inside_radius(p, 0.8)) do local obj = object:get_luaentity() if obj and obj.name == "__builtin:item" and obj.physical_state == false then diff --git a/mods/ENTITIES/mcl_minecarts/init.lua b/mods/ENTITIES/mcl_minecarts/init.lua index 9c61fa5ed..70bf16477 100644 --- a/mods/ENTITIES/mcl_minecarts/init.lua +++ b/mods/ENTITIES/mcl_minecarts/init.lua @@ -1,5 +1,7 @@ local S = minetest.get_translator("mcl_minecarts") +local has_mcl_wip = minetest.get_modpath("mcl_wip") + mcl_minecarts = {} mcl_minecarts.modpath = minetest.get_modpath("mcl_minecarts") mcl_minecarts.speed_max = 10 @@ -662,8 +664,6 @@ register_minecart( "mcl_minecarts_minecart_chest.png", {"mcl_minecarts:minecart", "mcl_chests:chest"}, nil, nil, false) - -mcl_wip.register_wip_item("mcl_minecarts:chest_minecart") -- Minecart with Furnace register_minecart( @@ -719,8 +719,6 @@ register_minecart( end, nil, false ) -mcl_wip.register_wip_item("mcl_minecarts:furnace_minecart") - -- Minecart with Command Block register_minecart( "mcl_minecarts:command_block_minecart", @@ -742,8 +740,6 @@ register_minecart( nil, nil, false ) -mcl_wip.register_wip_item("mcl_minecarts:command_block_minecart") - -- Minecart with Hopper register_minecart( "mcl_minecarts:hopper_minecart", @@ -762,8 +758,6 @@ register_minecart( nil, nil, false ) -mcl_wip.register_wip_item("mcl_minecarts:hopper_minecart") - -- Minecart with TNT register_minecart( "mcl_minecarts:tnt_minecart", @@ -824,29 +818,34 @@ minetest.register_craft({ -- TODO: Re-enable crafting of special minecarts when they have been implemented if false then + minetest.register_craft({ + output = "mcl_minecarts:furnace_minecart", + recipe = { + {"mcl_furnaces:furnace"}, + {"mcl_minecarts:minecart"}, + }, + }) -minetest.register_craft({ - output = "mcl_minecarts:furnace_minecart", - recipe = { - {"mcl_furnaces:furnace"}, - {"mcl_minecarts:minecart"}, - }, -}) - -minetest.register_craft({ - output = "mcl_minecarts:hopper_minecart", - recipe = { - {"mcl_hoppers:hopper"}, - {"mcl_minecarts:minecart"}, - }, -}) - -minetest.register_craft({ - output = "mcl_minecarts:chest_minecart", - recipe = { - {"mcl_chests:chest"}, - {"mcl_minecarts:minecart"}, - }, -}) + minetest.register_craft({ + output = "mcl_minecarts:hopper_minecart", + recipe = { + {"mcl_hoppers:hopper"}, + {"mcl_minecarts:minecart"}, + }, + }) + minetest.register_craft({ + output = "mcl_minecarts:chest_minecart", + recipe = { + {"mcl_chests:chest"}, + {"mcl_minecarts:minecart"}, + }, + }) end + +if has_mcl_wip then + mcl_wip.register_wip_item("mcl_minecarts:chest_minecart") + mcl_wip.register_wip_item("mcl_minecarts:furnace_minecart") + mcl_wip.register_wip_item("mcl_minecarts:command_block_minecart") + mcl_wip.register_wip_item("mcl_minecarts:hopper_minecart") +end \ No newline at end of file diff --git a/mods/ENTITIES/mcl_minecarts/mod.conf b/mods/ENTITIES/mcl_minecarts/mod.conf index 138fd18e6..9fff9175d 100644 --- a/mods/ENTITIES/mcl_minecarts/mod.conf +++ b/mods/ENTITIES/mcl_minecarts/mod.conf @@ -1,6 +1,6 @@ name = mcl_minecarts author = Krock description = Minecarts are vehicles to move players quickly on rails. -depends = mcl_explosions, mcl_core, mcl_sounds, mcl_player, mcl_achievements, mcl_chests, mcl_furnaces, mesecons_commandblock, mcl_hoppers, mcl_tnt, mesecons, mcl_wip -optional_depends = doc_identifier +depends = mcl_explosions, mcl_core, mcl_sounds, mcl_player, mcl_achievements, mcl_chests, mcl_furnaces, mesecons_commandblock, mcl_hoppers, mcl_tnt, mesecons +optional_depends = doc_identifier, mcl_wip diff --git a/mods/ENTITIES/mcl_mobs/api.lua b/mods/ENTITIES/mcl_mobs/api.lua index 0c8953079..f1df87e8b 100644 --- a/mods/ENTITIES/mcl_mobs/api.lua +++ b/mods/ENTITIES/mcl_mobs/api.lua @@ -226,7 +226,7 @@ local collision = function(self) local z = 0 local width = -self.collisionbox[1] + self.collisionbox[4] + 0.5 - for _,object in ipairs(minetest.get_objects_inside_radius(pos, width)) do + for _,object in pairs(minetest.get_objects_inside_radius(pos, width)) do if object:is_player() or (object:get_luaentity()._cmi_is_mob == true and object ~= self.object) then @@ -283,6 +283,33 @@ local get_velocity = function(self) return 0 end +local function update_roll(self) + local is_Fleckenstein = self.nametag == "Fleckenstein" + local was_Fleckenstein = false + + local rot = self.object:get_rotation() + rot.z = is_Fleckenstein and pi or 0 + self.object:set_rotation(rot) + + local cbox = table.copy(self.collisionbox) + local acbox = self.object:get_properties().collisionbox + + if math.abs(cbox[2] - acbox[2]) > 0.1 then + was_Fleckenstein = true + end + + if is_Fleckenstein ~= was_Fleckenstein then + local pos = self.object:get_pos() + pos.y = pos.y + (acbox[2] + acbox[5]) + self.object:set_pos(pos) + end + + if is_Fleckenstein then + cbox[2], cbox[5] = -cbox[5], -cbox[2] + end + + self.object:set_properties({collisionbox = cbox}) +end -- set and return valid yaw local set_yaw = function(self, yaw, delay, dtime) @@ -298,6 +325,7 @@ local set_yaw = function(self, yaw, delay, dtime) yaw = yaw + (math.random() * 2 - 1) * 5 * dtime end self.object:set_yaw(yaw) + update_roll(self) return yaw end @@ -645,9 +673,9 @@ local update_tag = function(self) nametag = tag, }) + update_roll(self) end - -- drop items local item_drop = function(self, cooked, looting_level) @@ -1047,8 +1075,13 @@ local do_env_damage = function(self) end end + -- Use get_node_light for Minetest version 5.3 where get_natural_light + -- does not exist yet. + local get_light = minetest.get_natural_light or minetest.get_node_light + local sunlight = get_light(pos, self.time_of_day) + -- bright light harms mob - if self.light_damage ~= 0 and (minetest.get_node_light(pos) or 0) > 12 then + if self.light_damage ~= 0 and (sunlight or 0) > 12 then if deal_light_damage(self, pos, self.light_damage) then return true end @@ -1057,7 +1090,7 @@ local do_env_damage = function(self) if mod_worlds then _, dim = mcl_worlds.y_to_layer(pos.y) end - if (self.sunlight_damage ~= 0 or self.ignited_by_sunlight) and (minetest.get_node_light(pos) or 0) >= minetest.LIGHT_MAX and dim == "overworld" then + if (self.sunlight_damage ~= 0 or self.ignited_by_sunlight) and (sunlight or 0) >= minetest.LIGHT_MAX and dim == "overworld" then if self.ignited_by_sunlight then mcl_burning.set_on_fire(self.object, 10) else @@ -2821,7 +2854,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 @@ -2851,6 +2884,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 @@ -3470,6 +3515,7 @@ local mob_step = function(self, dtime) yaw = yaw + (math.random() * 2 - 1) * 5 * dtime end self.object:set_yaw(yaw) + update_roll(self) end -- end rotation @@ -3768,6 +3814,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, @@ -4576,9 +4623,9 @@ local timer = 0 minetest.register_globalstep(function(dtime) timer = timer + dtime if timer < 1 then return end - for _, player in ipairs(minetest.get_connected_players()) do + for _, player in pairs(minetest.get_connected_players()) do local pos = player:get_pos() - for _, obj in ipairs(minetest.get_objects_inside_radius(pos, 47)) do + for _, obj in pairs(minetest.get_objects_inside_radius(pos, 47)) do local lua = obj:get_luaentity() if lua and lua._cmi_is_mob then lua.lifetimer = math.max(20, lua.lifetimer) diff --git a/mods/ENTITIES/mcl_paintings/init.lua b/mods/ENTITIES/mcl_paintings/init.lua index 39a513d3d..cb85ee5f8 100644 --- a/mods/ENTITIES/mcl_paintings/init.lua +++ b/mods/ENTITIES/mcl_paintings/init.lua @@ -191,6 +191,14 @@ minetest.register_craftitem("mcl_paintings:painting", { if pointed_thing.type ~= "node" then return itemstack end + + local node = minetest.get_node(pointed_thing.under) + 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 + end + end + local dir = vector.subtract(pointed_thing.above, pointed_thing.under) dir = vector.normalize(dir) if dir.y ~= 0 then diff --git a/mods/ENTITIES/mobs_mc/1_items_default.lua b/mods/ENTITIES/mobs_mc/1_items_default.lua index ddcc290c7..b4abd4f9c 100644 --- a/mods/ENTITIES/mobs_mc/1_items_default.lua +++ b/mods/ENTITIES/mobs_mc/1_items_default.lua @@ -521,7 +521,7 @@ if c("totem") then -- Totem of Undying minetest.register_craftitem("mobs_mc:totem", { description = S("Totem of Undying"), - _tt_help = minetest.colorize("#00FF00", S("Protects you from death while wielding it")), + _tt_help = minetest.colorize(mcl_colors.GREEN, S("Protects you from death while wielding it")), _doc_items_longdesc = S("A totem of undying is a rare artifact which may safe you from certain death."), _doc_items_usagehelp = S("The totem only works while you hold it in your hand. If you receive fatal damage, you are saved from death and you get a second chance with 1 HP. The totem is destroyed in the process, however."), inventory_image = "mcl_totems_totem.png", diff --git a/mods/ENTITIES/mobs_mc/2_throwing.lua b/mods/ENTITIES/mobs_mc/2_throwing.lua index fd55fa32c..23ae86d80 100644 --- a/mods/ENTITIES/mobs_mc/2_throwing.lua +++ b/mods/ENTITIES/mobs_mc/2_throwing.lua @@ -122,7 +122,7 @@ local arrows = { } local throwing_shoot_arrow = function(itemstack, player) - for _,arrow in ipairs(arrows) do + for _,arrow in pairs(arrows) do if player:get_inventory():get_stack("main", player:get_wield_index()+1):get_name() == arrow[1] then if not minetest.is_creative_enabled(player:get_player_name()) then player:get_inventory():remove_item("main", arrow[1]) diff --git a/mods/ENTITIES/mobs_mc/mod.conf b/mods/ENTITIES/mobs_mc/mod.conf index 98f48b388..a3057faff 100644 --- a/mods/ENTITIES/mobs_mc/mod.conf +++ b/mods/ENTITIES/mobs_mc/mod.conf @@ -1,6 +1,6 @@ name = mobs_mc author = maikerumine description = Adds Minecraft-like monsters and animals. -depends = mcl_init, mcl_particles, mcl_mobs, mcl_wip +depends = mcl_init, mcl_particles, mcl_mobs, mcl_wip, mcl_colors optional_depends = default, mcl_tnt, mcl_bows, mcl_throwing, mcl_fishing, bones, mesecons_materials, mobs_mc_gameconfig, doc_items diff --git a/mods/ENTITIES/mobs_mc/sheep.lua b/mods/ENTITIES/mobs_mc/sheep.lua index 681c68e1b..84650b4dd 100644 --- a/mods/ENTITIES/mobs_mc/sheep.lua +++ b/mods/ENTITIES/mobs_mc/sheep.lua @@ -25,6 +25,19 @@ local colors = { unicolor_black = { mobs_mc.items.wool_black, "#000000D0" }, } +local rainbow_colors = { + "unicolor_light_red", + "unicolor_red", + "unicolor_orange", + "unicolor_yellow", + "unicolor_green", + "unicolor_dark_green", + "unicolor_light_blue", + "unicolor_blue", + "unicolor_violet", + "unicolor_red_violet" +} + if minetest.get_modpath("mcl_wool") ~= nil then colors["unicolor_light_blue"] = { mobs_mc.items.wool_light_blue, "#5050FFD0" } end @@ -112,7 +125,7 @@ mobs:register_mob("mobs_mc:sheep", { end, -- Set random color on spawn - do_custom = function(self) + do_custom = function(self, dtime) if not self.initial_color_set then local r = math.random(0,100000) local textures @@ -149,8 +162,35 @@ mobs:register_mob("mobs_mc:sheep", { } self.initial_color_set = true end + + local is_kay27 = self.nametag == "kay27" + + if self.color_change_timer then + local old_color = self.color + if is_kay27 then + self.color_change_timer = self.color_change_timer - dtime + if self.color_change_timer < 0 then + self.color_change_timer = 0.5 + self.color_index = (self.color_index + 1) % #rainbow_colors + self.color = rainbow_colors[self.color_index + 1] + end + else + self.color_change_timer = nil + self.color_index = nil + self.color = self.initial_color + end + + if old_color ~= self.color then + self.base_texture = sheep_texture(self.color) + self.object:set_properties({textures = self.base_texture}) + end + elseif is_kay27 then + self.initial_color = self.color + self.color_change_timer = 0 + self.color_index = -1 + end end, - + on_rightclick = function(self, clicker) local item = clicker:get_wielded_item() diff --git a/mods/ENTITIES/mobs_mc/slime+magma_cube.lua b/mods/ENTITIES/mobs_mc/slime+magma_cube.lua index 54269b46e..7c21fb812 100644 --- a/mods/ENTITIES/mobs_mc/slime+magma_cube.lua +++ b/mods/ENTITIES/mobs_mc/slime+magma_cube.lua @@ -109,7 +109,6 @@ local slime_big = { fear_height = 0, spawn_small_alternative = "mobs_mc:slime_small", on_die = spawn_children_on_die("mobs_mc:slime_small", 4, 1.0, 1.5), - fire_resistant = true, use_texture_alpha = true, } mobs:register_mob("mobs_mc:slime_big", slime_big) diff --git a/mods/ENTITIES/mobs_mc/sounds/mobs_mc_villager.1.ogg b/mods/ENTITIES/mobs_mc/sounds/mobs_mc_villager.1.ogg new file mode 100644 index 000000000..9c56b0f65 Binary files /dev/null and b/mods/ENTITIES/mobs_mc/sounds/mobs_mc_villager.1.ogg differ diff --git a/mods/ENTITIES/mobs_mc/sounds/mobs_mc_villager.2.ogg b/mods/ENTITIES/mobs_mc/sounds/mobs_mc_villager.2.ogg new file mode 100644 index 000000000..bafc77b7e Binary files /dev/null and b/mods/ENTITIES/mobs_mc/sounds/mobs_mc_villager.2.ogg differ diff --git a/mods/ENTITIES/mobs_mc/sounds/mobs_mc_villager.3.ogg b/mods/ENTITIES/mobs_mc/sounds/mobs_mc_villager.3.ogg new file mode 100644 index 000000000..9e5c79b6d Binary files /dev/null and b/mods/ENTITIES/mobs_mc/sounds/mobs_mc_villager.3.ogg differ diff --git a/mods/ENTITIES/mobs_mc/sounds/mobs_mc_villager.4.ogg b/mods/ENTITIES/mobs_mc/sounds/mobs_mc_villager.4.ogg new file mode 100644 index 000000000..5c9ee492b Binary files /dev/null and b/mods/ENTITIES/mobs_mc/sounds/mobs_mc_villager.4.ogg differ diff --git a/mods/ENTITIES/mobs_mc/sounds/mobs_mc_villager.5.ogg b/mods/ENTITIES/mobs_mc/sounds/mobs_mc_villager.5.ogg new file mode 100644 index 000000000..acb236445 Binary files /dev/null and b/mods/ENTITIES/mobs_mc/sounds/mobs_mc_villager.5.ogg differ diff --git a/mods/ENTITIES/mobs_mc/sounds/mobs_mc_villager.6.ogg b/mods/ENTITIES/mobs_mc/sounds/mobs_mc_villager.6.ogg new file mode 100644 index 000000000..1ef7a5227 Binary files /dev/null and b/mods/ENTITIES/mobs_mc/sounds/mobs_mc_villager.6.ogg differ diff --git a/mods/ENTITIES/mobs_mc/sounds/mobs_mc_villager.7.ogg b/mods/ENTITIES/mobs_mc/sounds/mobs_mc_villager.7.ogg new file mode 100644 index 000000000..c2743fbcc Binary files /dev/null and b/mods/ENTITIES/mobs_mc/sounds/mobs_mc_villager.7.ogg differ diff --git a/mods/ENTITIES/mobs_mc/textures/mobs_mc_horse_skeleton.png b/mods/ENTITIES/mobs_mc/textures/mobs_mc_horse_skeleton.png index 7fa9ce1de..615eb67a8 100644 Binary files a/mods/ENTITIES/mobs_mc/textures/mobs_mc_horse_skeleton.png and b/mods/ENTITIES/mobs_mc/textures/mobs_mc_horse_skeleton.png differ diff --git a/mods/ENTITIES/mobs_mc/textures/mobs_mc_wither_half_health.png b/mods/ENTITIES/mobs_mc/textures/mobs_mc_wither_half_health.png new file mode 100644 index 000000000..f6353400c Binary files /dev/null and b/mods/ENTITIES/mobs_mc/textures/mobs_mc_wither_half_health.png differ diff --git a/mods/ENTITIES/mobs_mc/villager.lua b/mods/ENTITIES/mobs_mc/villager.lua index 0021a1adb..68644266f 100644 --- a/mods/ENTITIES/mobs_mc/villager.lua +++ b/mods/ENTITIES/mobs_mc/villager.lua @@ -516,7 +516,7 @@ local function show_trade_formspec(playername, trader, tradenum) "size[9,8.75]" .."background[-0.19,-0.25;9.41,9.49;mobs_mc_trading_formspec_bg.png]" ..disabled_img - .."label[4,0;"..F(minetest.colorize("#313131", S(profession))).."]" + .."label[4,0;"..F(minetest.colorize(mcl_colors.DARK_GRAY, S(profession))).."]" .."list[current_player;main;0,4.5;9,3;9]" .."list[current_player;main;0,7.74;9,1;]" ..b_prev..b_next @@ -960,13 +960,17 @@ 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, drops = {}, can_despawn = false, -- TODO: sounds + sounds = { + random = "mobs_mc_villager", + distance = 10, + }, animation = { stand_speed = 25, stand_start = 40, 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/ENTITIES/mobs_mc/wither.lua b/mods/ENTITIES/mobs_mc/wither.lua index 3fbf65955..caf5a248d 100644 --- a/mods/ENTITIES/mobs_mc/wither.lua +++ b/mods/ENTITIES/mobs_mc/wither.lua @@ -16,7 +16,7 @@ mobs:register_mob("mobs_mc:wither", { hp_min = 300, xp_min = 50, xp_max = 50, - armor = {undead = 80, fleshy = 80}, + armor = {undead = 80, fleshy = 100}, -- This deviates from MC Wiki's size, which makes no sense collisionbox = {-0.9, 0.4, -0.9, 0.9, 2.45, 0.9}, visual = "mesh", @@ -66,6 +66,14 @@ mobs:register_mob("mobs_mc:wither", { run_start = 0, run_end = 20, }, harmed_by_heal = true, + do_custom = function(self) + if self.health < (self.hp_max / 2) then + self.base_texture = "mobs_mc_wither_half_health.png" + self.fly = false + self.object:set_properties({textures={self.base_texture}}) + self.armor = {undead = 80, fleshy = 80} + end + end, on_spawn = function(self) minetest.sound_play("mobs_mc_wither_spawn", {object=self.object, gain=1.0, max_hear_distance=64}) end, diff --git a/mods/ENVIRONMENT/mcl_weather/nether_dust.lua b/mods/ENVIRONMENT/mcl_weather/nether_dust.lua index 735676454..16cdc9487 100644 --- a/mods/ENVIRONMENT/mcl_weather/nether_dust.lua +++ b/mods/ENVIRONMENT/mcl_weather/nether_dust.lua @@ -27,7 +27,7 @@ minetest.register_globalstep(function(dtime) if timer < 0.7 then return end timer = 0 - for _, player in ipairs(minetest.get_connected_players()) do + for _, player in pairs(minetest.get_connected_players()) do if not mcl_worlds.has_dust(player:get_pos()) then return false end diff --git a/mods/ENVIRONMENT/mcl_weather/rain.lua b/mods/ENVIRONMENT/mcl_weather/rain.lua index 0afbb5539..d8425784a 100644 --- a/mods/ENVIRONMENT/mcl_weather/rain.lua +++ b/mods/ENVIRONMENT/mcl_weather/rain.lua @@ -1,6 +1,8 @@ local PARTICLES_COUNT_RAIN = 30 local PARTICLES_COUNT_THUNDER = 45 +local get_connected_players = minetest.get_connected_players + mcl_weather.rain = { -- max rain particles created at time particles_count = PARTICLES_COUNT_RAIN, @@ -36,7 +38,7 @@ mcl_weather.rain.set_sky_box = function() {r=85, g=86, b=98}, {r=0, g=0, b=0}}) mcl_weather.skycolor.active = true - for _, player in ipairs(minetest.get_connected_players()) do + for _, player in pairs(get_connected_players()) do player:set_clouds({color="#5D5D5FE8"}) end end @@ -154,7 +156,7 @@ mcl_weather.rain.clear = function() mcl_weather.rain.init_done = false mcl_weather.rain.set_particles_mode("rain") mcl_weather.skycolor.remove_layer("weather-pack-rain-sky") - for _, player in ipairs(minetest.get_connected_players()) do + for _, player in pairs(get_connected_players()) do mcl_weather.rain.remove_sound(player) mcl_weather.rain.remove_player(player) end @@ -176,7 +178,7 @@ mcl_weather.rain.make_weather = function() mcl_weather.rain.init_done = true end - for _, player in ipairs(minetest.get_connected_players()) do + for _, player in pairs(get_connected_players()) do if (mcl_weather.is_underwater(player) or not mcl_worlds.has_weather(player:get_pos())) then mcl_weather.rain.remove_sound(player) return false diff --git a/mods/ENVIRONMENT/mcl_weather/skycolor.lua b/mods/ENVIRONMENT/mcl_weather/skycolor.lua index 6cc94b5c1..061634fcb 100644 --- a/mods/ENVIRONMENT/mcl_weather/skycolor.lua +++ b/mods/ENVIRONMENT/mcl_weather/skycolor.lua @@ -43,7 +43,7 @@ mcl_weather.skycolor = { -- Remove layer from colors table remove_layer = function(layer_name) - for k, name in ipairs(mcl_weather.skycolor.layer_names) do + for k, name in pairs(mcl_weather.skycolor.layer_names) do if name == layer_name then table.remove(mcl_weather.skycolor.layer_names, k) mcl_weather.skycolor.force_update = true diff --git a/mods/ENVIRONMENT/mcl_weather/snow.lua b/mods/ENVIRONMENT/mcl_weather/snow.lua index afe23c150..3a0c539e3 100644 --- a/mods/ENVIRONMENT/mcl_weather/snow.lua +++ b/mods/ENVIRONMENT/mcl_weather/snow.lua @@ -1,3 +1,5 @@ +local get_connected_players = minetest.get_connected_players + mcl_weather.snow = {} mcl_weather.snow.particles_count = 15 @@ -37,7 +39,7 @@ mcl_weather.snow.set_sky_box = function() {r=85, g=86, b=86}, {r=0, g=0, b=0}}) mcl_weather.skycolor.active = true - for _, player in ipairs(minetest.get_connected_players()) do + for _, player in pairs(get_connected_players()) do player:set_clouds({color="#ADADADE8"}) end mcl_weather.skycolor.active = true @@ -71,7 +73,7 @@ minetest.register_globalstep(function(dtime) mcl_weather.snow.init_done = true end - for _, player in ipairs(minetest.get_connected_players()) do + for _, player in pairs(get_connected_players()) do if (mcl_weather.is_underwater(player) or not mcl_worlds.has_weather(player:get_pos())) then return false end diff --git a/mods/ENVIRONMENT/mcl_weather/thunder.lua b/mods/ENVIRONMENT/mcl_weather/thunder.lua index 7da3308db..ece673170 100644 --- a/mods/ENVIRONMENT/mcl_weather/thunder.lua +++ b/mods/ENVIRONMENT/mcl_weather/thunder.lua @@ -1,3 +1,5 @@ +local get_connected_players = minetest.get_connected_players + -- turn off lightning mod 'auto mode' lightning.auto = false @@ -25,7 +27,7 @@ minetest.register_globalstep(function(dtime) {r=40, g=40, b=40}, {r=0, g=0, b=0}}) mcl_weather.skycolor.active = true - for _, player in ipairs(minetest.get_connected_players()) do + for _, player in pairs(get_connected_players()) do player:set_clouds({color="#3D3D3FE8"}) end mcl_weather.thunder.init_done = true 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/HELP/doc/doc/init.lua b/mods/HELP/doc/doc/init.lua index 360cc149c..9057cda8e 100644 --- a/mods/HELP/doc/doc/init.lua +++ b/mods/HELP/doc/doc/init.lua @@ -1,13 +1,7 @@ local S = minetest.get_translator("doc") local F = function(f) return minetest.formspec_escape(S(f)) end --- Compability for 0.4.14 or earlier -local colorize -if minetest.colorize then - colorize = minetest.colorize -else - colorize = function(color, text) return text end -end +local colorize = minetest.colorize doc = {} @@ -41,10 +35,10 @@ doc.FORMSPEC.ENTRY_HEIGHT = doc.FORMSPEC.ENTRY_END_Y - doc.FORMSPEC.ENTRY_START_ -- Internal helper variables local DOC_INTRO = S("This is the help.") -local COLOR_NOT_VIEWED = "#00FFFF" -- cyan -local COLOR_VIEWED = "#FFFFFF" -- white -local COLOR_HIDDEN = "#999999" -- gray -local COLOR_ERROR = "#FF0000" -- red +local COLOR_NOT_VIEWED = mcl_colors.AQUA +local COLOR_VIEWED = mcl_colors.WHITE +local COLOR_HIDDEN = mcl_colors.GRAY +local COLOR_ERROR = mcl_colors.RED local CATEGORYFIELDSIZE = { WIDTH = math.ceil(doc.FORMSPEC.WIDTH / 4), @@ -776,7 +770,7 @@ function doc.generate_entry_list(cid, playername) if name == nil or name == "" then name = S("Nameless entry (@1)", eid) if doc.entry_viewed(playername, cid, eid) then - viewedprefix = "#FF4444" + viewedprefix = mcl_colors.RED else viewedprefix = COLOR_ERROR end diff --git a/mods/HELP/doc/doc/mod.conf b/mods/HELP/doc/doc/mod.conf index 0f65ddff7..54064551b 100644 --- a/mods/HELP/doc/doc/mod.conf +++ b/mods/HELP/doc/doc/mod.conf @@ -2,3 +2,4 @@ name = doc author = Wuzzy description = A simple in-game documentation system which enables mods to add help entries based on templates. optional_depends = unified_inventory, sfinv_buttons, central_message, inventory_plus +depends = mcl_colors diff --git a/mods/HELP/mcl_craftguide/init.lua b/mods/HELP/mcl_craftguide/init.lua index eb98bcce0..829fc4181 100644 --- a/mods/HELP/mcl_craftguide/init.lua +++ b/mods/HELP/mcl_craftguide/init.lua @@ -410,7 +410,7 @@ local function get_tooltip(item, groups, cooktime, burntime) local tooltip if groups then - local gcol = "#FFAAFF" + local gcol = mcl_colors.LIGHT_PURPLE if #groups == 1 then local g = group_names[groups[1]] local groupstr @@ -446,12 +446,12 @@ local function get_tooltip(item, groups, cooktime, burntime) if not groups and cooktime then tooltip = tooltip .. "\n" .. - S("Cooking time: @1", colorize("yellow", cooktime)) + S("Cooking time: @1", colorize(mcl_colors.YELLOW, cooktime)) end if not groups and burntime then tooltip = tooltip .. "\n" .. - S("Burning time: @1", colorize("yellow", burntime)) + S("Burning time: @1", colorize(mcl_colors.YELLOW, burntime)) end return fmt(FMT.tooltip, item, ESC(tooltip)) @@ -668,7 +668,7 @@ local function make_formspec(name) fs[#fs + 1] = fmt("label[%f,%f;%s]", sfinv_only and 6.3 or data.iX - 2.2, 0.22, - ESC(colorize("#383838", fmt("%s / %u", data.pagenum, data.pagemax)))) + ESC(colorize(mcl_colors.DARK_GRAY, fmt("%s / %u", data.pagenum, data.pagemax)))) fs[#fs + 1] = fmt([[ image_button[%f,0.12;0.8,0.8;craftguide_prev_icon.png;prev;] diff --git a/mods/HELP/mcl_craftguide/mod.conf b/mods/HELP/mcl_craftguide/mod.conf index b7ab8882c..ce99c0e32 100644 --- a/mods/HELP/mcl_craftguide/mod.conf +++ b/mods/HELP/mcl_craftguide/mod.conf @@ -1,5 +1,5 @@ name = mcl_craftguide author = kilbith description = The most comprehensive Crafting Guide on Minetest. -depends = mcl_core, mcl_compass, mcl_clock, doc +depends = mcl_core, mcl_compass, mcl_clock, doc, mcl_colors optional_depends = sfinv, sfinv_buttons diff --git a/mods/HELP/mcl_tt/mod.conf b/mods/HELP/mcl_tt/mod.conf index 3a33b70dc..e442e1320 100644 --- a/mods/HELP/mcl_tt/mod.conf +++ b/mods/HELP/mcl_tt/mod.conf @@ -1,4 +1,4 @@ name = mcl_tt author = Wuzzy description = Add MCL2 tooltips -depends = tt, mcl_enchanting +depends = tt, mcl_enchanting, mcl_colors diff --git a/mods/HELP/mcl_tt/snippets_mcl.lua b/mods/HELP/mcl_tt/snippets_mcl.lua index 6e2803502..3d13df751 100644 --- a/mods/HELP/mcl_tt/snippets_mcl.lua +++ b/mods/HELP/mcl_tt/snippets_mcl.lua @@ -77,7 +77,7 @@ end) tt.register_snippet(function(itemstring) local def = minetest.registered_items[itemstring] if minetest.get_item_group(itemstring, "crush_after_fall") == 1 then - return S("Deals damage when falling"), "#FFFF00" + return S("Deals damage when falling"), mcl_colors.YELLOW end end) diff --git a/mods/HELP/tt/init.lua b/mods/HELP/tt/init.lua index f23778b6c..afc421e4f 100644 --- a/mods/HELP/tt/init.lua +++ b/mods/HELP/tt/init.lua @@ -1,7 +1,8 @@ tt = {} -tt.COLOR_DEFAULT = "#d0ffd0" -tt.COLOR_DANGER = "#ffff00" -tt.COLOR_GOOD = "#00ff00" +tt.COLOR_DEFAULT = mcl_colors.GREEN +tt.COLOR_DANGER = mcl_colors.YELLOW +tt.COLOR_GOOD = mcl_colors.GREEN +tt.NAME_COLOR = mcl_colors.YELLOW -- API tt.registered_snippets = {} @@ -63,12 +64,15 @@ tt.reload_itemstack_description = function(itemstack) local meta = itemstack:get_meta() if def and def._mcl_generate_description then def._mcl_generate_description(itemstack) - elseif should_change(itemstring, def) and meta:get_string("name") == "" then + elseif should_change(itemstring, def) then local toolcaps if def.tool_capabilities then toolcaps = itemstack:get_tool_capabilities() end local orig_desc = def._tt_original_description or def.description + if meta:get_string("name") ~= "" then + orig_desc = minetest.colorize(tt.NAME_COLOR, meta:get_string("name")) + end local desc = apply_snippets(orig_desc, itemstring, toolcaps or def.tool_capabilities, itemstack) if desc ~= orig_desc then meta:set_string("description", desc) diff --git a/mods/HELP/tt/mod.conf b/mods/HELP/tt/mod.conf index 23ce15369..2a260772d 100644 --- a/mods/HELP/tt/mod.conf +++ b/mods/HELP/tt/mod.conf @@ -1,3 +1,4 @@ name = tt author = Wuzzy description = Support for custom tooltip extensions for items +depends = mcl_colors diff --git a/mods/HUD/awards/api.lua b/mods/HUD/awards/api.lua index 9b0261b65..6601dd626 100644 --- a/mods/HUD/awards/api.lua +++ b/mods/HUD/awards/api.lua @@ -214,7 +214,7 @@ function awards.unlock(name, award) -- Get award minetest.log("action", name.." has gotten award "..award) - minetest.chat_send_all(S("@1 has made the achievement @2", name, minetest.colorize("#51EF4E", "[" .. (awdef.title or award) .. "]"))) + minetest.chat_send_all(S("@1 has made the achievement @2", name, minetest.colorize(mcl_colors.GREEN, "[" .. (awdef.title or award) .. "]"))) data.unlocked[award] = award awards.save() @@ -447,7 +447,7 @@ function awards.getFormspec(name, to, sid) first = false if def.secret and not award.got then - formspec = formspec .. "#707070"..minetest.formspec_escape(S("(Secret Award)")) + formspec = formspec .. mcl_colors.DARK_GRAY..minetest.formspec_escape(S("(Secret Award)")) else local title = award.name if def and def.title then @@ -456,7 +456,7 @@ function awards.getFormspec(name, to, sid) if award.got then formspec = formspec .. minetest.formspec_escape(title) else - formspec = formspec .. "#ACACAC".. minetest.formspec_escape(title) + formspec = formspec .. mcl_colors.GRAY.. minetest.formspec_escape(title) end end end diff --git a/mods/HUD/awards/mod.conf b/mods/HUD/awards/mod.conf index 8b1534692..1657323e2 100644 --- a/mods/HUD/awards/mod.conf +++ b/mods/HUD/awards/mod.conf @@ -6,3 +6,4 @@ license = LGPL 2.1 or later forum = https://forum.minetest.net/viewtopic.php?t=4870 version = 2.3.0 optional_depends = sfinv, unified_inventory +depends = mcl_colors diff --git a/mods/HUD/mcl_achievements/init.lua b/mods/HUD/mcl_achievements/init.lua index 7473568d2..2f1db1fe6 100644 --- a/mods/HUD/mcl_achievements/init.lua +++ b/mods/HUD/mcl_achievements/init.lua @@ -238,3 +238,20 @@ minetest.register_on_player_receive_fields(function(player, formname, fields) awards.show_to(name, name, nil, false) end end) + + +awards.register_achievement("mcl:stoneAge", { + title = S("Stone Age"), + description = S("Mine a stone with new pickaxe."), + icon = "default_cobble.png", +}) +awards.register_achievement("mcl:hotStuff", { + title = S("Hot Stuff"), + description = S("Put lava in a bucket."), + icon = "bucket_lava.png", +}) +awards.register_achievement("mcl:obsidian", { + title = S("Ice Bucket Challenge"), + description = S("Obtain an obsidian block."), + icon = "default_obsidian.png", +}) diff --git a/mods/HUD/mcl_death_messages/init.lua b/mods/HUD/mcl_death_messages/init.lua index b2c656ac4..8ca686701 100644 --- a/mods/HUD/mcl_death_messages/init.lua +++ b/mods/HUD/mcl_death_messages/init.lua @@ -1,5 +1,8 @@ local S = minetest.get_translator("mcl_death_messages") local N = function(s) return s end +local C = minetest.colorize + +local color_skyblue = mcl_colors.AQUA local function get_tool_name(item) local name = item:get_meta():get_string("name") @@ -41,6 +44,9 @@ local msgs = { ["murder"] = { N("@1 was slain by @2 using [@3]"), }, + ["murder_hand"] = { + N("@1 was slain by @2"), + }, ["murder_any"] = { N("@1 was killed."), }, @@ -131,7 +137,7 @@ local last_damages = { } minetest.register_on_dieplayer(function(player, reason) -- Death message - local message = minetest.settings:get_bool("mcl_showDeathMessages") + local message = minetest.settings:get_bool("mcl_showDeathMessages") --Maybe cache the setting? if message == nil then message = true end @@ -201,7 +207,11 @@ minetest.register_on_dieplayer(function(player, reason) elseif hitter:is_player() then hittername = hitter:get_player_name() if hittername ~= nil then - msg = dmsg("murder", name, hittername, minetest.colorize("#00FFFF", hitter_toolname)) + if hitter_toolname == "" then + msg = dmsg("murder_hand", name, hittername) + else + msg = dmsg("murder", name, hittername, C(color_skyblue, hitter_toolname)) + end else msg = dmsg("murder_any", name) end @@ -229,7 +239,7 @@ minetest.register_on_dieplayer(function(player, reason) if shooter == nil then msg = dmsg("arrow", name) elseif shooter:is_player() then - msg = dmsg("arrow_name", name, shooter:get_player_name(), minetest.colorize("#00FFFF", get_tool_name(shooter:get_wielded_item()))) + msg = dmsg("arrow_name", name, shooter:get_player_name(), C(color_skyblue, get_tool_name(shooter:get_wielded_item()))) elseif s_ent and s_ent._cmi_is_mob then if s_ent.nametag ~= "" then msg = dmsg("arrow_name", name, shooter:get_player_name(), get_tool_name(shooter:get_wielded_item())) diff --git a/mods/HUD/mcl_death_messages/locale/mcl_death_messages.de.tr b/mods/HUD/mcl_death_messages/locale/mcl_death_messages.de.tr index b9ef6680d..ffb567b8b 100644 --- a/mods/HUD/mcl_death_messages/locale/mcl_death_messages.de.tr +++ b/mods/HUD/mcl_death_messages/locale/mcl_death_messages.de.tr @@ -56,3 +56,4 @@ A ghast scared @1 to death.=Ein Ghast hat @1 zu Tode erschrocken. @1 was killed by a baby husk.=@1 wurde von einem Wüstenzombiebaby getötet. @1 was killed by a zombie pigman.=@1 wurde von einem Schweinezombie getötet. @1 was killed by a baby zombie pigman.=@1 wurde von einem Schweinezombiebaby getötet. +@1 was slain by @2.= diff --git a/mods/HUD/mcl_death_messages/locale/mcl_death_messages.es.tr b/mods/HUD/mcl_death_messages/locale/mcl_death_messages.es.tr index 6ed106db8..a56199e00 100644 --- a/mods/HUD/mcl_death_messages/locale/mcl_death_messages.es.tr +++ b/mods/HUD/mcl_death_messages/locale/mcl_death_messages.es.tr @@ -55,3 +55,4 @@ A ghast scared @1 to death.=Se ha asustado @1 hasta morir. @1 was killed by a baby husk.=@1 fue asesinado por un bebé husk. @1 was killed by a zombie pigman.=@1 fue asesinado por un cerdo zombie. @1 was killed by a baby zombie pigman.=@1 fue asesinado por un bebé cerdo zombie. +@1 was slain by @2.= diff --git a/mods/HUD/mcl_death_messages/locale/mcl_death_messages.fr.tr b/mods/HUD/mcl_death_messages/locale/mcl_death_messages.fr.tr index 6d0a5115c..05cf99976 100644 --- a/mods/HUD/mcl_death_messages/locale/mcl_death_messages.fr.tr +++ b/mods/HUD/mcl_death_messages/locale/mcl_death_messages.fr.tr @@ -56,3 +56,4 @@ A ghast scared @1 to death.=Un ghast a éffrayé @1 à mort. @1 was killed by a baby husk.=@1 a été tué par un bébé zombie momie. @1 was killed by a zombie pigman.=@1 a été tué par un zombie-couchon. @1 was killed by a baby zombie pigman.=@1 a été tué par un bébé zombie-couchon +@1 was slain by @2.= diff --git a/mods/HUD/mcl_death_messages/locale/mcl_death_messages.ru.tr b/mods/HUD/mcl_death_messages/locale/mcl_death_messages.ru.tr index f9f164dd3..d5b6ec396 100644 --- a/mods/HUD/mcl_death_messages/locale/mcl_death_messages.ru.tr +++ b/mods/HUD/mcl_death_messages/locale/mcl_death_messages.ru.tr @@ -56,3 +56,4 @@ A ghast scared @1 to death.=Гаст напугал @1 до смерти. @1 was killed by a baby husk.=@1 был(а) убит(а) машылом-кадавром. @1 was killed by a zombie pigman.=@1 был(а) убит(а) зомби-свиночеловеком. @1 was killed by a baby zombie pigman.=@1 был(а) убит(а) малышом-зомби-свиночеловеком. +@1 was slain by @2.= diff --git a/mods/HUD/mcl_death_messages/locale/template.txt b/mods/HUD/mcl_death_messages/locale/template.txt index db074f756..d1e3b832b 100644 --- a/mods/HUD/mcl_death_messages/locale/template.txt +++ b/mods/HUD/mcl_death_messages/locale/template.txt @@ -56,3 +56,4 @@ A ghast scared @1 to death.= @1 was killed by a baby husk.= @1 was killed by a zombie pigman.= @1 was killed by a baby zombie pigman.= +@1 was slain by @2.= diff --git a/mods/HUD/mcl_death_messages/mod.conf b/mods/HUD/mcl_death_messages/mod.conf index 23d2852e7..a634e16de 100644 --- a/mods/HUD/mcl_death_messages/mod.conf +++ b/mods/HUD/mcl_death_messages/mod.conf @@ -1,3 +1,4 @@ name = mcl_death_messages author = 4Evergreen4 description = Shows messages in chat when a player dies. +depends = mcl_colors diff --git a/mods/HUD/mcl_hbarmor/init.lua b/mods/HUD/mcl_hbarmor/init.lua index 57978359c..4434f5dad 100644 --- a/mods/HUD/mcl_hbarmor/init.lua +++ b/mods/HUD/mcl_hbarmor/init.lua @@ -118,7 +118,7 @@ minetest.register_globalstep(function(dtime) if main_timer > mcl_hbarmor.tick or timer > 4 then if minetest.settings:get_bool("enable_damage") then if main_timer > mcl_hbarmor.tick then main_timer = 0 end - for _,player in ipairs(minetest.get_connected_players()) do + for _,player in pairs(minetest.get_connected_players()) do local name = player:get_player_name() if mcl_hbarmor.player_active[name] == true then local ret = mcl_hbarmor.get_armor(player) diff --git a/mods/HUD/mcl_inventory/creative.lua b/mods/HUD/mcl_inventory/creative.lua index 1cebed0cd..a69fcef5b 100644 --- a/mods/HUD/mcl_inventory/creative.lua +++ b/mods/HUD/mcl_inventory/creative.lua @@ -442,7 +442,7 @@ mcl_inventory.set_creative_formspec = function(player, start_i, pagenum, inv_siz end local caption = "" if name ~= "inv" and filtername[name] then - caption = "label[0,1.2;"..F(minetest.colorize("#313131", filtername[name])).."]" + caption = "label[0,1.2;"..F(minetest.colorize(mcl_colors.DARK_GRAY, filtername[name])).."]" end formspec = "size[10,9.3]".. @@ -489,8 +489,8 @@ mcl_inventory.set_creative_formspec = function(player, start_i, pagenum, inv_siz if filter == nil then filter = "" end - formspec = formspec .. "field[5.3,1.34;4,0.75;suche;;"..minetest.formspec_escape(filter).."]" - formspec = formspec .. "field_close_on_enter[suche;false]" + formspec = formspec .. "field[5.3,1.34;4,0.75;search;;"..minetest.formspec_escape(filter).."]" + formspec = formspec .. "field_close_on_enter[search;false]" end if pagenum ~= nil then formspec = formspec .. "p"..tostring(pagenum) end @@ -561,11 +561,11 @@ minetest.register_on_player_receive_fields(function(player, formname, fields) elseif fields.inv then if players[name].page == "inv" then return end page = "inv" - elseif fields.suche == "" and not fields.creative_next and not fields.creative_prev then + elseif fields.search == "" and not fields.creative_next and not fields.creative_prev then set_inv_page("all", player) page = "nix" - elseif fields.suche ~= nil and not fields.creative_next and not fields.creative_prev then - set_inv_search(string.lower(fields.suche),player) + elseif fields.search ~= nil and not fields.creative_next and not fields.creative_prev then + set_inv_search(string.lower(fields.search),player) page = "nix" end @@ -612,8 +612,8 @@ minetest.register_on_player_receive_fields(function(player, formname, fields) players[name].start_i = start_i local filter = "" - if not fields.nix and fields.suche ~= nil and fields.suche ~= "" then - filter = fields.suche + if not fields.nix and fields.search ~= nil and fields.search ~= "" then + filter = fields.search players[name].filter = filter end diff --git a/mods/HUD/mcl_inventory/init.lua b/mods/HUD/mcl_inventory/init.lua index 054424051..e9da9486e 100644 --- a/mods/HUD/mcl_inventory/init.lua +++ b/mods/HUD/mcl_inventory/init.lua @@ -109,10 +109,10 @@ local function set_inventory(player, armor_change_only) mcl_formspec.get_itemslot_bg(0,3,1,1).. armor_slot_imgs.. -- craft and inventory - "label[0,4;"..F(minetest.colorize("#313131", S("Inventory"))).."]".. + "label[0,4;"..F(minetest.colorize(mcl_colors.DARK_GRAY, S("Inventory"))).."]".. "list[current_player;main;0,4.5;9,3;9]".. "list[current_player;main;0,7.74;9,1;]".. - "label[4,0.5;"..F(minetest.colorize("#313131", S("Crafting"))).."]".. + "label[4,0.5;"..F(minetest.colorize(mcl_colors.DARK_GRAY, S("Crafting"))).."]".. "list[current_player;craft;4,1;2,2]".. "list[current_player;craftpreview;7,1.5;1,1;]".. mcl_formspec.get_itemslot_bg(0,4.5,9,3).. diff --git a/mods/HUD/mcl_inventory/mod.conf b/mods/HUD/mcl_inventory/mod.conf index fa6b2c2f4..edd6343c7 100644 --- a/mods/HUD/mcl_inventory/mod.conf +++ b/mods/HUD/mcl_inventory/mod.conf @@ -1,6 +1,6 @@ name = mcl_inventory author = BlockMen description = Adds the player inventory and creative inventory. -depends = mcl_init, mcl_formspec +depends = mcl_init, mcl_formspec, mcl_colors optional_depends = mcl_player, _mcl_autogroup, mcl_armor, mcl_brewing, mcl_potions, mcl_enchanting diff --git a/mods/HUD/mcl_tmp_message/API.md b/mods/HUD/mcl_tmp_message/API.md new file mode 100644 index 000000000..0a3fc06a3 --- /dev/null +++ b/mods/HUD/mcl_tmp_message/API.md @@ -0,0 +1,7 @@ +# mcl_temp_message + +Allow mods to show short messages in the hud of players. + +## mcl_tmp_message.message(player, message) + +Show above the hotbar a hud message to player . \ No newline at end of file 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/init.lua b/mods/ITEMS/REDSTONE/mcl_dispensers/init.lua index b6d0d2ef6..1fd63cb4d 100644 --- a/mods/ITEMS/REDSTONE/mcl_dispensers/init.lua +++ b/mods/ITEMS/REDSTONE/mcl_dispensers/init.lua @@ -13,12 +13,12 @@ local S = minetest.get_translator("mcl_dispensers") local setup_dispenser = function(pos) -- Set formspec and inventory local form = "size[9,8.75]".. - "label[0,4.0;"..minetest.formspec_escape(minetest.colorize("#313131", S("Inventory"))).."]".. + "label[0,4.0;"..minetest.formspec_escape(minetest.colorize(mcl_colors.DARK_GRAY, S("Inventory"))).."]".. "list[current_player;main;0,4.5;9,3;9]".. mcl_formspec.get_itemslot_bg(0,4.5,9,3).. "list[current_player;main;0,7.74;9,1;]".. mcl_formspec.get_itemslot_bg(0,7.74,9,1).. - "label[3,0;"..minetest.formspec_escape(minetest.colorize("#313131", S("Dispenser"))).."]".. + "label[3,0;"..minetest.formspec_escape(minetest.colorize(mcl_colors.DARK_GRAY, S("Dispenser"))).."]".. "list[current_name;main;3,0.5;3,3;]".. mcl_formspec.get_itemslot_bg(3,0.5,3,3).. "listring[current_name;main]".. diff --git a/mods/ITEMS/REDSTONE/mcl_dispensers/mod.conf b/mods/ITEMS/REDSTONE/mcl_dispensers/mod.conf new file mode 100644 index 000000000..ac1b56c7d --- /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, mcl_colors +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/init.lua b/mods/ITEMS/REDSTONE/mcl_droppers/init.lua index 715a85f3d..0d41c3552 100644 --- a/mods/ITEMS/REDSTONE/mcl_droppers/init.lua +++ b/mods/ITEMS/REDSTONE/mcl_droppers/init.lua @@ -14,12 +14,12 @@ local S = minetest.get_translator("mcl_droppers") local setup_dropper = function(pos) -- Set formspec and inventory local form = "size[9,8.75]".. - "label[0,4.0;"..minetest.formspec_escape(minetest.colorize("#313131", S("Inventory"))).."]".. + "label[0,4.0;"..minetest.formspec_escape(minetest.colorize(mcl_colors.DARK_GRAY, S("Inventory"))).."]".. "list[current_player;main;0,4.5;9,3;9]".. mcl_formspec.get_itemslot_bg(0,4.5,9,3).. "list[current_player;main;0,7.74;9,1;]".. mcl_formspec.get_itemslot_bg(0,7.74,9,1).. - "label[3,0;"..minetest.formspec_escape(minetest.colorize("#313131", S("Dropper"))).."]".. + "label[3,0;"..minetest.formspec_escape(minetest.colorize(mcl_colors.DARK_GRAY, S("Dropper"))).."]".. "list[current_name;main;3,0.5;3,3;]".. mcl_formspec.get_itemslot_bg(3,0.5,3,3).. "listring[current_name;main]".. diff --git a/mods/ITEMS/REDSTONE/mcl_droppers/init_new.lua b/mods/ITEMS/REDSTONE/mcl_droppers/init_new.lua index 1bf968a82..b41d9c2fe 100644 --- a/mods/ITEMS/REDSTONE/mcl_droppers/init_new.lua +++ b/mods/ITEMS/REDSTONE/mcl_droppers/init_new.lua @@ -15,10 +15,10 @@ local setup_dropper = function(pos) -- Set formspec and inventory local form = "size[9,8.75]".. "background[-0.19,-0.25;9.41,9.49;crafting_inventory_9_slots.png]".. - "label[0,4.0;"..minetest.formspec_escape(minetest.colorize("#313131", S("Inventory"))).."]".. + "label[0,4.0;"..minetest.formspec_escape(minetest.colorize(mcl_colors.DARK_GRAY, S("Inventory"))).."]".. "list[current_player;main;0,4.5;9,3;9]".. "list[current_player;main;0,7.74;9,1;]".. - "label[3,0;"..minetest.formspec_escape(minetest.colorize("#313131", S("Dropper"))).."]".. + "label[3,0;"..minetest.formspec_escape(minetest.colorize(mcl_colors.DARK_GRAY, S("Dropper"))).."]".. "list[current_name;main;3,0.5;3,3;]".. "listring[current_name;main]".. "listring[current_player;main]" diff --git a/mods/ITEMS/REDSTONE/mcl_droppers/mod.conf b/mods/ITEMS/REDSTONE/mcl_droppers/mod.conf new file mode 100644 index 000000000..b5cf8f0b7 --- /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, mcl_colors +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/actionqueue.lua b/mods/ITEMS/REDSTONE/mesecons/actionqueue.lua index f3479ce59..eabe73d1a 100644 --- a/mods/ITEMS/REDSTONE/mesecons/actionqueue.lua +++ b/mods/ITEMS/REDSTONE/mesecons/actionqueue.lua @@ -22,7 +22,7 @@ function mesecon.queue:add_action(pos, func, params, time, overwritecheck, prior local toremove = nil -- Otherwise, add the action to the queue if overwritecheck then -- check if old action has to be overwritten / removed: - for i, ac in ipairs(mesecon.queue.actions) do + for i, ac in pairs(mesecon.queue.actions) do if(vector.equals(pos, ac.pos) and mesecon.cmpAny(overwritecheck, ac.owcheck)) then toremove = i 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/init.lua b/mods/ITEMS/REDSTONE/mesecons/init.lua index 93d299f06..18965287e 100644 --- a/mods/ITEMS/REDSTONE/mesecons/init.lua +++ b/mods/ITEMS/REDSTONE/mesecons/init.lua @@ -75,10 +75,10 @@ mesecon.queue:add_function("receptor_on", function (pos, rules) rules = rules or mesecon.rules.default -- Call turnon on all linking positions - for _, rule in ipairs(mesecon.flattenrules(rules)) do + for _, rule in pairs(mesecon.flattenrules(rules)) do local np = vector.add(pos, rule) local rulenames = mesecon.rules_link_rule_all(pos, rule) - for _, rulename in ipairs(rulenames) do + for _, rulename in pairs(rulenames) do mesecon.turnon(np, rulename) end end 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/init.lua b/mods/ITEMS/REDSTONE/mesecons_commandblock/init.lua index c5c3b3dc8..1928f809c 100644 --- a/mods/ITEMS/REDSTONE/mesecons_commandblock/init.lua +++ b/mods/ITEMS/REDSTONE/mesecons_commandblock/init.lua @@ -1,6 +1,11 @@ local S = minetest.get_translator("mesecons_commandblock") local F = minetest.formspec_escape +local color_red = mcl_colors.RED + +local command_blocks_activated = minetest.settings:get_bool("mcl_enable_commandblocks", true) +local msg_not_activated = S("Command blocks are not enabled on this server") + local function construct(pos) local meta = minetest.get_meta(pos) @@ -78,7 +83,7 @@ local function check_commands(commands, player_name) if string.sub(cmd, 1, 1) == "/" then msg = S("Error: The command “@1” does not exist; your command block has not been changed. Use the “help” chat command for a list of available commands. Hint: Try to remove the leading slash.", cmd) end - return false, minetest.colorize("#FF0000", msg) + return false, minetest.colorize(color_red, msg) end if player_name then local player_privs = minetest.get_player_privs(player_name) @@ -86,7 +91,7 @@ local function check_commands(commands, player_name) for cmd_priv, _ in pairs(cmddef.privs) do if player_privs[cmd_priv] ~= true then local msg = S("Error: You have insufficient privileges to use the command “@1” (missing privilege: @2)! The command block has not been changed.", cmd, cmd_priv) - return false, minetest.colorize("#FF0000", msg) + return false, minetest.colorize(color_red, msg) end end end @@ -98,10 +103,15 @@ local function commandblock_action_on(pos, node) if node.name ~= "mesecons_commandblock:commandblock_off" then return end - - minetest.swap_node(pos, {name = "mesecons_commandblock:commandblock_on"}) - + local meta = minetest.get_meta(pos) + local commander = meta:get_string("commander") + + if not command_blocks_activated then + --minetest.chat_send_player(commander, msg_not_activated) + return + end + minetest.swap_node(pos, {name = "mesecons_commandblock:commandblock_on"}) local commands = resolve_commands(meta:get_string("commands"), pos) for _, command in pairs(commands:split("\n")) do @@ -117,7 +127,6 @@ local function commandblock_action_on(pos, node) return end -- Execute command in the name of commander - local commander = meta:get_string("commander") cmddef.func(commander, param) end end @@ -129,6 +138,10 @@ local function commandblock_action_off(pos, node) end local on_rightclick = function(pos, node, player, itemstack, pointed_thing) + if not command_blocks_activated then + minetest.chat_send_player(player:get_player_name(), msg_not_activated) + return + end local can_edit = true -- Only allow write access in Creative Mode if not minetest.is_creative_enabled(player:get_player_name()) then diff --git a/mods/ITEMS/REDSTONE/mesecons_commandblock/locale/mesecons_commandblock.de.tr b/mods/ITEMS/REDSTONE/mesecons_commandblock/locale/mesecons_commandblock.de.tr index 9c9b1df1d..a149feef9 100644 --- a/mods/ITEMS/REDSTONE/mesecons_commandblock/locale/mesecons_commandblock.de.tr +++ b/mods/ITEMS/REDSTONE/mesecons_commandblock/locale/mesecons_commandblock.de.tr @@ -27,3 +27,4 @@ Access denied. You need the “maphack” privilege to edit command blocks.=Zugr Editing the command block has failed! You can only change the command block in Creative Mode!=Bearbeitung des Befehlsblocks fehlgeschlagen! Sie können den Befehlsblock nur im Kreativmodus ändern! Editing the command block has failed! The command block is gone.=Bearbeiten des Befehlsblocks fehlgeschlagen! Der Befehlsblock ist verschwunden. Executes server commands when powered by redstone power=Führt Serverbefehle aus, wenn mit Redstoneenergie versorgt +Command blocks are not enabled on this server= diff --git a/mods/ITEMS/REDSTONE/mesecons_commandblock/locale/mesecons_commandblock.es.tr b/mods/ITEMS/REDSTONE/mesecons_commandblock/locale/mesecons_commandblock.es.tr index 8826ab9a6..938c710b9 100644 --- a/mods/ITEMS/REDSTONE/mesecons_commandblock/locale/mesecons_commandblock.es.tr +++ b/mods/ITEMS/REDSTONE/mesecons_commandblock/locale/mesecons_commandblock.es.tr @@ -28,3 +28,4 @@ Example 2:@n give @@n mcl_core:apple 5@nGives the nearest player 5 apples=2. Access denied. You need the “maphack” privilege to edit command blocks.=Acceso denegado. Necesita el privilegio "maphack" para editar bloques de comandos. Editing the command block has failed! You can only change the command block in Creative Mode!=¡La edición del bloque de comando ha fallado! ¡Solo puede cambiar el bloque de comandos en modo creativo! Editing the command block has failed! The command block is gone.=¡La edición del bloque de comando ha fallado! El bloque de comando se ha ido. +Command blocks are not enabled on this server= diff --git a/mods/ITEMS/REDSTONE/mesecons_commandblock/locale/mesecons_commandblock.fr.tr b/mods/ITEMS/REDSTONE/mesecons_commandblock/locale/mesecons_commandblock.fr.tr index 061ac08a0..b397c979c 100644 --- a/mods/ITEMS/REDSTONE/mesecons_commandblock/locale/mesecons_commandblock.fr.tr +++ b/mods/ITEMS/REDSTONE/mesecons_commandblock/locale/mesecons_commandblock.fr.tr @@ -27,3 +27,4 @@ Access denied. You need the “maphack” privilege to edit command blocks.=Acc Editing the command block has failed! You can only change the command block in Creative Mode!=La modification du bloc de commandes a échoué! Vous ne pouvez modifier le bloc de commandes qu'en mode créatif! Editing the command block has failed! The command block is gone.=La modification du bloc de commandes a échoué! Le bloc de commande a disparu. Executes server commands when powered by redstone power=Exécute les commandes du serveur lorsqu'il est alimenté par l'alimentation Redstone +Command blocks are not enabled on this server=Les blocks de commandes ne sont pas activés sur ce serveur diff --git a/mods/ITEMS/REDSTONE/mesecons_commandblock/locale/mesecons_commandblock.ru.tr b/mods/ITEMS/REDSTONE/mesecons_commandblock/locale/mesecons_commandblock.ru.tr index 8671099c7..85bed4b95 100644 --- a/mods/ITEMS/REDSTONE/mesecons_commandblock/locale/mesecons_commandblock.ru.tr +++ b/mods/ITEMS/REDSTONE/mesecons_commandblock/locale/mesecons_commandblock.ru.tr @@ -27,3 +27,4 @@ Access denied. You need the “maphack” privilege to edit command blocks.=До Editing the command block has failed! You can only change the command block in Creative Mode!=Попытка редактирования командного блока потерпела неудачу. Вы можете изменять командные блоки только в творческом режиме! Editing the command block has failed! The command block is gone.=Попытка редактирования командного блока потерпела неудачу. Командный блок исчез. Executes server commands when powered by redstone power=При подаче энергии редстоуна выполняет серверные команды +Command blocks are not enabled on this server= diff --git a/mods/ITEMS/REDSTONE/mesecons_commandblock/locale/template.txt b/mods/ITEMS/REDSTONE/mesecons_commandblock/locale/template.txt index 0e0c3caa5..49e98ef2b 100644 --- a/mods/ITEMS/REDSTONE/mesecons_commandblock/locale/template.txt +++ b/mods/ITEMS/REDSTONE/mesecons_commandblock/locale/template.txt @@ -27,3 +27,4 @@ Access denied. You need the “maphack” privilege to edit command blocks.= Editing the command block has failed! You can only change the command block in Creative Mode!= Editing the command block has failed! The command block is gone.= Executes server commands when powered by redstone power= +Command blocks are not enabled on this server= diff --git a/mods/ITEMS/REDSTONE/mesecons_commandblock/mod.conf b/mods/ITEMS/REDSTONE/mesecons_commandblock/mod.conf new file mode 100644 index 000000000..a35c425f5 --- /dev/null +++ b/mods/ITEMS/REDSTONE/mesecons_commandblock/mod.conf @@ -0,0 +1,3 @@ +name = mesecons_commandblock +depends = mesecons, mcl_colors +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_anvils/init.lua b/mods/ITEMS/mcl_anvils/init.lua index f95ddabac..1845ed776 100644 --- a/mods/ITEMS/mcl_anvils/init.lua +++ b/mods/ITEMS/mcl_anvils/init.lua @@ -9,7 +9,6 @@ local MATERIAL_TOOL_REPAIR_BOOST = { math.ceil(MAX_WEAR * 0.75), -- 75% MAX_WEAR, -- 100% } -local NAME_COLOR = "#FFFF4C" local function get_anvil_formspec(set_name) if not set_name then @@ -17,7 +16,7 @@ local function get_anvil_formspec(set_name) end return "size[9,8.75]".. "background[-0.19,-0.25;9.41,9.49;mcl_anvils_inventory.png]".. - "label[0,4.0;"..minetest.formspec_escape(minetest.colorize("#313131", S("Inventory"))).."]".. + "label[0,4.0;"..minetest.formspec_escape(minetest.colorize(mcl_colors.DARK_GRAY, S("Inventory"))).."]".. "list[current_player;main;0,4.5;9,3;9]".. mcl_formspec.get_itemslot_bg(0,4.5,9,3).. "list[current_player;main;0,7.74;9,1;]".. @@ -28,7 +27,7 @@ local function get_anvil_formspec(set_name) mcl_formspec.get_itemslot_bg(4,2.5,1,1).. "list[context;output;8,2.5;1,1;]".. mcl_formspec.get_itemslot_bg(8,2.5,1,1).. - "label[3,0.1;"..minetest.formspec_escape(minetest.colorize("#313131", S("Repair and Name"))).."]".. + "label[3,0.1;"..minetest.formspec_escape(minetest.colorize(mcl_colors.DARK_GRAY, S("Repair and Name"))).."]".. "field[3.25,1;4,1;name;;"..minetest.formspec_escape(set_name).."]".. "field_close_on_enter[name;false]".. "button[7,0.7;2,1;name_button;"..minetest.formspec_escape(S("Set Name")).."]".. @@ -172,14 +171,8 @@ local function update_anvil_slots(meta) if new_name ~= old_name then -- Save the raw name internally meta:set_string("name", new_name) - -- Rename item - if new_name == "" then - tt.reload_itemstack_description(name_item) - else - -- Custom name set. Colorize it! - -- This makes the name visually different from unnamed items - meta:set_string("description", minetest.colorize(NAME_COLOR, new_name)) - end + -- Rename item handled by tt + tt.reload_itemstack_description(name_item) new_output = name_item elseif just_rename then new_output = "" @@ -495,7 +488,6 @@ S("The anvil has limited durability and 3 damage levels: undamaged, slightly dam local anvildef1 = table.copy(anvildef) anvildef1.description = S("Slightly Damaged Anvil") anvildef1._doc_items_create_entry = false -anvildef1.groups.not_in_creative_inventory = 1 anvildef1.groups.anvil = 2 anvildef1._doc_items_create_entry = false anvildef1.tiles = {"mcl_anvils_anvil_top_damaged_1.png^[transformR90", "mcl_anvils_anvil_base.png", "mcl_anvils_anvil_side.png"} @@ -503,7 +495,6 @@ anvildef1.tiles = {"mcl_anvils_anvil_top_damaged_1.png^[transformR90", "mcl_anvi local anvildef2 = table.copy(anvildef) anvildef2.description = S("Very Damaged Anvil") anvildef2._doc_items_create_entry = false -anvildef2.groups.not_in_creative_inventory = 1 anvildef2.groups.anvil = 3 anvildef2._doc_items_create_entry = false anvildef2.tiles = {"mcl_anvils_anvil_top_damaged_2.png^[transformR90", "mcl_anvils_anvil_base.png", "mcl_anvils_anvil_side.png"} diff --git a/mods/ITEMS/mcl_anvils/mod.conf b/mods/ITEMS/mcl_anvils/mod.conf index cd4fa02a8..cbb5dc223 100644 --- a/mods/ITEMS/mcl_anvils/mod.conf +++ b/mods/ITEMS/mcl_anvils/mod.conf @@ -1,5 +1,5 @@ name = mcl_anvils author = Wuzzy description = Anvils mods for MCL2 -depends = mcl_init, mcl_formspec, mcl_sounds, tt, mcl_enchanting +depends = mcl_init, mcl_formspec, mcl_sounds, tt, mcl_enchanting, mcl_colors optional_depends = mcl_core, screwdriver diff --git a/mods/ITEMS/mcl_armor/armor.lua b/mods/ITEMS/mcl_armor/armor.lua index a879f7240..05a020016 100644 --- a/mods/ITEMS/mcl_armor/armor.lua +++ b/mods/ITEMS/mcl_armor/armor.lua @@ -367,6 +367,7 @@ mcl_player.player_register_model("mcl_armor_character.b3d", { run_walk = {x=440, y=459}, run_walk_mine = {x=461, y=480}, sit_mount = {x=484, y=484}, + die = {x=498, y=498}, }, }) diff --git a/mods/ITEMS/mcl_armor/models/mcl_armor_character.b3d b/mods/ITEMS/mcl_armor/models/mcl_armor_character.b3d index c6a1274c5..a658f753c 100644 Binary files a/mods/ITEMS/mcl_armor/models/mcl_armor_character.b3d and b/mods/ITEMS/mcl_armor/models/mcl_armor_character.b3d differ diff --git a/mods/ITEMS/mcl_armor/models/mcl_armor_character.blend b/mods/ITEMS/mcl_armor/models/mcl_armor_character.blend index 88db35cf5..c1efab399 100644 Binary files a/mods/ITEMS/mcl_armor/models/mcl_armor_character.blend and b/mods/ITEMS/mcl_armor/models/mcl_armor_character.blend differ diff --git a/mods/ITEMS/mcl_armor/models/mcl_armor_character_female.b3d b/mods/ITEMS/mcl_armor/models/mcl_armor_character_female.b3d index cd2fca988..44494d1ec 100644 Binary files a/mods/ITEMS/mcl_armor/models/mcl_armor_character_female.b3d and b/mods/ITEMS/mcl_armor/models/mcl_armor_character_female.b3d differ diff --git a/mods/ITEMS/mcl_armor/models/mcl_armor_character_female.blend b/mods/ITEMS/mcl_armor/models/mcl_armor_character_female.blend index 098417b42..c854a49e5 100644 Binary files a/mods/ITEMS/mcl_armor/models/mcl_armor_character_female.blend and b/mods/ITEMS/mcl_armor/models/mcl_armor_character_female.blend differ diff --git a/mods/ITEMS/mcl_banners/mod.conf b/mods/ITEMS/mcl_banners/mod.conf index cee7bace7..8c3117206 100644 --- a/mods/ITEMS/mcl_banners/mod.conf +++ b/mods/ITEMS/mcl_banners/mod.conf @@ -1,4 +1,5 @@ name = mcl_banners author = 22i description = Adds decorative banners in different colors which can be emblazoned with patterns, offering a countless number of combinations. +depends = mcl_colors optional_depends = mcl_sounds, mcl_core, mcl_wool, mcl_cauldrons, doc, screwdriver diff --git a/mods/ITEMS/mcl_banners/patterncraft.lua b/mods/ITEMS/mcl_banners/patterncraft.lua index e1f05ff11..31782a42b 100644 --- a/mods/ITEMS/mcl_banners/patterncraft.lua +++ b/mods/ITEMS/mcl_banners/patterncraft.lua @@ -281,7 +281,7 @@ mcl_banners.make_advanced_banner_description = function(description, layers) -- Final string concatenations: Just a list of strings local append = table.concat(layerstrings, "\n") - description = description .. "\n" .. minetest.colorize("#8F8F8F", append) + description = description .. "\n" .. minetest.colorize(mcl_colors.GRAY, append) return description end end diff --git a/mods/ITEMS/mcl_beds/api.lua b/mods/ITEMS/mcl_beds/api.lua index c274a29a0..a2df1bdf3 100644 --- a/mods/ITEMS/mcl_beds/api.lua +++ b/mods/ITEMS/mcl_beds/api.lua @@ -89,6 +89,7 @@ function mcl_beds.register_bed(name, def) selection_box = selection_box_bottom, collision_box = collision_box_bottom, drop = "", + node_placement_prediction = "", on_place = function(itemstack, placer, pointed_thing) local under = pointed_thing.under diff --git a/mods/ITEMS/mcl_beds/functions.lua b/mods/ITEMS/mcl_beds/functions.lua index 33c38c6cb..86f6a6852 100644 --- a/mods/ITEMS/mcl_beds/functions.lua +++ b/mods/ITEMS/mcl_beds/functions.lua @@ -36,7 +36,7 @@ local function check_in_beds(players) players = minetest.get_connected_players() end - for n, player in ipairs(players) do + for n, player in pairs(players) do local name = player:get_player_name() if not in_bed[name] then return false @@ -102,8 +102,7 @@ local function lay_down(player, pos, bed_pos, state, skip) -- No sleeping if monsters nearby. -- The exceptions above apply. -- Zombie pigmen only prevent sleep while they are hostle. - local objs = minetest.get_objects_inside_radius(bed_pos, 8) - for _, obj in ipairs(objs) do + for _, obj in pairs(minetest.get_objects_inside_radius(bed_pos, 8)) do if obj ~= nil and not obj:is_player() then local ent = obj:get_luaentity() local mobname = ent.name diff --git a/mods/ITEMS/mcl_books/init.lua b/mods/ITEMS/mcl_books/init.lua index 45208c413..5101994e9 100644 --- a/mods/ITEMS/mcl_books/init.lua +++ b/mods/ITEMS/mcl_books/init.lua @@ -1,4 +1,4 @@ -local S =minetest.get_translator("mcl_books") +local S = minetest.get_translator("mcl_books") local max_text_length = 4500 -- TODO: Increase to 12800 when scroll bar was added to written book local max_title_length = 64 @@ -67,7 +67,7 @@ local make_description = function(title, author, generation) else desc = S("Tattered Book") end - desc = desc .. "\n" .. minetest.colorize("#AAAAAA", S("by @1", author)) + desc = desc .. "\n" .. minetest.colorize(mcl_colors.GRAY, S("by @1", author)) return desc end @@ -147,8 +147,8 @@ minetest.register_on_player_receive_fields(function ( player, formname, fields ) local formspec = "size[8,9]".. header.. "background[-0.5,-0.5;9,10;mcl_books_book_bg.png]".. - "field[0.75,1;7.25,1;title;"..minetest.formspec_escape(minetest.colorize("#000000", S("Enter book title:")))..";]".. - "label[0.75,1.5;"..minetest.formspec_escape(minetest.colorize("#404040", S("by @1", name))).."]".. + "field[0.75,1;7.25,1;title;"..minetest.formspec_escape(minetest.colorize(mcl_colors.BLACK, S("Enter book title:")))..";]".. + "label[0.75,1.5;"..minetest.formspec_escape(minetest.colorize(mcl_colors.DARK_GRAY, S("by @1", name))).."]".. "button_exit[0.75,7.95;3,1;sign;"..minetest.formspec_escape(S("Sign and Close")).."]".. "tooltip[sign;"..minetest.formspec_escape(S("Note: The book will no longer be editable after signing")).."]".. "button[4.25,7.95;3,1;cancel;"..minetest.formspec_escape(S("Cancel")).."]" diff --git a/mods/ITEMS/mcl_books/mod.conf b/mods/ITEMS/mcl_books/mod.conf index 7c4513b00..cea9a5dd8 100644 --- a/mods/ITEMS/mcl_books/mod.conf +++ b/mods/ITEMS/mcl_books/mod.conf @@ -1,4 +1,4 @@ name = mcl_books author = celeron55 description = Books mod for MCL2 -optional_depends = mcl_init, mcl_core, mcl_sounds, mcl_mobitems, mcl_dye +optional_depends = mcl_init, mcl_core, mcl_sounds, mcl_mobitems, mcl_dye, mcl_colors diff --git a/mods/ITEMS/mcl_bows/arrow.lua b/mods/ITEMS/mcl_bows/arrow.lua index efa465ddf..cddae0869 100644 --- a/mods/ITEMS/mcl_bows/arrow.lua +++ b/mods/ITEMS/mcl_bows/arrow.lua @@ -15,6 +15,20 @@ local dir_to_pitch = function(dir) return -math.atan2(-dir.y, xz) end +local random_arrow_positions = function(positions, placement) + if positions == 'x' then + return math.random(-4, 4) + elseif positions == 'y' then + return math.random(0, 10) + end + if placement == 'front' and positions == 'z' then + return 3 + elseif placement == 'back' and positions == 'z' then + return -3 + end + return 0 +end + local mod_awards = minetest.get_modpath("awards") and minetest.get_modpath("mcl_achievements") local mod_button = minetest.get_modpath("mesecons_button") @@ -96,11 +110,23 @@ end ARROW_ENTITY.on_step = function(self, dtime) mcl_burning.tick(self.object, dtime) + self._time_in_air = self._time_in_air + .001 + local pos = self.object:get_pos() local dpos = table.copy(pos) -- digital pos dpos = vector.round(dpos) local node = minetest.get_node(dpos) + if self.object:get_attach() ~= nil and self.object:get_attach(parent):get_hp() < 1 then + self.object:remove() + end + + minetest.register_on_leaveplayer(function(player) + if self.object:get_attach(parent) == player then + self.object:remove() + end + end) + if self._stuck then self._stucktimer = self._stucktimer + dtime self._stuckrechecktimer = self._stuckrechecktimer + dtime @@ -146,7 +172,7 @@ ARROW_ENTITY.on_step = function(self, dtime) -- Check for object "collision". Done every tick (hopefully this is not too stressing) else - if self._damage >= 9 then + if self._damage >= 9 and self._in_player == false then minetest.add_particlespawner({ amount = 1, time = .001, @@ -180,10 +206,10 @@ ARROW_ENTITY.on_step = function(self, dtime) for k, obj in pairs(objs) do local ok = false -- Arrows can only damage players and mobs - if obj ~= self._shooter and obj:is_player() then + if obj:is_player() then ok = true elseif obj:get_luaentity() ~= nil then - if obj ~= self._shooter and (obj:get_luaentity()._cmi_is_mob or obj:get_luaentity()._hittable_by_projectile) then + if (obj:get_luaentity()._cmi_is_mob or obj:get_luaentity()._hittable_by_projectile) then ok = true end end @@ -201,11 +227,12 @@ ARROW_ENTITY.on_step = function(self, dtime) end -- If an attackable object was found, we will damage the closest one only + if closest_object ~= nil then local obj = closest_object local is_player = obj:is_player() local lua = obj:get_luaentity() - if obj ~= self._shooter and (is_player or (lua and (lua._cmi_is_mob or lua._hittable_by_projectile))) then + if obj == self._shooter and self._time_in_air > 1.02 or obj ~= self._shooter and (is_player or (lua and (lua._cmi_is_mob or lua._hittable_by_projectile))) then if obj:get_hp() > 0 then -- Check if there is no solid node between arrow and object local ray = minetest.raycast(self.object:get_pos(), obj:get_pos(), true) @@ -230,19 +257,60 @@ ARROW_ENTITY.on_step = function(self, dtime) if obj:is_player() and rawget(_G, "armor") and armor.last_damage_types then armor.last_damage_types[obj:get_player_name()] = "projectile" end - damage_particles(self.object:get_pos(), self._is_critical) + if self._in_player == false then + damage_particles(self.object:get_pos(), self._is_critical) + end if mcl_burning.is_burning(self.object) then mcl_burning.set_on_fire(obj, 5) end - obj:punch(self.object, 1.0, { - full_punch_interval=1.0, - damage_groups={fleshy=self._damage}, - }, self.object:get_velocity()) + if self._in_player == false then + obj:punch(self.object, 1.0, { + full_punch_interval=1.0, + damage_groups={fleshy=self._damage}, + }, self.object:get_velocity()) + if obj:is_player() then + local placement = '' + self._placement = math.random(1, 2) + if self._placement == 1 then + placement = 'front' + else + placement = 'back' + end + self._in_player = true + if self._placement == 2 then + self._rotation_station = 90 + else + self._rotation_station = -90 + end + self._y_position = random_arrow_positions('y', placement) + self._x_position = random_arrow_positions('x', placement) + if self._y_position > 6 and self._x_position < 2 and self._x_position > -2 then + self._attach_parent = 'Head' + self._y_position = self._y_position - 6 + elseif self._x_position > 2 then + self._attach_parent = 'Arm_Right' + self._y_position = self._y_position - 3 + self._x_position = self._x_position - 2 + elseif self._x_position < -2 then + self._attach_parent = 'Arm_Left' + self._y_position = self._y_position - 3 + self._x_position = self._x_position + 2 + else + self._attach_parent = 'Body' + end + 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() + end) + end + end end if is_player then - if self._shooter and self._shooter:is_player() then + if self._shooter and self._shooter:is_player() and self._in_player == false then -- “Ding” sound for hitting another player minetest.sound_play({name="mcl_bows_hit_player", gain=0.1}, {to_player=self._shooter:get_player_name()}, true) end @@ -259,10 +327,14 @@ ARROW_ENTITY.on_step = function(self, dtime) end end end - minetest.sound_play({name="mcl_bows_hit_other", gain=0.3}, {pos=self.object:get_pos(), max_hear_distance=16}, true) + if self._in_player == false then + minetest.sound_play({name="mcl_bows_hit_other", gain=0.3}, {pos=self.object:get_pos(), max_hear_distance=16}, true) + end + end + if not obj:is_player() then + mcl_burning.extinguish(self.object) + self.object:remove() end - mcl_burning.extinguish(self.object) - self.object:remove() return end end @@ -389,6 +461,8 @@ ARROW_ENTITY.get_staticdata = function(self) end ARROW_ENTITY.on_activate = function(self, staticdata, dtime_s) + self._time_in_air = 1.0 + self._in_player = false local data = minetest.deserialize(staticdata) if data then self._stuck = data.stuck diff --git a/mods/ITEMS/mcl_bows/bow.lua b/mods/ITEMS/mcl_bows/bow.lua index 4ea2066b0..87820071d 100644 --- a/mods/ITEMS/mcl_bows/bow.lua +++ b/mods/ITEMS/mcl_bows/bow.lua @@ -341,7 +341,7 @@ controls.register_on_hold(function(player, key, time) end) minetest.register_globalstep(function(dtime) - for _, player in ipairs(minetest.get_connected_players()) do + for _, player in pairs(minetest.get_connected_players()) do local name = player:get_player_name() local wielditem = player:get_wielded_item() local wieldindex = player:get_wield_index() diff --git a/mods/ITEMS/mcl_brewing/init.lua b/mods/ITEMS/mcl_brewing/init.lua index 617929ff7..78ccd8ed9 100644 --- a/mods/ITEMS/mcl_brewing/init.lua +++ b/mods/ITEMS/mcl_brewing/init.lua @@ -4,8 +4,8 @@ local function active_brewing_formspec(fuel_percent, brew_percent) return "size[9,8.75]".. "background[-0.19,-0.25;9.5,9.5;mcl_brewing_inventory.png]".. - "label[4,0;"..minetest.formspec_escape(minetest.colorize("#313131", S("Brewing Stand"))).."]".. - "label[0,4.0;"..minetest.formspec_escape(minetest.colorize("#313131", S("Inventory"))).."]".. + "label[4,0;"..minetest.formspec_escape(minetest.colorize(mcl_colors.DARK_GRAY, S("Brewing Stand"))).."]".. + "label[0,4.0;"..minetest.formspec_escape(minetest.colorize(mcl_colors.DARK_GRAY, S("Inventory"))).."]".. "list[current_player;main;0,4.5;9,3;9]".. mcl_formspec.get_itemslot_bg(0,4.5,9,3).. "list[current_player;main;0,7.75;9,1;]".. @@ -35,8 +35,8 @@ end local brewing_formspec = "size[9,8.75]".. "background[-0.19,-0.25;9.5,9.5;mcl_brewing_inventory.png]".. - "label[4,0;"..minetest.formspec_escape(minetest.colorize("#313131", S("Brewing Stand"))).."]".. - "label[0,4.0;"..minetest.formspec_escape(minetest.colorize("#313131", S("Inventory"))).."]".. + "label[4,0;"..minetest.formspec_escape(minetest.colorize(mcl_colors.DARK_GRAY, S("Brewing Stand"))).."]".. + "label[0,4.0;"..minetest.formspec_escape(minetest.colorize(mcl_colors.DARK_GRAY, S("Inventory"))).."]".. "list[current_player;main;0,4.5;9,3;9]".. mcl_formspec.get_itemslot_bg(0,4.5,9,3).. "list[current_player;main;0,7.75;9,1;]".. diff --git a/mods/ITEMS/mcl_brewing/mod.conf b/mods/ITEMS/mcl_brewing/mod.conf index 2c27c979e..160319c93 100644 --- a/mods/ITEMS/mcl_brewing/mod.conf +++ b/mods/ITEMS/mcl_brewing/mod.conf @@ -1,4 +1,4 @@ name = mcl_brewing author = bzoss -depends = mcl_init, mcl_formspec, mcl_sounds, mcl_potions, mcl_mobitems +depends = mcl_init, mcl_formspec, mcl_sounds, mcl_potions, mcl_mobitems, mcl_colors optional_depends = mcl_core, doc, screwdriver diff --git a/mods/ITEMS/mcl_buckets/API.md b/mods/ITEMS/mcl_buckets/API.md index 69ee4b21d..53f7d3698 100644 --- a/mods/ITEMS/mcl_buckets/API.md +++ b/mods/ITEMS/mcl_buckets/API.md @@ -5,17 +5,17 @@ Add an API to register buckets to mcl Register a new liquid Accept folowing params: -* source_place = a string or function. +* source_place: a string or function. * string: name of the node to place * function(pos): will returns name of the node to place with pos being the placement position -* source_take = table of liquid source node names to take -* itemname = itemstring of the new bucket item (or nil if liquid is not takeable) -* inventory_image = texture of the new bucket item (ignored if itemname == nil) -* name = user-visible bucket description -* longdesc = long explanatory description (for help) -* usagehelp = short usage explanation (for help) -* tt_help = very short tooltip help -* extra_check(pos, placer) = optional function(pos) which can returns false to avoid placing the liquid. Placer is object/player who is placing the liquid, can be nil. -* groups = optional list of item groups +* source_take: table of liquid source node names to take +* itemname: itemstring of the new bucket item (or nil if liquid is not takeable) +* inventory_image: texture of the new bucket item (ignored if itemname == nil) +* name: user-visible bucket description +* longdesc: long explanatory description (for help) +* usagehelp: short usage explanation (for help) +* tt_help: very short tooltip help +* extra_check(pos, placer): (optional) function(pos) which can returns false to avoid placing the liquid. Placer is object/player who is placing the liquid, can be nil. +* groups: optional list of item groups This function can be called from any mod (which depends on this one) \ No newline at end of file diff --git a/mods/ITEMS/mcl_buckets/init.lua b/mods/ITEMS/mcl_buckets/init.lua index 9e830fd73..0ba68b723 100644 --- a/mods/ITEMS/mcl_buckets/init.lua +++ b/mods/ITEMS/mcl_buckets/init.lua @@ -65,7 +65,7 @@ function mcl_buckets.register_liquid(def) _doc_items_usagehelp = def.usagehelp, _tt_help = def.tt_help, inventory_image = def.inventory_image, - stack_max = 16, + stack_max = 1, groups = def.groups, on_place = function(itemstack, user, pointed_thing) -- Must be pointing to node @@ -92,7 +92,7 @@ function mcl_buckets.register_liquid(def) -- Check if pointing to a buildable node local item = itemstack:get_name() - if extra_check and extra_check(place_pos, user) == false then + if def.extra_check and def.extra_check(place_pos, user) == false then -- Fail placement of liquid elseif minetest.registered_nodes[nn] and minetest.registered_nodes[nn].buildable_to then -- buildable; replace the node @@ -207,6 +207,9 @@ minetest.register_craftitem("mcl_buckets:bucket_empty", { -- Fill bucket, but not in Creative Mode if not minetest.is_creative_enabled(user:get_player_name()) then new_bucket = ItemStack({name = liquiddef.itemname}) + if liquiddef.itemname == "mcl_buckets:bucket_lava" and awards and awards.unlock and user and user:is_player() then + awards.unlock(user:get_player_name(), "mcl:hotStuff") + end end minetest.add_node(pointed_thing.under, {name="air"}) diff --git a/mods/ITEMS/mcl_buckets/register.lua b/mods/ITEMS/mcl_buckets/register.lua index 1af9fcdba..b5d86ac0e 100644 --- a/mods/ITEMS/mcl_buckets/register.lua +++ b/mods/ITEMS/mcl_buckets/register.lua @@ -2,6 +2,20 @@ local S = minetest.get_translator(minetest.get_current_modname()) local mod_mcl_core = minetest.get_modpath("mcl_core") local mod_mclx_core = minetest.get_modpath("mclx_core") +local sound_place = function(itemname, pos) + local def = minetest.registered_nodes[itemname] + if def and def.sounds and def.sounds.place then + minetest.sound_play(def.sounds.place, {gain=1.0, pos = pos, pitch = 1 + math.random(-10, 10)*0.005}, true) + end +end + +local sound_take = function(itemname, pos) + local def = minetest.registered_nodes[itemname] + if def and def.sounds and def.sounds.dug then + minetest.sound_play(def.sounds.dug, {gain=1.0, pos = pos, pitch = 1 + math.random(-10, 10)*0.005}, true) + end +end + if mod_mcl_core then -- Lava bucket mcl_buckets.register_liquid({ 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/init.lua b/mods/ITEMS/mcl_cauldrons/init.lua index 5c8d93160..f4356d27b 100644 --- a/mods/ITEMS/mcl_cauldrons/init.lua +++ b/mods/ITEMS/mcl_cauldrons/init.lua @@ -131,7 +131,7 @@ minetest.register_abm({ interval = 0.5, chance = 1, action = function(pos, node) - for _, obj in ipairs(minetest.get_objects_inside_radius(pos, 0.4)) do + for _, obj in pairs(minetest.get_objects_inside_radius(pos, 0.4)) do if mcl_burning.is_burning(obj) then mcl_burning.extinguish(obj) local new_group = minetest.get_item_group(node.name, "cauldron_filled") - 1 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/init.lua b/mods/ITEMS/mcl_chests/init.lua index 852a47fec..1f3f518a4 100644 --- a/mods/ITEMS/mcl_chests/init.lua +++ b/mods/ITEMS/mcl_chests/init.lua @@ -11,10 +11,8 @@ local entity_animations = { }, chest = { speed = 25, - open = {x = 0, y = 10}, - open_partly = {x = 0, y = 7}, - close = {x = 10, y = 20}, - close_partly = {x = 13, y = 20}, + open = {x = 0, y = 7}, + close = {x = 13, y = 20}, } } @@ -34,15 +32,14 @@ minetest.register_entity("mcl_chests:chest", { self.object:set_animation(anim, anim_table.speed, 0, false) end, - open = function(self, playername, partly) + open = function(self, playername) self.players[playername] = true if not self.is_open then - self:set_animation(partly and "open_partly" or "open") + self:set_animation("open") minetest.sound_play(self.sound_prefix .. "_open", { pos = self.node_pos, }) self.is_open = true - self.opened_partly = partly end end, @@ -53,12 +50,11 @@ minetest.register_entity("mcl_chests:chest", { for _ in pairs(playerlist) do return end - self:set_animation(self.opened_partly and "close_partly" or "close") + self:set_animation("close") minetest.sound_play(self.sound_prefix .. "_close", { pos = self.node_pos, }) self.is_open = false - self.opened_partly = false end end, @@ -118,7 +114,7 @@ local function get_entity_pos(pos, dir, double) end local function find_entity(pos) - for _, obj in ipairs(minetest.get_objects_inside_radius(pos, 0)) do + for _, obj in pairs(minetest.get_objects_inside_radius(pos, 0)) do local luaentity = obj:get_luaentity() if luaentity and luaentity.name == "mcl_chests:chest" then return luaentity @@ -179,8 +175,7 @@ local player_chest_open = function(player, pos, node_name, textures, param2, dou open_chests[name] = {pos = pos, node_name = node_name, textures = textures, param2 = param2, double = double, sound = sound, mesh = mesh, shulker = shulker} if animate_chests then local dir = minetest.facedir_to_dir(param2) - local blocked = not shulker and (back_is_blocked(pos, dir) or double and back_is_blocked(mcl_util.get_double_container_neighbor_pos(pos, param2, node_name:sub(-4)), dir)) - find_or_create_entity(pos, node_name, textures, param2, double, sound, mesh, shulker and "shulker" or "chest", dir):open(name, blocked) + find_or_create_entity(pos, node_name, textures, param2, double, sound, mesh, shulker and "shulker" or "chest", dir):open(name) end end @@ -480,10 +475,10 @@ minetest.register_node(small_name, { minetest.show_formspec(clicker:get_player_name(), "mcl_chests:"..canonical_basename.."_"..pos.x.."_"..pos.y.."_"..pos.z, "size[9,8.75]".. - "label[0,0;"..minetest.formspec_escape(minetest.colorize("#313131", name)).."]".. + "label[0,0;"..minetest.formspec_escape(minetest.colorize(mcl_colors.DARK_GRAY, name)).."]".. "list[nodemeta:"..pos.x..","..pos.y..","..pos.z..";main;0,0.5;9,3;]".. mcl_formspec.get_itemslot_bg(0,0.5,9,3).. - "label[0,4.0;"..minetest.formspec_escape(minetest.colorize("#313131", S("Inventory"))).."]".. + "label[0,4.0;"..minetest.formspec_escape(minetest.colorize(mcl_colors.DARK_GRAY, S("Inventory"))).."]".. "list[current_player;main;0,4.5;9,3;9]".. mcl_formspec.get_itemslot_bg(0,4.5,9,3).. "list[current_player;main;0,7.74;9,1;]".. @@ -629,12 +624,12 @@ minetest.register_node(left_name, { minetest.show_formspec(clicker:get_player_name(), "mcl_chests:"..canonical_basename.."_"..pos.x.."_"..pos.y.."_"..pos.z, "size[9,11.5]".. - "label[0,0;"..minetest.formspec_escape(minetest.colorize("#313131", name)).."]".. + "label[0,0;"..minetest.formspec_escape(minetest.colorize(mcl_colors.DARK_GRAY, name)).."]".. "list[nodemeta:"..pos.x..","..pos.y..","..pos.z..";main;0,0.5;9,3;]".. mcl_formspec.get_itemslot_bg(0,0.5,9,3).. "list[nodemeta:"..pos_other.x..","..pos_other.y..","..pos_other.z..";main;0,3.5;9,3;]".. mcl_formspec.get_itemslot_bg(0,3.5,9,3).. - "label[0,7;"..minetest.formspec_escape(minetest.colorize("#313131", S("Inventory"))).."]".. + "label[0,7;"..minetest.formspec_escape(minetest.colorize(mcl_colors.DARK_GRAY, S("Inventory"))).."]".. "list[current_player;main;0,7.5;9,3;9]".. mcl_formspec.get_itemslot_bg(0,7.5,9,3).. "list[current_player;main;0,10.75;9,1;]".. @@ -778,12 +773,12 @@ minetest.register_node("mcl_chests:"..basename.."_right", { "mcl_chests:"..canonical_basename.."_"..pos.x.."_"..pos.y.."_"..pos.z, "size[9,11.5]".. - "label[0,0;"..minetest.formspec_escape(minetest.colorize("#313131", name)).."]".. + "label[0,0;"..minetest.formspec_escape(minetest.colorize(mcl_colors.DARK_GRAY, name)).."]".. "list[nodemeta:"..pos_other.x..","..pos_other.y..","..pos_other.z..";main;0,0.5;9,3;]".. mcl_formspec.get_itemslot_bg(0,0.5,9,3).. "list[nodemeta:"..pos.x..","..pos.y..","..pos.z..";main;0,3.5;9,3;]".. mcl_formspec.get_itemslot_bg(0,3.5,9,3).. - "label[0,7;"..minetest.formspec_escape(minetest.colorize("#313131", S("Inventory"))).."]".. + "label[0,7;"..minetest.formspec_escape(minetest.colorize(mcl_colors.DARK_GRAY, S("Inventory"))).."]".. "list[current_player;main;0,7.5;9,3;9]".. mcl_formspec.get_itemslot_bg(0,7.5,9,3).. "list[current_player;main;0,10.75;9,1;]".. @@ -991,10 +986,10 @@ minetest.register_node("mcl_chests:ender_chest", { }) local formspec_ender_chest = "size[9,8.75]".. - "label[0,0;"..minetest.formspec_escape(minetest.colorize("#313131", S("Ender Chest"))).."]".. + "label[0,0;"..minetest.formspec_escape(minetest.colorize(mcl_colors.DARK_GRAY, S("Ender Chest"))).."]".. "list[current_player;enderchest;0,0.5;9,3;]".. mcl_formspec.get_itemslot_bg(0,0.5,9,3).. - "label[0,4.0;"..minetest.formspec_escape(minetest.colorize("#313131", S("Inventory"))).."]".. + "label[0,4.0;"..minetest.formspec_escape(minetest.colorize(mcl_colors.DARK_GRAY, S("Inventory"))).."]".. "list[current_player;main;0,4.5;9,3;9]".. mcl_formspec.get_itemslot_bg(0,4.5,9,3).. "list[current_player;main;0,7.74;9,1;]".. @@ -1109,10 +1104,10 @@ local function formspec_shulker_box(name) name = S("Shulker Box") end return "size[9,8.75]".. - "label[0,0;"..minetest.formspec_escape(minetest.colorize("#313131", name)).."]".. + "label[0,0;"..minetest.formspec_escape(minetest.colorize(mcl_colors.DARK_GRAY, name)).."]".. "list[current_name;main;0,0.5;9,3;]".. mcl_formspec.get_itemslot_bg(0,0.5,9,3).. - "label[0,4.0;"..minetest.formspec_escape(minetest.colorize("#313131", S("Inventory"))).."]".. + "label[0,4.0;"..minetest.formspec_escape(minetest.colorize(mcl_colors.DARK_GRAY, S("Inventory"))).."]".. "list[current_player;main;0,4.5;9,3;9]".. mcl_formspec.get_itemslot_bg(0,4.5,9,3).. "list[current_player;main;0,7.74;9,1;]".. diff --git a/mods/ITEMS/mcl_chests/mod.conf b/mods/ITEMS/mcl_chests/mod.conf new file mode 100644 index 000000000..609b1fff9 --- /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, mcl_colors +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/init.lua b/mods/ITEMS/mcl_clock/init.lua index 0532bf5f7..d53d75076 100644 --- a/mods/ITEMS/mcl_clock/init.lua +++ b/mods/ITEMS/mcl_clock/init.lua @@ -94,9 +94,8 @@ minetest.register_globalstep(function(dtime) watch.old_time = now - local players = minetest.get_connected_players() - for p, player in ipairs(players) do - for s, stack in ipairs(player:get_inventory():get_list("main")) do + for p, player in pairs(minetest.get_connected_players()) do + for s, stack in pairs(player:get_inventory():get_list("main")) do local dim = mcl_worlds.pos_to_dimension(player:get_pos()) local frame -- Clocks do not work in certain zones 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/init.lua b/mods/ITEMS/mcl_compass/init.lua index b0cf5627e..f15459303 100644 --- a/mods/ITEMS/mcl_compass/init.lua +++ b/mods/ITEMS/mcl_compass/init.lua @@ -14,15 +14,14 @@ local random_frame = math.random(0, compass_frames-1) minetest.register_globalstep(function(dtime) random_timer = random_timer + dtime - local players = minetest.get_connected_players() if random_timer >= random_timer_trigger then random_frame = (random_frame + math.random(-1, 1)) % compass_frames random_timer = 0 end - for i,player in ipairs(players) do + for i,player in pairs(minetest.get_connected_players()) do local function has_compass(player) - for _,stack in ipairs(player:get_inventory():get_list("main")) do + for _,stack in pairs(player:get_inventory():get_list("main")) do if minetest.get_item_group(stack:get_name(), "compass") ~= 0 then return true end @@ -53,7 +52,7 @@ minetest.register_globalstep(function(dtime) compass_image = math.floor((angle_relative/11.25) + 0.5) % compass_frames end - for j,stack in ipairs(player:get_inventory():get_list("main")) do + for j,stack in pairs(player:get_inventory():get_list("main")) do if minetest.get_item_group(stack:get_name(), "compass") ~= 0 and minetest.get_item_group(stack:get_name(), "compass")-1 ~= compass_image then local itemname = "mcl_compass:"..compass_image 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/functions.lua b/mods/ITEMS/mcl_core/functions.lua index 3d47336f3..0c25de94f 100644 --- a/mods/ITEMS/mcl_core/functions.lua +++ b/mods/ITEMS/mcl_core/functions.lua @@ -1378,7 +1378,7 @@ minetest.register_abm({ if not do_preserve then -- Drop stuff other than the node itself local itemstacks = minetest.get_node_drops(n0.name) - for _, itemname in ipairs(itemstacks) do + for _, itemname in pairs(itemstacks) do local p_drop = { x = p0.x - 0.5 + math.random(), y = p0.y - 0.5 + math.random(), 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..45018df75 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, mcl_colors +optional_depends = doc diff --git a/mods/ITEMS/mcl_core/nodes_base.lua b/mods/ITEMS/mcl_core/nodes_base.lua index cc6a0e6ae..4477f0377 100644 --- a/mods/ITEMS/mcl_core/nodes_base.lua +++ b/mods/ITEMS/mcl_core/nodes_base.lua @@ -33,6 +33,11 @@ minetest.register_node("mcl_core:stone", { _mcl_blast_resistance = 6, _mcl_hardness = 1.5, _mcl_silk_touch_drop = true, + after_dig_node = function(pos, oldnode, oldmetadata, digger) + if awards and awards.unlock and digger and digger:is_player() then + awards.unlock(digger:get_player_name(), "mcl:stoneAge") + end + end, }) minetest.register_node("mcl_core:stone_with_coal", { @@ -808,12 +813,17 @@ minetest.register_node("mcl_core:obsidian", { description = S("Obsidian"), _doc_items_longdesc = S("Obsidian is an extremely hard mineral with an enourmous blast-resistance. Obsidian is formed when water meets lava."), tiles = {"default_obsidian.png"}, - is_ground_content = true, + is_ground_content = false, sounds = mcl_sounds.node_sound_stone_defaults(), stack_max = 64, groups = {pickaxey=5, building_block=1, material_stone=1}, _mcl_blast_resistance = 1200, _mcl_hardness = 50, + after_dig_node = function(pos, oldnode, oldmetadata, digger) + if awards and awards.unlock and digger and digger:is_player() then + awards.unlock(digger:get_player_name(), "mcl:obsidian") + end + end, }) minetest.register_node("mcl_core:ice", { diff --git a/mods/ITEMS/mcl_core/nodes_cactuscane.lua b/mods/ITEMS/mcl_core/nodes_cactuscane.lua index d1bcac011..4ec005170 100644 --- a/mods/ITEMS/mcl_core/nodes_cactuscane.lua +++ b/mods/ITEMS/mcl_core/nodes_cactuscane.lua @@ -4,7 +4,7 @@ local S = minetest.get_translator("mcl_core") minetest.register_node("mcl_core:cactus", { description = S("Cactus"), - _tt_help = S("Grows on sand").."\n"..minetest.colorize("#FFFF00", S("Contact damage: @1 per half second", 1)), + _tt_help = S("Grows on sand").."\n"..minetest.colorize(mcl_colors.YELLOW, S("Contact damage: @1 per half second", 1)), _doc_items_longdesc = S("This is a piece of cactus commonly found in dry areas, especially deserts. Over time, cacti will grow up to 3 blocks high on sand or red sand. A cactus hurts living beings touching it with a damage of 1 HP every half second. When a cactus block is broken, all cactus blocks connected above it will break as well."), _doc_items_usagehelp = S("A cactus can only be placed on top of another cactus or any sand."), drawtype = "nodebox", diff --git a/mods/ITEMS/mcl_core/nodes_misc.lua b/mods/ITEMS/mcl_core/nodes_misc.lua index 305682244..8b36f0696 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(), @@ -236,7 +236,7 @@ minetest.register_node("mcl_core:realm_barrier", { -- Prevent placement to protect player from screwing up the world, because the node is not pointable and hard to get rid of. node_placement_prediction = "", on_place = function(pos, placer, itemstack, pointed_thing) - minetest.chat_send_player(placer:get_player_name(), minetest.colorize("#FF0000", "You can't just place a realm barrier by hand!")) + minetest.chat_send_player(placer:get_player_name(), minetest.colorize(mcl_colors.RED, "You can't just place a realm barrier by hand!")) return end, }) @@ -266,7 +266,7 @@ minetest.register_node("mcl_core:void", { -- Prevent placement to protect player from screwing up the world, because the node is not pointable and hard to get rid of. node_placement_prediction = "", on_place = function(pos, placer, itemstack, pointed_thing) - minetest.chat_send_player(placer:get_player_name(), minetest.colorize("#FF0000", "You can't just place the void by hand!")) + minetest.chat_send_player(placer:get_player_name(), minetest.colorize(mcl_colors.RED, "You can't just place the void by hand!")) return end, drop = "", 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_crafting_table/API.md b/mods/ITEMS/mcl_crafting_table/API.md new file mode 100644 index 000000000..45aa0c9ce --- /dev/null +++ b/mods/ITEMS/mcl_crafting_table/API.md @@ -0,0 +1,6 @@ +# mcl_crafting_table +Add a node which allow players to craft more complex things. + +## mcl_crafting_table.show_crafting_form(player) +Show the crafting form to a player. +Used in the node registration, but can be used by external mods. \ No newline at end of file diff --git a/mods/ITEMS/mcl_crafting_table/init.lua b/mods/ITEMS/mcl_crafting_table/init.lua index 4ad581774..6df4c2544 100644 --- a/mods/ITEMS/mcl_crafting_table/init.lua +++ b/mods/ITEMS/mcl_crafting_table/init.lua @@ -2,7 +2,7 @@ local S = minetest.get_translator("mcl_crafting_table") local formspec_escape = minetest.formspec_escape local show_formspec = minetest.show_formspec local C = minetest.colorize -local text_color = mcl_colors.BLACK or "#313131" +local text_color = mcl_colors.DARK_GRAY local itemslot_bg = mcl_formspec.get_itemslot_bg mcl_crafting_table = {} @@ -13,7 +13,7 @@ function mcl_crafting_table.show_crafting_form(player) show_formspec(player:get_player_name(), "main", "size[9,8.75]".. "image[4.7,1.5;1.5,1;gui_crafting_arrow.png]".. - "label[0,4;"..formspec_escape(C(text_color, S("Inventory"))).."]".. --"#313131" + "label[0,4;"..formspec_escape(C(text_color, S("Inventory"))).."]".. "list[current_player;main;0,4.5;9,3;9]".. itemslot_bg(0,4.5,9,3).. "list[current_player;main;0,7.74;9,1;]".. diff --git a/mods/ITEMS/mcl_crafting_table/mod.conf b/mods/ITEMS/mcl_crafting_table/mod.conf index 03b3174ab..149d1c982 100644 --- a/mods/ITEMS/mcl_crafting_table/mod.conf +++ b/mods/ITEMS/mcl_crafting_table/mod.conf @@ -1,4 +1,3 @@ name = mcl_crafting_table description = Adds a crafting table. -depends = mcl_init, mcl_formspec, mcl_sounds -optional_depends = mcl_colors +depends = mcl_init, mcl_formspec, mcl_sounds, mcl_colors diff --git a/mods/ITEMS/mcl_doors/api_doors.lua b/mods/ITEMS/mcl_doors/api_doors.lua index 716fb22ec..f3dd0f469 100644 --- a/mods/ITEMS/mcl_doors/api_doors.lua +++ b/mods/ITEMS/mcl_doors/api_doors.lua @@ -4,7 +4,7 @@ local S = minetest.get_translator("mcl_doors") local function on_place_node(place_to, newnode, placer, oldnode, itemstack, pointed_thing) -- Run script hook - for _, callback in ipairs(minetest.registered_on_placenodes) do + for _, callback in pairs(minetest.registered_on_placenodes) do -- Deep-copy pos, node and pointed_thing because callback can modify them local place_to_copy = {x = place_to.x, y = place_to.y, z = place_to.z} local newnode_copy = 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..ea69d1868 100644 --- a/mods/ITEMS/mcl_enchanting/engine.lua +++ b/mods/ITEMS/mcl_enchanting/engine.lua @@ -52,7 +52,7 @@ function mcl_enchanting.get_enchantment_description(enchantment, level) end function mcl_enchanting.get_colorized_enchantment_description(enchantment, level) - return minetest.colorize(mcl_enchanting.enchantments[enchantment].curse and "#FC5454" or "#A8A8A8", mcl_enchanting.get_enchantment_description(enchantment, level)) + return minetest.colorize(mcl_enchanting.enchantments[enchantment].curse and mcl_colors.RED or mcl_colors.GRAY, mcl_enchanting.get_enchantment_description(enchantment, level)) end function mcl_enchanting.get_enchanted_itemstring(itemname) @@ -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 @@ -435,13 +468,13 @@ function mcl_enchanting.show_enchanting_formspec(player) local formspec = "" .. "size[9.07,8.6;]" .. "formspec_version[3]" - .. "label[0,0;" .. C("#313131") .. F(table_name) .. "]" + .. "label[0,0;" .. C(mcl_colors.DARK_GRAY) .. F(table_name) .. "]" .. mcl_formspec.get_itemslot_bg(0.2, 2.4, 1, 1) .. "list[current_player;enchanting_item;0.2,2.4;1,1]" .. mcl_formspec.get_itemslot_bg(1.1, 2.4, 1, 1) .. "image[1.1,2.4;1,1;mcl_enchanting_lapis_background.png]" .. "list[current_player;enchanting_lapis;1.1,2.4;1,1]" - .. "label[0,4;" .. C("#313131") .. F(S("Inventory")).."]" + .. "label[0,4;" .. C(mcl_colors.DARK_GRAY) .. F(S("Inventory")).."]" .. mcl_formspec.get_itemslot_bg(0, 4.5, 9, 3) .. mcl_formspec.get_itemslot_bg(0, 7.74, 9, 1) .. "list[current_player;main;0,4.5;9,3;9]" @@ -468,11 +501,11 @@ function mcl_enchanting.show_enchanting_formspec(player) local hover_ending = (can_enchant and "_hovered" or "_off") formspec = formspec .. "container[3.2," .. y .. "]" - .. (slot and "tooltip[button_" .. i .. ";" .. C("#818181") .. F(slot.description) .. " " .. C("#FFFFFF") .. " . . . ?\n\n" .. (enough_levels and C(enough_lapis and "#818181" or "#FC5454") .. F(S("@1 Lapis Lazuli", i)) .. "\n" .. C("#818181") .. F(S("@1 Enchantment Levels", i)) or C("#FC5454") .. F(S("Level requirement: @1", slot.level_requirement))) .. "]" or "") + .. (slot and "tooltip[button_" .. i .. ";" .. C(mcl_colors.GRAY) .. F(slot.description) .. " " .. C(mcl_colors.WHITE) .. " . . . ?\n\n" .. (enough_levels and C(enough_lapis and mcl_colors.GRAY or mcl_colors.RED) .. F(S("@1 Lapis Lazuli", i)) .. "\n" .. C(mcl_colors.GRAY) .. F(S("@1 Enchantment Levels", i)) or C(mcl_colors.RED) .. F(S("Level requirement: @1", slot.level_requirement))) .. "]" or "") .. "style[button_" .. i .. ";bgimg=mcl_enchanting_button" .. ending .. ".png;bgimg_hovered=mcl_enchanting_button" .. hover_ending .. ".png;bgimg_pressed=mcl_enchanting_button" .. hover_ending .. ".png]" .. "button[0,0;7.5,1.3;button_" .. i .. ";]" .. (slot and "image[0,0;1.3,1.3;mcl_enchanting_number_" .. i .. ending .. ".png]" or "") - .. (slot and "label[7.2,1.1;" .. C(can_enchant and "#80FF20" or "#407F10") .. slot.level_requirement .. "]" or "") + .. (slot and "label[7.2,1.1;" .. C(can_enchant and mcl_colors.GREEN or mcl_colors.DARK_GREEN) .. slot.level_requirement .. "]" or "") .. (slot and slot.glyphs or "") .. "container_end[]" y = y + 1.35 @@ -549,7 +582,12 @@ function mcl_enchanting.allow_inventory_action(player, action, inventory, invent local listname = inventory_info.to_list local stack = inventory:get_stack(inventory_info.from_list, inventory_info.from_index) if stack:get_name() == "mcl_dye:blue" and listname ~= "enchanting_item" then - return math.min(inventory:get_stack("enchanting_lapis", 1):get_free_space(), stack:get_count()) + local count = stack:get_count() + local old_stack = inventory:get_stack("enchanting_lapis", 1) + if old_stack:get_name() ~= "" then + count = math.min(count, old_stack:get_free_space()) + end + return count elseif inventory:get_stack("enchanting_item", 1):get_count() == 0 and listname ~= "enchanting_lapis" then return 1 else diff --git a/mods/ITEMS/mcl_enchanting/groupcaps.lua b/mods/ITEMS/mcl_enchanting/groupcaps.lua new file mode 100644 index 000000000..375029547 --- /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_meta():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 a53350a70..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", { @@ -191,7 +192,7 @@ minetest.register_entity("mcl_enchanting:book", { local old_player_near = self._player_near local player_near = false local player - for _, obj in ipairs(minetest.get_objects_inside_radius(vector.subtract(self.object:get_pos(), mcl_enchanting.book_offset), 2.5)) do + for _, obj in pairs(minetest.get_objects_inside_radius(vector.subtract(self.object:get_pos(), mcl_enchanting.book_offset), 2.5)) do if obj:is_player() then player_near = true player = obj @@ -308,7 +309,7 @@ minetest.register_abm({ nodenames = "mcl_enchanting:table", action = function(pos) local playernames = {} - for _, obj in ipairs(minetest.get_objects_inside_radius(pos, 15)) do + for _, obj in pairs(minetest.get_objects_inside_radius(pos, 15)) do if obj:is_player() then table.insert(playernames, obj:get_player_name()) end diff --git a/mods/ITEMS/mcl_enchanting/mod.conf b/mods/ITEMS/mcl_enchanting/mod.conf index ac4dad644..4d4741fb8 100644 --- a/mods/ITEMS/mcl_enchanting/mod.conf +++ b/mods/ITEMS/mcl_enchanting/mod.conf @@ -1,5 +1,5 @@ name = mcl_enchanting description = Enchanting for MineClone2 -depends = tt, walkover, mcl_sounds +depends = tt, walkover, mcl_sounds, mcl_colors optional_depends = screwdriver author = Fleckenstein diff --git a/mods/ITEMS/mcl_end/chorus_plant.lua b/mods/ITEMS/mcl_end/chorus_plant.lua index 1363debf7..9622e618f 100644 --- a/mods/ITEMS/mcl_end/chorus_plant.lua +++ b/mods/ITEMS/mcl_end/chorus_plant.lua @@ -419,7 +419,7 @@ mcl_end.grow_chorus_plant_step = function(pos, node) end end - for _, f in ipairs(new_flowers) do + for _, f in pairs(new_flowers) do if age >= MAX_FLOWER_AGE then local nn = minetest.get_node(f).name if nn ~= "mcl_end:chorus_flower" and nn ~= "mcl_end:chorus_flower_dead" then diff --git a/mods/ITEMS/mcl_end/end_crystal.lua b/mods/ITEMS/mcl_end/end_crystal.lua index c07ff7930..b6b9fdd6a 100644 --- a/mods/ITEMS/mcl_end/end_crystal.lua +++ b/mods/ITEMS/mcl_end/end_crystal.lua @@ -77,7 +77,7 @@ minetest.register_entity("mcl_end:crystal", { _exploded = false, _hittable_by_projectile = true }) - + minetest.register_craftitem("mcl_end:crystal", { inventory_image = "mcl_end_crystal_item.png", description = S("End Crystal"), @@ -85,10 +85,16 @@ 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 + end + end if find_crystal(pos) then return itemstack end - if node == "mcl_core:obsidian" or node == "mcl_core:bedrock" then - if not minetest.is_creative_enabled(placer:get_player_name()) 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 spawn_crystal(pos) @@ -110,5 +116,5 @@ minetest.register_craft({ {"mcl_core:glass", "mcl_mobitems:ghast_tear", "mcl_core:glass"}, } }) - + minetest.register_alias("mcl_end_crystal:end_crystal", "mcl_end:crystal") diff --git a/mods/ITEMS/mcl_end/eye_of_ender.lua b/mods/ITEMS/mcl_end/eye_of_ender.lua index 16f1c906b..afac9ebfc 100644 --- a/mods/ITEMS/mcl_end/eye_of_ender.lua +++ b/mods/ITEMS/mcl_end/eye_of_ender.lua @@ -29,7 +29,7 @@ minetest.register_entity("mcl_end:ender_eye", { if self._age >= 3 then -- End of life local r = math.random(1,5) - if r == 1 or minetest.is_creative_enabled("") then + if r == 1 then -- 20% chance to get destroyed completely. -- 100% if in Creative Mode self.object:remove() 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..9ab36c39f 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, mcl_colors +optional_depends = mcl_armor, doc diff --git a/mods/ITEMS/mcl_farming/potatoes.lua b/mods/ITEMS/mcl_farming/potatoes.lua index 871d67963..a7f5a7084 100644 --- a/mods/ITEMS/mcl_farming/potatoes.lua +++ b/mods/ITEMS/mcl_farming/potatoes.lua @@ -118,7 +118,7 @@ minetest.register_craftitem("mcl_farming:potato_item_baked", { minetest.register_craftitem("mcl_farming:potato_item_poison", { description = S("Poisonous Potato"), - _tt_help = minetest.colorize("#FFFF00", S("60% chance of poisoning")), + _tt_help = minetest.colorize(mcl_colors.YELLOW, S("60% chance of poisoning")), _doc_items_longdesc = S("This potato doesn't look too healthy. You can eat it to restore hunger points, but there's a 60% chance it will poison you briefly."), stack_max = 64, inventory_image = "farming_potato_poison.png", 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/init.lua b/mods/ITEMS/mcl_fishing/init.lua index 1ff56c277..228d490ea 100644 --- a/mods/ITEMS/mcl_fishing/init.lua +++ b/mods/ITEMS/mcl_fishing/init.lua @@ -173,7 +173,7 @@ local fish = function(itemstack, player, pointed_thing) if noent == true then local playerpos = player:get_pos() local dir = player:get_look_dir() - local obj = mcl_throwing.throw("mcl_throwing:flying_bobber", {x=playerpos.x, y=playerpos.y+1.5, z=playerpos.z}, dir, 15, player:get_player_name()) + local obj = mcl_throwing.throw("mcl_fishing:flying_bobber", {x=playerpos.x, y=playerpos.y+1.5, z=playerpos.z}, dir, 15, player:get_player_name()) end end @@ -295,6 +295,52 @@ bobber_ENTITY.on_step = bobber_on_step minetest.register_entity("mcl_fishing:bobber_entity", bobber_ENTITY) +local flying_bobber_ENTITY={ + physical = false, + timer=0, + textures = {"mcl_fishing_bobber.png"}, --FIXME: Replace with correct texture. + visual_size = {x=0.5, y=0.5}, + collisionbox = {0,0,0,0,0,0}, + pointable = false, + + get_staticdata = get_staticdata, + on_activate = on_activate, + + _lastpos={}, + _thrower = nil, + objtype="fishing", +} + +-- Movement function of flying bobber +local flying_bobber_on_step = function(self, dtime) + self.timer=self.timer+dtime + local pos = self.object:get_pos() + local node = minetest.get_node(pos) + local def = minetest.registered_nodes[node.name] + --local player = minetest.get_player_by_name(self._thrower) + + -- Destroy when hitting a solid node + if self._lastpos.x~=nil then + if (def and (def.walkable or def.liquidtype == "flowing" or def.liquidtype == "source")) or not def then + local make_child= function(object) + local ent = object:get_luaentity() + ent.player = self._thrower + ent.child = true + end + make_child(minetest.add_entity(self._lastpos, "mcl_fishing:bobber_entity")) + self.object:remove() + return + end + end + self._lastpos={x=pos.x, y=pos.y, z=pos.z} -- Set lastpos-->Node will be added at last pos outside the node +end + +flying_bobber_ENTITY.on_step = flying_bobber_on_step + +minetest.register_entity("mcl_fishing:flying_bobber_entity", flying_bobber_ENTITY) + +mcl_throwing.register_throwable_object("mcl_fishing:flying_bobber", "mcl_fishing:flying_bobber_entity", 5) + -- If player leaves area, remove bobber. minetest.register_on_leaveplayer(function(player) local objs = minetest.get_objects_inside_radius(player:get_pos(), 250) @@ -449,7 +495,7 @@ minetest.register_craftitem("mcl_fishing:clownfish_raw", { minetest.register_craftitem("mcl_fishing:pufferfish_raw", { description = S("Pufferfish"), - _tt_help = minetest.colorize("#FFFF00", S("Very poisonous")), + _tt_help = minetest.colorize(mcl_colors.YELLOW, S("Very poisonous")), _doc_items_longdesc = S("Pufferfish are a common species of fish and can be obtained by fishing. They can technically be eaten, but they are very bad for humans. Eating a pufferfish only restores 1 hunger point and will poison you very badly (which drains your health non-fatally) and causes serious food poisoning (which increases your hunger)."), inventory_image = "mcl_fishing_pufferfish_raw.png", on_place = minetest.item_eat(1), diff --git a/mods/ITEMS/mcl_fishing/mod.conf b/mods/ITEMS/mcl_fishing/mod.conf index 3a02c5cfc..c4e5f5f2e 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, mcl_throwing, mcl_colors 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..1d1ecc031 100644 --- a/mods/ITEMS/mcl_furnaces/init.lua +++ b/mods/ITEMS/mcl_furnaces/init.lua @@ -9,12 +9,12 @@ local LIGHT_ACTIVE_FURNACE = 13 local function active_formspec(fuel_percent, item_percent) return "size[9,8.75]".. - "label[0,4;"..minetest.formspec_escape(minetest.colorize("#313131", S("Inventory"))).."]".. + "label[0,4;"..minetest.formspec_escape(minetest.colorize(mcl_colors.DARK_GRAY, S("Inventory"))).."]".. "list[current_player;main;0,4.5;9,3;9]".. mcl_formspec.get_itemslot_bg(0,4.5,9,3).. "list[current_player;main;0,7.74;9,1;]".. mcl_formspec.get_itemslot_bg(0,7.74,9,1).. - "label[2.75,0;"..minetest.formspec_escape(minetest.colorize("#313131", S("Furnace"))).."]".. + "label[2.75,0;"..minetest.formspec_escape(minetest.colorize(mcl_colors.DARK_GRAY, S("Furnace"))).."]".. "list[current_name;src;2.75,0.5;1,1;]".. mcl_formspec.get_itemslot_bg(2.75,0.5,1,1).. "list[current_name;fuel;2.75,2.5;1,1;]".. @@ -38,12 +38,12 @@ local function active_formspec(fuel_percent, item_percent) end local inactive_formspec = "size[9,8.75]".. - "label[0,4;"..minetest.formspec_escape(minetest.colorize("#313131", S("Inventory"))).."]".. + "label[0,4;"..minetest.formspec_escape(minetest.colorize(mcl_colors.DARK_GRAY, S("Inventory"))).."]".. "list[current_player;main;0,4.5;9,3;9]".. mcl_formspec.get_itemslot_bg(0,4.5,9,3).. "list[current_player;main;0,7.74;9,1;]".. mcl_formspec.get_itemslot_bg(0,7.74,9,1).. - "label[2.75,0;"..minetest.formspec_escape(minetest.colorize("#313131", S("Furnace"))).."]".. + "label[2.75,0;"..minetest.formspec_escape(minetest.colorize(mcl_colors.DARK_GRAY, S("Furnace"))).."]".. "list[current_name;src;2.75,0.5;1,1;]".. mcl_formspec.get_itemslot_bg(2.75,0.5,1,1).. "list[current_name;fuel;2.75,2.5;1,1;]".. @@ -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..99a1ad0bf 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, mcl_colors +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/init.lua b/mods/ITEMS/mcl_hoppers/init.lua index 52cb60874..e9b3f75e0 100644 --- a/mods/ITEMS/mcl_hoppers/init.lua +++ b/mods/ITEMS/mcl_hoppers/init.lua @@ -4,10 +4,10 @@ local S = minetest.get_translator("mcl_hoppers") local mcl_hoppers_formspec = "size[9,7]".. - "label[2,0;"..minetest.formspec_escape(minetest.colorize("#313131", S("Hopper"))).."]".. + "label[2,0;"..minetest.formspec_escape(minetest.colorize(mcl_colors.DARK_GRAY, S("Hopper"))).."]".. "list[current_name;main;2,0.5;5,1;]".. mcl_formspec.get_itemslot_bg(2,0.5,5,1).. - "label[0,2;"..minetest.formspec_escape(minetest.colorize("#313131", S("Inventory"))).."]".. + "label[0,2;"..minetest.formspec_escape(minetest.colorize(mcl_colors.DARK_GRAY, S("Inventory"))).."]".. "list[current_player;main;0,2.5;9,3;9]".. mcl_formspec.get_itemslot_bg(0,2.5,9,3).. "list[current_player;main;0,5.74;9,1;]".. @@ -349,7 +349,7 @@ minetest.register_abm({ local meta = minetest.get_meta(pos) local inv = meta:get_inventory() - for _,object in ipairs(minetest.get_objects_inside_radius(pos, 2)) do + for _,object in pairs(minetest.get_objects_inside_radius(pos, 2)) do if not object:is_player() and object:get_luaentity() and object:get_luaentity().name == "__builtin:item" then if inv and inv:room_for_item("main", ItemStack(object:get_luaentity().itemstring)) then -- Item must get sucked in when the item just TOUCHES the block above the hopper diff --git a/mods/ITEMS/mcl_hoppers/mod.conf b/mods/ITEMS/mcl_hoppers/mod.conf new file mode 100644 index 000000000..53f514f39 --- /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, mcl_colors +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_jukebox/init.lua b/mods/ITEMS/mcl_jukebox/init.lua index c5bd3d268..067848f50 100644 --- a/mods/ITEMS/mcl_jukebox/init.lua +++ b/mods/ITEMS/mcl_jukebox/init.lua @@ -20,8 +20,8 @@ function mcl_jukebox.register_record(title, author, identifier, image, sound) local usagehelp = S("Place a music disc into an empty jukebox to play the music. Use the jukebox again to retrieve the music disc. The music can only be heard by you, not by other players.") minetest.register_craftitem(":mcl_jukebox:record_"..identifier, { description = - core.colorize("#55FFFF", S("Music Disc")) .. "\n" .. - core.colorize("#989898", S("@1—@2", author, title)), + core.colorize(mcl_colors.AQUA, S("Music Disc")) .. "\n" .. + core.colorize(mcl_colors.GRAY, S("@1—@2", author, title)), _doc_items_create_entry = true, _doc_items_entry_name = entryname, _doc_items_longdesc = longdesc, diff --git a/mods/ITEMS/mcl_jukebox/mod.conf b/mods/ITEMS/mcl_jukebox/mod.conf index ad1f8c06a..9046ff7d3 100644 --- a/mods/ITEMS/mcl_jukebox/mod.conf +++ b/mods/ITEMS/mcl_jukebox/mod.conf @@ -1,3 +1,3 @@ name = mcl_jukebox description = Jukebox and music discs are used to play background music on a per-player basis. -depends = mcl_core, mcl_sounds +depends = mcl_core, mcl_sounds, mcl_colors 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/init.lua b/mods/ITEMS/mcl_mobitems/init.lua index 650e40ac3..1b7929722 100644 --- a/mods/ITEMS/mcl_mobitems/init.lua +++ b/mods/ITEMS/mcl_mobitems/init.lua @@ -2,7 +2,7 @@ local S = minetest.get_translator("mcl_mobitems") minetest.register_craftitem("mcl_mobitems:rotten_flesh", { description = S("Rotten Flesh"), - _tt_help = minetest.colorize("#FFFF00", S("80% chance of food poisoning")), + _tt_help = minetest.colorize(mcl_colors.YELLOW, S("80% chance of food poisoning")), _doc_items_longdesc = S("Yuck! This piece of flesh clearly has seen better days. If you're really desperate, you can eat it to restore a few hunger points, but there's a 80% chance it causes food poisoning, which increases your hunger for a while."), inventory_image = "mcl_mobitems_rotten_flesh.png", wield_image = "mcl_mobitems_rotten_flesh.png", @@ -63,7 +63,7 @@ minetest.register_craftitem("mcl_mobitems:cooked_beef", { minetest.register_craftitem("mcl_mobitems:chicken", { description = S("Raw Chicken"), - _tt_help = minetest.colorize("#FFFF00", S("30% chance of food poisoning")), + _tt_help = minetest.colorize(mcl_colors.YELLOW, S("30% chance of food poisoning")), _doc_items_longdesc = S("Raw chicken is a food item which is not safe to consume. You can eat it to restore a few hunger points, but there's a 30% chance to suffer from food poisoning, which increases your hunger rate for a while. Cooking raw chicken will make it safe to eat and increases its nutritional value."), inventory_image = "mcl_mobitems_chicken_raw.png", wield_image = "mcl_mobitems_chicken_raw.png", @@ -147,7 +147,7 @@ end minetest.register_craftitem("mcl_mobitems:milk_bucket", { description = S("Milk"), - _tt_help = minetest.colorize("#00FF00", S("Removes all status effects")), + _tt_help = minetest.colorize(mcl_colors.GREEN, S("Removes all status effects")), _doc_items_longdesc = S("Milk is very refreshing and can be obtained by using a bucket on a cow. Drinking it will remove all status effects, but restores no hunger points."), _doc_items_usagehelp = S("Use the placement key to drink the milk."), inventory_image = "mcl_mobitems_bucket_milk.png", @@ -160,7 +160,7 @@ minetest.register_craftitem("mcl_mobitems:milk_bucket", { minetest.register_craftitem("mcl_mobitems:spider_eye", { description = S("Spider Eye"), - _tt_help = minetest.colorize("#FFFF00", S("Poisonous")), + _tt_help = minetest.colorize(mcl_colors.YELLOW, S("Poisonous")), _doc_items_longdesc = S("Spider eyes are used mainly in crafting. If you're really desperate, you can eat a spider eye, but it will poison you briefly."), inventory_image = "mcl_mobitems_spider_eye.png", wield_image = "mcl_mobitems_spider_eye.png", diff --git a/mods/ITEMS/mcl_mobitems/mod.conf b/mods/ITEMS/mcl_mobitems/mod.conf index bd534323a..e9604036e 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, mcl_colors 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/init.lua b/mods/ITEMS/mcl_mobspawners/init.lua index f12c893d9..d95395642 100644 --- a/mods/ITEMS/mcl_mobspawners/init.lua +++ b/mods/ITEMS/mcl_mobspawners/init.lua @@ -17,7 +17,7 @@ local function get_mob_textures(mob) end local function find_doll(pos) - for _,obj in ipairs(minetest.get_objects_inside_radius(pos, 0.5)) do + for _,obj in pairs(minetest.get_objects_inside_radius(pos, 0.5)) do if not obj:is_player() then if obj ~= nil and obj:get_luaentity().name == "mcl_mobspawners:doll" then return obj 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 026428db2..467054767 100644 --- a/mods/ITEMS/mcl_nether/init.lua +++ b/mods/ITEMS/mcl_nether/init.lua @@ -95,7 +95,7 @@ minetest.register_node("mcl_nether:netherrack", { minetest.register_node("mcl_nether:magma", { description = S("Magma Block"), - _tt_help = minetest.colorize("#FFFF00", S("Burns your feet")), + _tt_help = minetest.colorize(mcl_colors.YELLOW, S("Burns your feet")), _doc_items_longdesc = S("Magma blocks are hot solid blocks which hurt anyone standing on it, unless they have fire resistance. Starting a fire on this block will create an eternal fire."), stack_max = 64, tiles = {{name="mcl_nether_magma.png", animation={type="vertical_frames", aspect_w=32, aspect_h=32, length=1.5}}}, @@ -106,7 +106,7 @@ minetest.register_node("mcl_nether:magma", { sounds = mcl_sounds.node_sound_stone_defaults(), -- From walkover mod on_walk_over = function(loc, nodeiamon, player) - if minetest.global_exists("mcl_potions") and mcl_potions.player_has_effect(player, "fire_proof") then + if player and player:get_player_control().sneak or minetest.global_exists("mcl_potions") and mcl_potions.player_has_effect(player, "fire_proof") then return end -- Hurt players standing on top of this block @@ -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..8bef6c6c9 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, mcl_colors +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_end.lua b/mods/ITEMS/mcl_portals/portal_end.lua index 045993530..0bc0ce57e 100644 --- a/mods/ITEMS/mcl_portals/portal_end.lua +++ b/mods/ITEMS/mcl_portals/portal_end.lua @@ -224,7 +224,7 @@ function mcl_portals.end_teleport(obj, pos) end function mcl_portals.end_portal_teleport(pos, node) - for _,obj in ipairs(minetest.get_objects_inside_radius(pos, 1)) do + for _,obj in pairs(minetest.get_objects_inside_radius(pos, 1)) do local lua_entity = obj:get_luaentity() --maikerumine added for objects to travel if obj:is_player() or lua_entity then local objpos = obj:get_pos() diff --git a/mods/ITEMS/mcl_portals/portal_nether.lua b/mods/ITEMS/mcl_portals/portal_nether.lua index 32a24e092..e842edf81 100644 --- a/mods/ITEMS/mcl_portals/portal_nether.lua +++ b/mods/ITEMS/mcl_portals/portal_nether.lua @@ -1,83 +1,206 @@ 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) + +local get_node = mcl_vars.get_node +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) + 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 and 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 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 +212,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 +223,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 +263,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 +272,293 @@ 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, node, node_frame) + 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 = {} + local node = node or {name = PORTAL, param2 = orientation} + local node_frame = node_frame or {name = OBSIDIAN} + 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, node_frame) else - stack[i + 2] = {x = x, y = y, z = z - 1} - stack[i + 3] = {x = x, y = y, z = z + 1} + set_node(pos, node) + 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, clear_before_build) + 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 + if clear_before_build then + light_frame(pos.x, pos.y, pos.z, pos.x + (1 - orientation) * (width - 1), pos.y + height - 1, pos.z + orientation * (width - 1), name, {name="air"}, {name="air"}) end + light_frame(pos.x, pos.y, pos.z, pos.x + (1 - orientation) * (width - 1), pos.y + height - 1, pos.z + orientation * (width - 1), name) - 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}) - - 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, true) +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 get_node(objpos).name ~= PORTAL then return end + + -- THIS IS A TEMPORATY CODE SECTION FOR COMPATIBILITY REASONS -- 1 of 2 -- TODO: Remove -- + -- Old worlds have no exits indexed - adding the exit to return here: + add_exit(objpos) + -- TEMPORATY CODE SECTION ENDS HERE -- + + + -- 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) + + -- THIS IS A TEMPORATY CODE SECTION FOR COMPATIBILITY REASONS -- 2 of 2 -- TODO: Remove -- + -- Find portals for old worlds (new worlds keep them all in the table): + local portals = find_nodes_in_area(pos1, pos2, {PORTAL}) + if portals and #portals>0 then + for _, p in pairs(portals) do + add_exit(p) + end + local exit = find_exit(pos) + if exit then + finalize_teleport(obj, exit) + end + return + end + -- TEMPORATY CODE SECTION ENDS HERE -- + + + 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 + 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 = 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 +578,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,9 +606,14 @@ 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 + minetest.after(0.2, function(pos) -- generate target map chunk + 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) + minetest.emerge_area(pos1, pos2) + end, vector.new(pos)) return true end orientation = 1 - orientation @@ -606,126 +621,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 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 +695,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 +735,11 @@ minetest.register_abm({ acceleration.z = -acceleration.z end end - distance = vector.subtract(pos, distance) - for _, obj in ipairs(minetest.get_objects_inside_radius(pos, 15)) do + 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, @@ -818,7 +756,7 @@ minetest.register_abm({ }) end end - for _, obj in ipairs(minetest.get_objects_inside_radius(pos, 1)) do --maikerumine added for objects to travel + for _, obj in pairs(minetest.get_objects_inside_radius(pos, 1)) do --maikerumine added for objects to travel local lua_entity = obj:get_luaentity() --maikerumine added for objects to travel if (obj:is_player() or lua_entity) and prevent_portal_chatter(obj) then teleport(obj, pos) @@ -830,14 +768,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 +784,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_potions/functions.lua b/mods/ITEMS/mcl_potions/functions.lua index cd4939c2f..996637aa7 100644 --- a/mods/ITEMS/mcl_potions/functions.lua +++ b/mods/ITEMS/mcl_potions/functions.lua @@ -539,7 +539,7 @@ end) minetest.register_on_shutdown(function() -- save player effects on server shutdown - for _,player in ipairs(minetest.get_connected_players()) do + for _,player in pairs(minetest.get_connected_players()) do mcl_potions._save_player_effects(player) end 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/API.md b/mods/ITEMS/mcl_throwing/API.md new file mode 100644 index 000000000..f2b1c7374 --- /dev/null +++ b/mods/ITEMS/mcl_throwing/API.md @@ -0,0 +1,35 @@ +# mcl_throwing + +## mcl_throwing.throw(throw_item, pos, dir, velocity, thrower) +Throw a throwable item. + +* throw_item: itemstring of the throwable item +* pos: initial position of the entity +* dir: direction where the throwable item will be thrown +* velocity: (optional) will overide the default velocity value (can be nil) +* thrower: (optional) player/entity who throw the object (can be nil) + +## mcl_throwing.register_throwable_object(name, entity, velocity) +Register a throwable item. + +* name: itemname of the throwable object +* entity: entity thrown +* velocity: initial velocity of the entity + +## mcl_throwing.dispense_function(stack, dispenserpos, droppos, dropnode, dropdir) +Throw throwable item from dispencer. + +Shouldn't be called directly. + +Must be used in item definition: + +`_on_dispense = mcl_throwing.dispense_function,` + +## mcl_throwing.get_player_throw_function(entity_name, velocity) + +Return a function who handle item throwing (to be used in item definition) + +Handle creative mode, and throw params. + +* entity_name: the name of the entity to throw +* velocity: (optional) velocity overide (can be nil) 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/init.lua b/mods/ITEMS/mcl_throwing/init.lua index 5fe34b45e..4d6dcfe5c 100644 --- a/mods/ITEMS/mcl_throwing/init.lua +++ b/mods/ITEMS/mcl_throwing/init.lua @@ -2,7 +2,7 @@ mcl_throwing = {} local S = minetest.get_translator("mcl_throwing") local mod_death_messages = minetest.get_modpath("mcl_death_messages") -local mod_fishing = minetest.get_modpath("mcl_fishing") +local modpath = minetest.get_modpath(minetest.get_current_modname()) -- -- Snowballs and other throwable items @@ -10,21 +10,15 @@ local mod_fishing = minetest.get_modpath("mcl_fishing") local GRAVITY = tonumber(minetest.settings:get("movement_gravity")) -local entity_mapping = { - ["mcl_throwing:flying_bobber"] = "mcl_throwing:flying_bobber_entity", - ["mcl_throwing:snowball"] = "mcl_throwing:snowball_entity", - ["mcl_throwing:egg"] = "mcl_throwing:egg_entity", - ["mcl_throwing:ender_pearl"] = "mcl_throwing:ender_pearl_entity", -} +local entity_mapping = {} +local velocities = {} -local velocities = { - ["mcl_throwing:flying_bobber_entity"] = 5, - ["mcl_throwing:snowball_entity"] = 22, - ["mcl_throwing:egg_entity"] = 22, - ["mcl_throwing:ender_pearl_entity"] = 22, -} +function mcl_throwing.register_throwable_object(name, entity, velocity) + entity_mapping[name] = entity + velocities[name] = velocity +end -mcl_throwing.throw = function(throw_item, pos, dir, velocity, thrower) +function mcl_throwing.throw(throw_item, pos, dir, velocity, thrower) if velocity == nil then velocity = velocities[throw_item] end @@ -44,7 +38,7 @@ mcl_throwing.throw = function(throw_item, pos, dir, velocity, thrower) end -- Throw item -local player_throw_function = function(entity_name, velocity) +function mcl_throwing.get_player_throw_function(entity_name, velocity) local func = function(item, player, pointed_thing) local playerpos = player:get_pos() local dir = player:get_look_dir() @@ -57,7 +51,7 @@ local player_throw_function = function(entity_name, velocity) return func end -local dispense_function = function(stack, dispenserpos, droppos, dropnode, dropdir) +function mcl_throwing.dispense_function(stack, dispenserpos, droppos, dropnode, dropdir) -- Launch throwable item local shootpos = vector.add(dispenserpos, vector.multiply(dropdir, 0.51)) mcl_throwing.throw(stack:get_name(), shootpos, dropdir) @@ -85,374 +79,4 @@ local on_activate = function(self, staticdata, dtime_s) end end --- The snowball entity -local snowball_ENTITY={ - physical = false, - timer=0, - textures = {"mcl_throwing_snowball.png"}, - visual_size = {x=0.5, y=0.5}, - collisionbox = {0,0,0,0,0,0}, - pointable = false, - - get_staticdata = get_staticdata, - on_activate = on_activate, - _thrower = nil, - - _lastpos={}, -} -local egg_ENTITY={ - physical = false, - timer=0, - textures = {"mcl_throwing_egg.png"}, - visual_size = {x=0.45, y=0.45}, - collisionbox = {0,0,0,0,0,0}, - pointable = false, - - get_staticdata = get_staticdata, - on_activate = on_activate, - _thrower = nil, - - _lastpos={}, -} --- Ender pearl entity -local pearl_ENTITY={ - physical = false, - timer=0, - textures = {"mcl_throwing_ender_pearl.png"}, - visual_size = {x=0.9, y=0.9}, - collisionbox = {0,0,0,0,0,0}, - pointable = false, - - get_staticdata = get_staticdata, - on_activate = on_activate, - - _lastpos={}, - _thrower = nil, -- Player ObjectRef of the player who threw the ender pearl -} - -local flying_bobber_ENTITY={ - physical = false, - timer=0, - textures = {"mcl_fishing_bobber.png"}, --FIXME: Replace with correct texture. - visual_size = {x=0.5, y=0.5}, - collisionbox = {0,0,0,0,0,0}, - pointable = false, - - get_staticdata = get_staticdata, - on_activate = on_activate, - - _lastpos={}, - _thrower = nil, - objtype="fishing", -} - -local check_object_hit = function(self, pos, dmg) - for _,object in pairs(minetest.get_objects_inside_radius(pos, 1.5)) do - - local entity = object:get_luaentity() - - if entity - and entity.name ~= self.object:get_luaentity().name then - - if object:is_player() and self._thrower ~= object:get_player_name() then - -- TODO: Deal knockback - self.object:remove() - return true - elseif (entity._cmi_is_mob == true or entity._hittable_by_projectile) and (self._thrower ~= object) then - -- FIXME: Knockback is broken - object:punch(self.object, 1.0, { - full_punch_interval = 1.0, - damage_groups = dmg, - }, nil) - return true - end - end - end - return false -end - -local snowball_particles = function(pos, vel) - local vel = vector.normalize(vector.multiply(vel, -1)) - minetest.add_particlespawner({ - amount = 20, - time = 0.001, - minpos = pos, - maxpos = pos, - minvel = vector.add({x=-2, y=3, z=-2}, vel), - maxvel = vector.add({x=2, y=5, z=2}, vel), - minacc = {x=0, y=-9.81, z=0}, - maxacc = {x=0, y=-9.81, z=0}, - minexptime = 1, - maxexptime = 3, - minsize = 0.7, - maxsize = 0.7, - collisiondetection = true, - collision_removal = true, - object_collision = false, - texture = "weather_pack_snow_snowflake"..math.random(1,2)..".png", - }) -end - --- Snowball on_step()--> called when snowball is moving. -local snowball_on_step = function(self, dtime) - self.timer=self.timer+dtime - local pos = self.object:get_pos() - local vel = self.object:get_velocity() - local node = minetest.get_node(pos) - local def = minetest.registered_nodes[node.name] - - - -- Destroy when hitting a solid node - if self._lastpos.x~=nil then - if (def and def.walkable) or not def then - minetest.sound_play("mcl_throwing_snowball_impact_hard", { pos = pos, max_hear_distance=16, gain=0.7 }, true) - snowball_particles(self._lastpos, vel) - self.object:remove() - return - end - end - - if check_object_hit(self, pos, {snowball_vulnerable = 3}) then - minetest.sound_play("mcl_throwing_snowball_impact_soft", { pos = pos, max_hear_distance=16, gain=0.7 }, true) - snowball_particles(pos, vel) - self.object:remove() - return - end - - self._lastpos={x=pos.x, y=pos.y, z=pos.z} -- Set _lastpos-->Node will be added at last pos outside the node -end - --- Movement function of egg -local egg_on_step = function(self, dtime) - self.timer=self.timer+dtime - local pos = self.object:get_pos() - local node = minetest.get_node(pos) - local def = minetest.registered_nodes[node.name] - - -- Destroy when hitting a solid node with chance to spawn chicks - if self._lastpos.x~=nil then - if (def and def.walkable) or not def then - -- 1/8 chance to spawn a chick - -- FIXME: Chicks have a quite good chance to spawn in walls - local r = math.random(1,8) - - -- Turn given object into a child - local make_child= function(object) - local ent = object:get_luaentity() - object:set_properties({ - visual_size = { x = ent.base_size.x/2, y = ent.base_size.y/2 }, - collisionbox = { - ent.base_colbox[1]/2, - ent.base_colbox[2]/2, - ent.base_colbox[3]/2, - ent.base_colbox[4]/2, - ent.base_colbox[5]/2, - ent.base_colbox[6]/2, - } - }) - ent.child = true - end - if r == 1 then - make_child(minetest.add_entity(self._lastpos, "mobs_mc:chicken")) - - -- BONUS ROUND: 1/32 chance to spawn 3 additional chicks - local r = math.random(1,32) - if r == 1 then - local offsets = { - { x=0.7, y=0, z=0 }, - { x=-0.7, y=0, z=-0.7 }, - { x=-0.7, y=0, z=0.7 }, - } - for o=1, 3 do - local pos = vector.add(self._lastpos, offsets[o]) - make_child(minetest.add_entity(pos, "mobs_mc:chicken")) - end - end - end - minetest.sound_play("mcl_throwing_egg_impact", { pos = self.object:get_pos(), max_hear_distance=10, gain=0.5 }, true) - self.object:remove() - return - end - end - - -- Destroy when hitting a mob or player (no chick spawning) - if check_object_hit(self, pos) then - minetest.sound_play("mcl_throwing_egg_impact", { pos = self.object:get_pos(), max_hear_distance=10, gain=0.5 }, true) - self.object:remove() - return - end - - self._lastpos={x=pos.x, y=pos.y, z=pos.z} -- Set lastpos-->Node will be added at last pos outside the node -end - --- Movement function of ender pearl -local pearl_on_step = function(self, dtime) - self.timer=self.timer+dtime - local pos = self.object:get_pos() - pos.y = math.floor(pos.y) - local node = minetest.get_node(pos) - local nn = node.name - local def = minetest.registered_nodes[node.name] - - -- Destroy when hitting a solid node - if self._lastpos.x~=nil then - local walkable = (def and def.walkable) - - -- No teleport for hitting ignore for now. Otherwise the player could get stuck. - -- FIXME: This also means the player loses an ender pearl for throwing into unloaded areas - if node.name == "ignore" then - self.object:remove() - -- Activate when hitting a solid node or a plant - elseif walkable or nn == "mcl_core:vine" or nn == "mcl_core:deadbush" or minetest.get_item_group(nn, "flower") ~= 0 or minetest.get_item_group(nn, "sapling") ~= 0 or minetest.get_item_group(nn, "plant") ~= 0 or minetest.get_item_group(nn, "mushroom") ~= 0 or not def then - local player = minetest.get_player_by_name(self._thrower) - if player then - -- Teleport and hurt player - - -- First determine good teleport position - local dir = {x=0, y=0, z=0} - - local v = self.object:get_velocity() - if walkable then - local vc = table.copy(v) -- vector for calculating - -- Node is walkable, we have to find a place somewhere outside of that node - vc = vector.normalize(vc) - - -- Zero-out the two axes with a lower absolute value than - -- the axis with the strongest force - local lv, ld - lv, ld = math.abs(vc.y), "y" - if math.abs(vc.x) > lv then - lv, ld = math.abs(vc.x), "x" - end - if math.abs(vc.z) > lv then - lv, ld = math.abs(vc.z), "z" - end - if ld ~= "x" then vc.x = 0 end - if ld ~= "y" then vc.y = 0 end - if ld ~= "z" then vc.z = 0 end - - -- Final tweaks to the teleporting pos, based on direction - -- Impact from the side - dir.x = vc.x * -1 - dir.z = vc.z * -1 - - -- Special case: top or bottom of node - if vc.y > 0 then - -- We need more space when impact is from below - dir.y = -2.3 - elseif vc.y < 0 then - -- Standing on top - dir.y = 0.5 - end - end - -- If node was not walkable, no modification to pos is made. - - -- Final teleportation position - local telepos = vector.add(pos, dir) - local telenode = minetest.get_node(telepos) - - --[[ It may be possible that telepos is walkable due to the algorithm. - Especially when the ender pearl is faster horizontally than vertical. - This applies final fixing, just to be sure we're not in a walkable node ]] - if not minetest.registered_nodes[telenode.name] or minetest.registered_nodes[telenode.name].walkable then - if v.y < 0 then - telepos.y = telepos.y + 0.5 - else - telepos.y = telepos.y - 2.3 - end - end - - local oldpos = player:get_pos() - -- Teleport and hurt player - player:set_pos(telepos) - player:set_hp(player:get_hp() - 5, { type = "fall", from = "mod" }) - - -- 5% chance to spawn endermite at the player's origin - local r = math.random(1,20) - if r == 1 then - minetest.add_entity(oldpos, "mobs_mc:endermite") - end - - end - self.object:remove() - return - end - end - self._lastpos={x=pos.x, y=pos.y, z=pos.z} -- Set lastpos-->Node will be added at last pos outside the node -end - --- Movement function of flying bobber -local flying_bobber_on_step = function(self, dtime) - self.timer=self.timer+dtime - local pos = self.object:get_pos() - local node = minetest.get_node(pos) - local def = minetest.registered_nodes[node.name] - --local player = minetest.get_player_by_name(self._thrower) - - -- Destroy when hitting a solid node - if self._lastpos.x~=nil then - if (def and (def.walkable or def.liquidtype == "flowing" or def.liquidtype == "source")) or not def then - local make_child= function(object) - local ent = object:get_luaentity() - ent.player = self._thrower - ent.child = true - end - make_child(minetest.add_entity(self._lastpos, "mcl_fishing:bobber_entity")) - self.object:remove() - return - end - end - self._lastpos={x=pos.x, y=pos.y, z=pos.z} -- Set lastpos-->Node will be added at last pos outside the node -end - -snowball_ENTITY.on_step = snowball_on_step -egg_ENTITY.on_step = egg_on_step -pearl_ENTITY.on_step = pearl_on_step -flying_bobber_ENTITY.on_step = flying_bobber_on_step - -minetest.register_entity("mcl_throwing:snowball_entity", snowball_ENTITY) -minetest.register_entity("mcl_throwing:egg_entity", egg_ENTITY) -minetest.register_entity("mcl_throwing:ender_pearl_entity", pearl_ENTITY) -minetest.register_entity("mcl_throwing:flying_bobber_entity", flying_bobber_ENTITY) - -local how_to_throw = S("Use the punch key to throw.") - --- Snowball -minetest.register_craftitem("mcl_throwing:snowball", { - description = S("Snowball"), - _tt_help = S("Throwable"), - _doc_items_longdesc = S("Snowballs can be thrown or launched from a dispenser for fun. Hitting something with a snowball does nothing."), - _doc_items_usagehelp = how_to_throw, - inventory_image = "mcl_throwing_snowball.png", - stack_max = 16, - groups = { weapon_ranged = 1 }, - on_use = player_throw_function("mcl_throwing:snowball_entity"), - _on_dispense = dispense_function, -}) - --- Egg -minetest.register_craftitem("mcl_throwing:egg", { - description = S("Egg"), - _tt_help = S("Throwable").."\n"..S("Chance to hatch chicks when broken"), - _doc_items_longdesc = S("Eggs can be thrown or launched from a dispenser and breaks on impact. There is a small chance that 1 or even 4 chicks will pop out of the egg."), - _doc_items_usagehelp = how_to_throw, - inventory_image = "mcl_throwing_egg.png", - stack_max = 16, - on_use = player_throw_function("mcl_throwing:egg_entity"), - _on_dispense = dispense_function, - groups = { craftitem = 1 }, -}) - --- Ender Pearl -minetest.register_craftitem("mcl_throwing:ender_pearl", { - description = S("Ender Pearl"), - _tt_help = S("Throwable").."\n"..minetest.colorize("#FFFF00", S("Teleports you on impact for cost of 5 HP")), - _doc_items_longdesc = S("An ender pearl is an item which can be used for teleportation at the cost of health. It can be thrown and teleport the thrower to its impact location when it hits a solid block or a plant. Each teleportation hurts the user by 5 hit points."), - _doc_items_usagehelp = how_to_throw, - wield_image = "mcl_throwing_ender_pearl.png", - inventory_image = "mcl_throwing_ender_pearl.png", - stack_max = 16, - on_use = player_throw_function("mcl_throwing:ender_pearl_entity"), - groups = { transport = 1 }, -}) - +dofile(modpath.."/register.lua") \ No newline at end of file diff --git a/mods/ITEMS/mcl_throwing/mod.conf b/mods/ITEMS/mcl_throwing/mod.conf index 117ca80a7..60d3e31a7 100644 --- a/mods/ITEMS/mcl_throwing/mod.conf +++ b/mods/ITEMS/mcl_throwing/mod.conf @@ -1 +1,3 @@ name = mcl_throwing +depends = mcl_colors +optional_depends = mcl_core, mcl_mobitems, doc diff --git a/mods/ITEMS/mcl_throwing/register.lua b/mods/ITEMS/mcl_throwing/register.lua new file mode 100644 index 000000000..027ff4e93 --- /dev/null +++ b/mods/ITEMS/mcl_throwing/register.lua @@ -0,0 +1,335 @@ +local S = minetest.get_translator(minetest.get_current_modname()) + +-- The snowball entity +local snowball_ENTITY={ + physical = false, + timer=0, + textures = {"mcl_throwing_snowball.png"}, + visual_size = {x=0.5, y=0.5}, + collisionbox = {0,0,0,0,0,0}, + pointable = false, + + get_staticdata = get_staticdata, + on_activate = on_activate, + _thrower = nil, + + _lastpos={}, +} +local egg_ENTITY={ + physical = false, + timer=0, + textures = {"mcl_throwing_egg.png"}, + visual_size = {x=0.45, y=0.45}, + collisionbox = {0,0,0,0,0,0}, + pointable = false, + + get_staticdata = get_staticdata, + on_activate = on_activate, + _thrower = nil, + + _lastpos={}, +} +-- Ender pearl entity +local pearl_ENTITY={ + physical = false, + timer=0, + textures = {"mcl_throwing_ender_pearl.png"}, + visual_size = {x=0.9, y=0.9}, + collisionbox = {0,0,0,0,0,0}, + pointable = false, + + get_staticdata = get_staticdata, + on_activate = on_activate, + + _lastpos={}, + _thrower = nil, -- Player ObjectRef of the player who threw the ender pearl +} + +local check_object_hit = function(self, pos, dmg) + for _,object in pairs(minetest.get_objects_inside_radius(pos, 1.5)) do + + local entity = object:get_luaentity() + + if entity + and entity.name ~= self.object:get_luaentity().name then + + if object:is_player() and self._thrower ~= object:get_player_name() then + -- TODO: Deal knockback + self.object:remove() + return true + elseif (entity._cmi_is_mob == true or entity._hittable_by_projectile) and (self._thrower ~= object) then + -- FIXME: Knockback is broken + object:punch(self.object, 1.0, { + full_punch_interval = 1.0, + damage_groups = dmg, + }, nil) + return true + end + end + end + return false +end + +local snowball_particles = function(pos, vel) + local vel = vector.normalize(vector.multiply(vel, -1)) + minetest.add_particlespawner({ + amount = 20, + time = 0.001, + minpos = pos, + maxpos = pos, + minvel = vector.add({x=-2, y=3, z=-2}, vel), + maxvel = vector.add({x=2, y=5, z=2}, vel), + minacc = {x=0, y=-9.81, z=0}, + maxacc = {x=0, y=-9.81, z=0}, + minexptime = 1, + maxexptime = 3, + minsize = 0.7, + maxsize = 0.7, + collisiondetection = true, + collision_removal = true, + object_collision = false, + texture = "weather_pack_snow_snowflake"..math.random(1,2)..".png", + }) +end + +-- Snowball on_step()--> called when snowball is moving. +local snowball_on_step = function(self, dtime) + self.timer=self.timer+dtime + local pos = self.object:get_pos() + local vel = self.object:get_velocity() + local node = minetest.get_node(pos) + local def = minetest.registered_nodes[node.name] + + + -- Destroy when hitting a solid node + if self._lastpos.x~=nil then + if (def and def.walkable) or not def then + minetest.sound_play("mcl_throwing_snowball_impact_hard", { pos = pos, max_hear_distance=16, gain=0.7 }, true) + snowball_particles(self._lastpos, vel) + self.object:remove() + return + end + end + + if check_object_hit(self, pos, {snowball_vulnerable = 3}) then + minetest.sound_play("mcl_throwing_snowball_impact_soft", { pos = pos, max_hear_distance=16, gain=0.7 }, true) + snowball_particles(pos, vel) + self.object:remove() + return + end + + self._lastpos={x=pos.x, y=pos.y, z=pos.z} -- Set _lastpos-->Node will be added at last pos outside the node +end + +-- Movement function of egg +local egg_on_step = function(self, dtime) + self.timer=self.timer+dtime + local pos = self.object:get_pos() + local node = minetest.get_node(pos) + local def = minetest.registered_nodes[node.name] + + -- Destroy when hitting a solid node with chance to spawn chicks + if self._lastpos.x~=nil then + if (def and def.walkable) or not def then + -- 1/8 chance to spawn a chick + -- FIXME: Chicks have a quite good chance to spawn in walls + local r = math.random(1,8) + + -- Turn given object into a child + local make_child= function(object) + local ent = object:get_luaentity() + object:set_properties({ + visual_size = { x = ent.base_size.x/2, y = ent.base_size.y/2 }, + collisionbox = { + ent.base_colbox[1]/2, + ent.base_colbox[2]/2, + ent.base_colbox[3]/2, + ent.base_colbox[4]/2, + ent.base_colbox[5]/2, + ent.base_colbox[6]/2, + } + }) + ent.child = true + end + if r == 1 then + make_child(minetest.add_entity(self._lastpos, "mobs_mc:chicken")) + + -- BONUS ROUND: 1/32 chance to spawn 3 additional chicks + local r = math.random(1,32) + if r == 1 then + local offsets = { + { x=0.7, y=0, z=0 }, + { x=-0.7, y=0, z=-0.7 }, + { x=-0.7, y=0, z=0.7 }, + } + for o=1, 3 do + local pos = vector.add(self._lastpos, offsets[o]) + make_child(minetest.add_entity(pos, "mobs_mc:chicken")) + end + end + end + minetest.sound_play("mcl_throwing_egg_impact", { pos = self.object:get_pos(), max_hear_distance=10, gain=0.5 }, true) + self.object:remove() + return + end + end + + -- Destroy when hitting a mob or player (no chick spawning) + if check_object_hit(self, pos) then + minetest.sound_play("mcl_throwing_egg_impact", { pos = self.object:get_pos(), max_hear_distance=10, gain=0.5 }, true) + self.object:remove() + return + end + + self._lastpos={x=pos.x, y=pos.y, z=pos.z} -- Set lastpos-->Node will be added at last pos outside the node +end + +-- Movement function of ender pearl +local pearl_on_step = function(self, dtime) + self.timer=self.timer+dtime + local pos = self.object:get_pos() + pos.y = math.floor(pos.y) + local node = minetest.get_node(pos) + local nn = node.name + local def = minetest.registered_nodes[node.name] + + -- Destroy when hitting a solid node + if self._lastpos.x~=nil then + local walkable = (def and def.walkable) + + -- No teleport for hitting ignore for now. Otherwise the player could get stuck. + -- FIXME: This also means the player loses an ender pearl for throwing into unloaded areas + if node.name == "ignore" then + self.object:remove() + -- Activate when hitting a solid node or a plant + elseif walkable or nn == "mcl_core:vine" or nn == "mcl_core:deadbush" or minetest.get_item_group(nn, "flower") ~= 0 or minetest.get_item_group(nn, "sapling") ~= 0 or minetest.get_item_group(nn, "plant") ~= 0 or minetest.get_item_group(nn, "mushroom") ~= 0 or not def then + local player = minetest.get_player_by_name(self._thrower) + if player then + -- Teleport and hurt player + + -- First determine good teleport position + local dir = {x=0, y=0, z=0} + + local v = self.object:get_velocity() + if walkable then + local vc = table.copy(v) -- vector for calculating + -- Node is walkable, we have to find a place somewhere outside of that node + vc = vector.normalize(vc) + + -- Zero-out the two axes with a lower absolute value than + -- the axis with the strongest force + local lv, ld + lv, ld = math.abs(vc.y), "y" + if math.abs(vc.x) > lv then + lv, ld = math.abs(vc.x), "x" + end + if math.abs(vc.z) > lv then + lv, ld = math.abs(vc.z), "z" + end + if ld ~= "x" then vc.x = 0 end + if ld ~= "y" then vc.y = 0 end + if ld ~= "z" then vc.z = 0 end + + -- Final tweaks to the teleporting pos, based on direction + -- Impact from the side + dir.x = vc.x * -1 + dir.z = vc.z * -1 + + -- Special case: top or bottom of node + if vc.y > 0 then + -- We need more space when impact is from below + dir.y = -2.3 + elseif vc.y < 0 then + -- Standing on top + dir.y = 0.5 + end + end + -- If node was not walkable, no modification to pos is made. + + -- Final teleportation position + local telepos = vector.add(pos, dir) + local telenode = minetest.get_node(telepos) + + --[[ It may be possible that telepos is walkable due to the algorithm. + Especially when the ender pearl is faster horizontally than vertical. + This applies final fixing, just to be sure we're not in a walkable node ]] + if not minetest.registered_nodes[telenode.name] or minetest.registered_nodes[telenode.name].walkable then + if v.y < 0 then + telepos.y = telepos.y + 0.5 + else + telepos.y = telepos.y - 2.3 + end + end + + local oldpos = player:get_pos() + -- Teleport and hurt player + player:set_pos(telepos) + player:set_hp(player:get_hp() - 5, { type = "fall", from = "mod" }) + + -- 5% chance to spawn endermite at the player's origin + local r = math.random(1,20) + if r == 1 then + minetest.add_entity(oldpos, "mobs_mc:endermite") + end + + end + self.object:remove() + return + end + end + self._lastpos={x=pos.x, y=pos.y, z=pos.z} -- Set lastpos-->Node will be added at last pos outside the node +end + +snowball_ENTITY.on_step = snowball_on_step +egg_ENTITY.on_step = egg_on_step +pearl_ENTITY.on_step = pearl_on_step + +minetest.register_entity("mcl_throwing:snowball_entity", snowball_ENTITY) +minetest.register_entity("mcl_throwing:egg_entity", egg_ENTITY) +minetest.register_entity("mcl_throwing:ender_pearl_entity", pearl_ENTITY) + + +local how_to_throw = S("Use the punch key to throw.") + +-- Snowball +minetest.register_craftitem("mcl_throwing:snowball", { + description = S("Snowball"), + _tt_help = S("Throwable"), + _doc_items_longdesc = S("Snowballs can be thrown or launched from a dispenser for fun. Hitting something with a snowball does nothing."), + _doc_items_usagehelp = how_to_throw, + inventory_image = "mcl_throwing_snowball.png", + stack_max = 16, + groups = { weapon_ranged = 1 }, + on_use = mcl_throwing.get_player_throw_function("mcl_throwing:snowball_entity"), + _on_dispense = mcl_throwing.dispense_function, +}) + +-- Egg +minetest.register_craftitem("mcl_throwing:egg", { + description = S("Egg"), + _tt_help = S("Throwable").."\n"..S("Chance to hatch chicks when broken"), + _doc_items_longdesc = S("Eggs can be thrown or launched from a dispenser and breaks on impact. There is a small chance that 1 or even 4 chicks will pop out of the egg."), + _doc_items_usagehelp = how_to_throw, + inventory_image = "mcl_throwing_egg.png", + stack_max = 16, + on_use = mcl_throwing.get_player_throw_function("mcl_throwing:egg_entity"), + _on_dispense = mcl_throwing.dispense_function, + groups = { craftitem = 1 }, +}) + +-- Ender Pearl +minetest.register_craftitem("mcl_throwing:ender_pearl", { + description = S("Ender Pearl"), + _tt_help = S("Throwable").."\n"..minetest.colorize(mcl_colors.YELLOW, S("Teleports you on impact for cost of 5 HP")), + _doc_items_longdesc = S("An ender pearl is an item which can be used for teleportation at the cost of health. It can be thrown and teleport the thrower to its impact location when it hits a solid block or a plant. Each teleportation hurts the user by 5 hit points."), + _doc_items_usagehelp = how_to_throw, + wield_image = "mcl_throwing_ender_pearl.png", + inventory_image = "mcl_throwing_ender_pearl.png", + stack_max = 16, + on_use = mcl_throwing.get_player_throw_function("mcl_throwing:ender_pearl_entity"), + groups = { transport = 1 }, +}) + +mcl_throwing.register_throwable_object("mcl_throwing:snowball", "mcl_throwing:snowball_entity", 22) +mcl_throwing.register_throwable_object("mcl_throwing:egg", "mcl_throwing:egg_entity", 22) +mcl_throwing.register_throwable_object("mcl_throwing:ender_pearl", "mcl_throwing:ender_pearl_entity", 22) 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_dungeons/init.lua b/mods/MAPGEN/mcl_dungeons/init.lua index 05d82c3e9..dc9c6d619 100644 --- a/mods/MAPGEN/mcl_dungeons/init.lua +++ b/mods/MAPGEN/mcl_dungeons/init.lua @@ -12,6 +12,8 @@ end local min_y = math.max(mcl_vars.mg_overworld_min, mcl_vars.mg_bedrock_overworld_max) + 1 local max_y = mcl_vars.mg_overworld_max - 1 +local get_node = mcl_vars.get_node + -- Calculate the number of dungeon spawn attempts -- In Minecraft, there 8 dungeon spawn attempts Minecraft chunk (16*256*16 = 65536 blocks). -- Minetest chunks don't have this size, so scale the number accordingly. @@ -49,8 +51,8 @@ local function ecb_spawn_dungeon(blockpos, action, calls_remaining, param) local y_floor = y local y_ceiling = y + dim.y + 1 if check then for tx = x+1, x+dim.x do for tz = z+1, z+dim.z do - if not minetest.registered_nodes[mcl_mapgen_core.get_node({x = tx, y = y_floor , z = tz}).name].walkable - or not minetest.registered_nodes[mcl_mapgen_core.get_node({x = tx, y = y_ceiling, z = tz}).name].walkable then return false end + if not minetest.registered_nodes[get_node({x = tx, y = y_floor , z = tz}).name].walkable + or not minetest.registered_nodes[get_node({x = tx, y = y_ceiling, z = tz}).name].walkable then return false end end end end -- Check for air openings (2 stacked air at ground level) in wall positions @@ -63,25 +65,25 @@ local function ecb_spawn_dungeon(blockpos, action, calls_remaining, param) local x2,z2 = x+dim.x+1, z+dim.z+1 - if mcl_mapgen_core.get_node({x=x, y=y+1, z=z}).name == "air" and mcl_mapgen_core.get_node({x=x, y=y+2, z=z}).name == "air" then + if get_node({x=x, y=y+1, z=z}).name == "air" and get_node({x=x, y=y+2, z=z}).name == "air" then openings_counter = openings_counter + 1 if not openings[x] then openings[x]={} end openings[x][z] = true table.insert(corners, {x=x, z=z}) end - if mcl_mapgen_core.get_node({x=x2, y=y+1, z=z}).name == "air" and mcl_mapgen_core.get_node({x=x2, y=y+2, z=z}).name == "air" then + if get_node({x=x2, y=y+1, z=z}).name == "air" and get_node({x=x2, y=y+2, z=z}).name == "air" then openings_counter = openings_counter + 1 if not openings[x2] then openings[x2]={} end openings[x2][z] = true table.insert(corners, {x=x2, z=z}) end - if mcl_mapgen_core.get_node({x=x, y=y+1, z=z2}).name == "air" and mcl_mapgen_core.get_node({x=x, y=y+2, z=z2}).name == "air" then + if get_node({x=x, y=y+1, z=z2}).name == "air" and get_node({x=x, y=y+2, z=z2}).name == "air" then openings_counter = openings_counter + 1 if not openings[x] then openings[x]={} end openings[x][z2] = true table.insert(corners, {x=x, z=z2}) end - if mcl_mapgen_core.get_node({x=x2, y=y+1, z=z2}).name == "air" and mcl_mapgen_core.get_node({x=x2, y=y+2, z=z2}).name == "air" then + if get_node({x=x2, y=y+1, z=z2}).name == "air" and get_node({x=x2, y=y+2, z=z2}).name == "air" then openings_counter = openings_counter + 1 if not openings[x2] then openings[x2]={} end openings[x2][z2] = true @@ -89,13 +91,13 @@ local function ecb_spawn_dungeon(blockpos, action, calls_remaining, param) end for wx = x+1, x+dim.x do - if mcl_mapgen_core.get_node({x=wx, y=y+1, z=z}).name == "air" and mcl_mapgen_core.get_node({x=wx, y=y+2, z=z}).name == "air" then + if get_node({x=wx, y=y+1, z=z}).name == "air" and get_node({x=wx, y=y+2, z=z}).name == "air" then openings_counter = openings_counter + 1 if check and openings_counter > 5 then return end if not openings[wx] then openings[wx]={} end openings[wx][z] = true end - if mcl_mapgen_core.get_node({x=wx, y=y+1, z=z2}).name == "air" and mcl_mapgen_core.get_node({x=wx, y=y+2, z=z2}).name == "air" then + if get_node({x=wx, y=y+1, z=z2}).name == "air" and get_node({x=wx, y=y+2, z=z2}).name == "air" then openings_counter = openings_counter + 1 if check and openings_counter > 5 then return end if not openings[wx] then openings[wx]={} end @@ -103,13 +105,13 @@ local function ecb_spawn_dungeon(blockpos, action, calls_remaining, param) end end for wz = z+1, z+dim.z do - if mcl_mapgen_core.get_node({x=x, y=y+1, z=wz}).name == "air" and mcl_mapgen_core.get_node({x=x, y=y+2, z=wz}).name == "air" then + if get_node({x=x, y=y+1, z=wz}).name == "air" and get_node({x=x, y=y+2, z=wz}).name == "air" then openings_counter = openings_counter + 1 if check and openings_counter > 5 then return end if not openings[x] then openings[x]={} end openings[x][wz] = true end - if mcl_mapgen_core.get_node({x=x2, y=y+1, z=wz}).name == "air" and mcl_mapgen_core.get_node({x=x2, y=y+2, z=wz}).name == "air" then + if get_node({x=x2, y=y+1, z=wz}).name == "air" and get_node({x=x2, y=y+2, z=wz}).name == "air" then openings_counter = openings_counter + 1 if check and openings_counter > 5 then return end if not openings[x2] then openings[x2]={} end @@ -185,7 +187,7 @@ local function ecb_spawn_dungeon(blockpos, action, calls_remaining, param) -- Calculate the mob spawner position, to be re-used for later local sp = {x = x + math.ceil(dim.x/2), y = y+1, z = z + math.ceil(dim.z/2)} - local rn = minetest.registered_nodes[mcl_mapgen_core.get_node(sp).name] + local rn = minetest.registered_nodes[get_node(sp).name] if rn and rn.is_ground_content then table.insert(spawner_posses, sp) end @@ -200,7 +202,7 @@ local function ecb_spawn_dungeon(blockpos, action, calls_remaining, param) -- Do not overwrite nodes with is_ground_content == false (e.g. bedrock) -- Exceptions: cobblestone and mossy cobblestone so neighborings dungeons nicely connect to each other - local name = mcl_mapgen_core.get_node(p).name + local name = get_node(p).name if minetest.registered_nodes[name].is_ground_content or name == "mcl_core:cobble" or name == "mcl_core:mossycobble" then -- Floor if ty == y then @@ -245,7 +247,7 @@ local function ecb_spawn_dungeon(blockpos, action, calls_remaining, param) if forChest and (currentChest < totalChests + 1) and (chestSlots[currentChest] == chestSlotCounter) then currentChest = currentChest + 1 table.insert(chests, {x=tx, y=ty, z=tz}) - else + -- else --minetest.swap_node(p, {name = "air"}) end if forChest then @@ -263,8 +265,8 @@ local function ecb_spawn_dungeon(blockpos, action, calls_remaining, param) -- Detect the 4 horizontal neighbors local spos = vector.add(pos, surround_vectors[s]) local wpos = vector.subtract(pos, surround_vectors[s]) - local nodename = minetest.get_node(spos).name - local nodename2 = minetest.get_node(wpos).name + local nodename = get_node(spos).name + local nodename2 = get_node(wpos).name local nodedef = minetest.registered_nodes[nodename] local nodedef2 = minetest.registered_nodes[nodename2] -- The chest needs an open space in front of it and a walkable node (except chest) behind it @@ -345,6 +347,7 @@ local function ecb_spawn_dungeon(blockpos, action, calls_remaining, param) }) end + minetest.log("action", "[mcl_dungeons] Filling chest " .. tostring(c) .. " at " .. minetest.pos_to_string(pos)) mcl_loot.fill_inventory(meta:get_inventory(), "main", mcl_loot.get_multi_loot(loottable, pr), pr) end diff --git a/mods/MAPGEN/mcl_mapgen_core/init.lua b/mods/MAPGEN/mcl_mapgen_core/init.lua index 2986664f6..e08b55ba3 100644 --- a/mods/MAPGEN/mcl_mapgen_core/init.lua +++ b/mods/MAPGEN/mcl_mapgen_core/init.lua @@ -1,45 +1,8 @@ mcl_mapgen_core = {} -mcl_mapgen_core.registered_generators = {} +local registered_generators = {} local lvm, nodes, param2 = 0, 0, 0 - -local generating = {} -- generating chunks -local chunks = {} -- intervals of chunks generated -local function add_chunk(pos) - local n = mcl_vars.get_chunk_number(pos) -- unsigned int - local prev - for i, d in pairs(chunks) do - if n <= d[2] then -- we've found it - if (n == d[2]) or (n >= d[1]) then return end -- already here - if n == d[1]-1 then -- right before: - if prev and (prev[2] == n-1) then - prev[2] = d[2] - table.remove(chunks, i) - return - end - d[1] = n - return - end - if prev and (prev[2] == n-1) then --join to previous - prev[2] = n - return - end - table.insert(chunks, i, {n, n}) -- insert new interval before i - return - end - prev = d - end - chunks[#chunks] = {n, n} -end -function mcl_mapgen_core.is_generated(pos) - local n = mcl_vars.get_chunk_number(pos) -- unsigned int - for i, d in pairs(chunks) do - if n <= d[2] then - return (n >= d[1]) - end - end - return false -end +local lvm_buffer = {} -- -- Aliases for map generator outputs @@ -1790,6 +1753,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,24 +1812,23 @@ local generate_nether_decorations = function(minp, maxp, seed) end minetest.register_on_generated(function(minp, maxp, blockseed) - add_chunk(minp) + minetest.log("action", "[mcl_mapgen_core] Generating chunk " .. minetest.pos_to_string(minp) .. " ... " .. minetest.pos_to_string(maxp)) 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 local lvm_used, shadow = false, false - local lb = {} -- buffer local lb2 = {} -- param2 local vm, emin, emax = minetest.get_mapgen_object("voxelmanip") local e1, e2 = {x=emin.x, y=emin.y, z=emin.z}, {x=emax.x, y=emax.y, z=emax.z} local data2 - local data = vm:get_data(lb) + local data = vm:get_data(lvm_buffer) if param2 > 0 then data2 = vm:get_param2_data(lb2) end local area = VoxelArea:new({MinEdge=e1, MaxEdge=e2}) - for _, rec in pairs(mcl_mapgen_core.registered_generators) do + for _, rec in pairs(registered_generators) do if rec.vf then - local lvm_used0, shadow0 = rec.vf(vm, data, data2, p1, p2, area, p1, p2, blockseed) + local lvm_used0, shadow0 = rec.vf(vm, data, data2, e1, e2, area, p1, p2, blockseed) if lvm_used0 then lvm_used = true end @@ -1887,18 +1851,18 @@ minetest.register_on_generated(function(minp, maxp, blockseed) end if nodes > 0 then - for _, rec in pairs(mcl_mapgen_core.registered_generators) do + for _, rec in pairs(registered_generators) do if rec.nf then rec.nf(p1, p2, blockseed) end end end --- add_chunk(minp) + mcl_vars.add_chunk(minp) end) minetest.register_on_generated=function(node_function) - mcl_mapgen_core.register_generator("mod_"..tostring(#mcl_mapgen_core.registered_generators+1), nil, node_function) + mcl_mapgen_core.register_generator("mod_"..tostring(#registered_generators+1), nil, node_function) end function mcl_mapgen_core.register_generator(id, lvm_function, node_function, priority, needs_param2) @@ -1917,18 +1881,18 @@ function mcl_mapgen_core.register_generator(id, lvm_function, node_function, pri needs_param2 = needs_param2, } - mcl_mapgen_core.registered_generators[id] = new_record + registered_generators[id] = new_record table.sort( - mcl_mapgen_core.registered_generators, + registered_generators, function(a, b) return (a.i < b.i) or ((a.i == b.i) and (a.vf ~= nil) and (b.vf == nil)) end) end function mcl_mapgen_core.unregister_generator(id) - if not mcl_mapgen_core.registered_generators[id] then return end - local rec = mcl_mapgen_core.registered_generators[id] - mcl_mapgen_core.registered_generators[id] = nil + if not registered_generators[id] then return end + local rec = registered_generators[id] + registered_generators[id] = nil if rec.vf then lvm = lvm - 1 end if rev.nf then nodes = nodes - 1 end if rec.needs_param2 then param2 = param2 - 1 end @@ -2131,24 +2095,26 @@ local function basic(vm, data, data2, emin, emax, area, minp, maxp, blockseed) -- Nether block fixes: -- * 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 + elseif emin.y <= mcl_vars.mg_nether_max and emax.y >= mcl_vars.mg_nether_min then 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"}) + local nodes = minetest.find_nodes_in_area(emin, emax, {"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 - 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(emin, emax, {"group:water"}) + for _, n in pairs(nodes) do + data[area:index(n.x, n.y, n.z)] = c_nether_lava end end @@ -2157,17 +2123,16 @@ local function basic(vm, data, data2, emin, emax, area, minp, maxp, blockseed) -- * Remove stone, sand, dirt in v6 so our End map generator works in v6. -- * Generate spawn platform (End portal destination) elseif minp.y <= mcl_vars.mg_end_max and maxp.y >= mcl_vars.mg_end_min then - local nodes, node + local nodes, n 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"}) + nodes = minetest.find_nodes_in_area(emin, emax, {"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"}) + nodes = minetest.find_nodes_in_area(emin, emax, {"mcl_core:water_source"}) end if #nodes > 0 then lvm_used = true - for n=1, #nodes do - node = nodes[n] - data[area:index(node.x, node.y, node.z)] = c_air + for _, n in pairs(nodes) do + data[area:index(n.x, n.y, n.z)] = c_air end end @@ -2220,48 +2185,3 @@ end mcl_mapgen_core.register_generator("main", basic, nil, 1, true) --- "Trivial" (actually NOT) function to just read the node and some stuff to not just return "ignore", like 5.3.0 does. --- p: Position, if it's wrong, {name="error"} node will return. --- force: optional (default: false) - Do the maximum to still read the node within us_timeout. --- us_timeout: optional (default: 244 = 0.000244 s = 1/80/80/80), set it at least to 3000000 to let mapgen to finish its job. --- --- returns node definition, eg. {name="air"}. Unfortunately still can return {name="ignore"}. -function mcl_mapgen_core.get_node(p, force, us_timeout) - -- check initial circumstances - if not p or not p.x or not p.y or not p.z then return {name="error"} end - - -- try common way - local node = minetest.get_node(p) - if node.name ~= "ignore" then - return node - end - - -- copy table to get sure it won't changed by other threads - local pos = {x=p.x,y=p.y,z=p.z} - - -- try LVM - minetest.get_voxel_manip():read_from_map(pos, pos) - node = minetest.get_node(pos) - if node.name ~= "ignore" or not force then - return node - end - - -- all ways failed - need to emerge (or forceload if generated) - local us_timeout = us_timeout or 244 - if mcl_mapgen_core.is_generated(pos) then - minetest.forceload_block(pos) - else - minetest.emerge_area(pos, pos) - end - - local t = minetest.get_us_time() - - node = minetest.get_node(pos) - - while (not node or node.name == "ignore") and (minetest.get_us_time() - t < us_timeout) do - node = minetest.get_node(pos) - end - - return node - -- it still can return "ignore", LOL, even if force = true, but only after time out -end diff --git a/mods/MAPGEN/mcl_structures/init.lua b/mods/MAPGEN/mcl_structures/init.lua index 96c620c99..f6317bdeb 100644 --- a/mods/MAPGEN/mcl_structures/init.lua +++ b/mods/MAPGEN/mcl_structures/init.lua @@ -272,7 +272,7 @@ local function hut_placement_callback(p1, p2, size, orientation, pr) if not p1 or not p2 then return end local legs = minetest.find_nodes_in_area(p1, p2, "mcl_core:tree") for i = 1, #legs do - while minetest.get_item_group(mcl_mapgen_core.get_node({x=legs[i].x, y=legs[i].y-1, z=legs[i].z}, true, 333333).name, "water") ~= 0 do + while minetest.get_item_group(mcl_vars.get_node({x=legs[i].x, y=legs[i].y-1, z=legs[i].z}, true, 333333).name, "water") ~= 0 do legs[i].y = legs[i].y - 1 minetest.swap_node(legs[i], {name = "mcl_core:tree", param2 = 2}) end @@ -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/MAPGEN/mcl_villages/buildings.lua b/mods/MAPGEN/mcl_villages/buildings.lua index 18d6c1e0b..e43db6d98 100644 --- a/mods/MAPGEN/mcl_villages/buildings.lua +++ b/mods/MAPGEN/mcl_villages/buildings.lua @@ -4,7 +4,7 @@ ------------------------------------------------------------------------------- function settlements.build_schematic(vm, data, va, pos, building, replace_wall, name) -- get building node material for better integration to surrounding - local platform_material = mcl_mapgen_core.get_node(pos) + local platform_material = mcl_vars.get_node(pos) if not platform_material or (platform_material.name == "air" or platform_material.name == "ignore") then return end diff --git a/mods/MAPGEN/mcl_villages/foundation.lua b/mods/MAPGEN/mcl_villages/foundation.lua index 67a2385f7..038a2f202 100644 --- a/mods/MAPGEN/mcl_villages/foundation.lua +++ b/mods/MAPGEN/mcl_villages/foundation.lua @@ -52,7 +52,7 @@ function settlements.terraform(settlement_info, pr) else -- write ground -- local p = {x=pos.x+xi, y=pos.y+yi, z=pos.z+zi} --- local node = mcl_mapgen_core.get_node(p) +-- local node = mcl_vars.get_node(p) -- if node and node.name ~= "air" then -- minetest.swap_node(p,{name="air"}) -- end diff --git a/mods/MAPGEN/mcl_villages/utils.lua b/mods/MAPGEN/mcl_villages/utils.lua index 2d96ba26f..d7617541d 100644 --- a/mods/MAPGEN/mcl_villages/utils.lua +++ b/mods/MAPGEN/mcl_villages/utils.lua @@ -1,28 +1,5 @@ -local c_dirt_with_grass = minetest.get_content_id("mcl_core:dirt_with_grass") -local c_dirt_with_snow = minetest.get_content_id("mcl_core:dirt_with_grass_snow") ---local c_dirt_with_dry_grass = minetest.get_content_id("mcl_core:dirt_with_dry_grass") -local c_podzol = minetest.get_content_id("mcl_core:podzol") -local c_sand = minetest.get_content_id("mcl_core:sand") -local c_desert_sand = minetest.get_content_id("mcl_core:redsand") ---local c_silver_sand = minetest.get_content_id("mcl_core:silver_sand") --- -local c_air = minetest.get_content_id("air") -local c_snow = minetest.get_content_id("mcl_core:snow") -local c_fern_1 = minetest.get_content_id("mcl_flowers:fern") -local c_fern_2 = minetest.get_content_id("mcl_flowers:fern") -local c_fern_3 = minetest.get_content_id("mcl_flowers:fern") -local c_rose = minetest.get_content_id("mcl_flowers:poppy") -local c_viola = minetest.get_content_id("mcl_flowers:blue_orchid") -local c_geranium = minetest.get_content_id("mcl_flowers:allium") -local c_tulip = minetest.get_content_id("mcl_flowers:tulip_orange") -local c_dandelion_y = minetest.get_content_id("mcl_flowers:dandelion") -local c_dandelion_w = minetest.get_content_id("mcl_flowers:oxeye_daisy") -local c_bush_leaves = minetest.get_content_id("mcl_core:leaves") -local c_bush_stem = minetest.get_content_id("mcl_core:tree") -local c_a_bush_leaves = minetest.get_content_id("mcl_core:acacialeaves") -local c_a_bush_stem = minetest.get_content_id("mcl_core:acaciatree") -local c_water_source = minetest.get_content_id("mcl_core:water_source") -local c_water_flowing = minetest.get_content_id("mcl_core:water_flowing") +local get_node = mcl_vars.get_node + ------------------------------------------------------------------------------- -- function to copy tables ------------------------------------------------------------------------------- @@ -53,9 +30,9 @@ function settlements.find_surface(pos, wait) -- check, in which direction to look for surface local surface_node if wait then - surface_node = mcl_mapgen_core.get_node(p6, true, 10000000) + surface_node = get_node(p6, true, 10000000) else - surface_node = mcl_mapgen_core.get_node(p6) + surface_node = get_node(p6) end if surface_node.name=="air" or surface_node.name=="ignore" then itter = -1 @@ -65,7 +42,7 @@ function settlements.find_surface(pos, wait) -- Check Surface_node and Node above -- if settlements.surface_mat[surface_node.name] then - local surface_node_plus_1 = mcl_mapgen_core.get_node({ x=p6.x, y=p6.y+1, z=p6.z}) + local surface_node_plus_1 = get_node({ x=p6.x, y=p6.y+1, z=p6.z}) if surface_node_plus_1 and surface_node and (string.find(surface_node_plus_1.name,"air") or string.find(surface_node_plus_1.name,"snow") or @@ -90,7 +67,7 @@ function settlements.find_surface(pos, wait) return nil end cnt = cnt+1 - surface_node = mcl_mapgen_core.get_node(p6) + surface_node = get_node(p6) end settlements.debug("find_surface5: cnt_max overflow") return nil diff --git a/mods/MAPGEN/tsm_railcorridors/init.lua b/mods/MAPGEN/tsm_railcorridors/init.lua index 982edcd0d..893f3d739 100644 --- a/mods/MAPGEN/tsm_railcorridors/init.lua +++ b/mods/MAPGEN/tsm_railcorridors/init.lua @@ -393,7 +393,7 @@ local function RecheckCartHack(params) local pos = params[1] local cart_id = params[2] -- Find cart - for _, obj in ipairs(minetest.get_objects_inside_radius(pos, 1)) do + for _, obj in pairs(minetest.get_objects_inside_radius(pos, 1)) do if obj ~= nil and obj:get_luaentity().name == cart_id then -- Cart found! We can now safely call the callback func. -- (calling it earlier has the danger of failing) diff --git a/mods/MISC/mcl_wip/API.md b/mods/MISC/mcl_wip/API.md new file mode 100644 index 000000000..e3439af77 --- /dev/null +++ b/mods/MISC/mcl_wip/API.md @@ -0,0 +1,16 @@ +# mcl_wip +Used to mark items or nodes as WIP. + +## mcl_wip.register_wip_item(itemname) +Register as a WIP item. +If isn't a valid itemname, an error will be shown after mods loaded. + +## mcl_wip.register_experimental_item(itemname) +Register as a experimental item. +If isn't a valid itemname, an error will be shown after mods loaded. + +## mcl_wip.registered_wip_items +Table containing WIP items names. + +## mcl_wip.registered_experimental_items +Table containing experimental items names. \ No newline at end of file diff --git a/mods/PLAYER/mcl_death_drop/API.md b/mods/PLAYER/mcl_death_drop/API.md new file mode 100644 index 000000000..b19e2fd7c --- /dev/null +++ b/mods/PLAYER/mcl_death_drop/API.md @@ -0,0 +1,14 @@ +# mcl_death_drop +Drop registered inventories on player death. + +## mcl_death_drop.register_dropped_list(inv, listname, drop) +* inv: can be: + * "PLAYER": will be interpreted like player inventory (to avoid multiple calling to get_inventory()) + * function(player): must return inventory +* listname: string +* drop: bool + * true: the entire list will be dropped + * false: items with curse_of_vanishing enchantement will be broken. + +## mcl_death_drop.registered_dropped_lists +Table containing dropped list inventory, name and drop state. \ No newline at end of file diff --git a/mods/PLAYER/mcl_death_drop/init.lua b/mods/PLAYER/mcl_death_drop/init.lua index 56e6ea522..7c54334a9 100644 --- a/mods/PLAYER/mcl_death_drop/init.lua +++ b/mods/PLAYER/mcl_death_drop/init.lua @@ -1,26 +1,40 @@ +local random = math.random + +mcl_death_drop = {} + +mcl_death_drop.registered_dropped_lists = {} + +function mcl_death_drop.register_dropped_list(inv, listname, drop) + table.insert(mcl_death_drop.registered_dropped_lists, {inv=inv, listname=listname, drop=drop}) +end + +mcl_death_drop.register_dropped_list("PLAYER", "main", true) +mcl_death_drop.register_dropped_list("PLAYER", "craft", true) +mcl_death_drop.register_dropped_list("PLAYER", "armor", true) +mcl_death_drop.register_dropped_list(function(player) return select(3, armor:get_valid_player(player)) end , "armor", false) + minetest.register_on_dieplayer(function(player) local keep = minetest.settings:get_bool("mcl_keepInventory", false) if keep == false then -- Drop inventory, crafting grid and armor - local inv = player:get_inventory() + local playerinv = player:get_inventory() local pos = player:get_pos() - local name, player_armor_inv, armor_armor_inv, pos = armor:get_valid_player(player, "[on_dieplayer]") -- No item drop if in deep void local void, void_deadly = mcl_worlds.is_in_void(pos) - local lists = { - { inv = inv, listname = "main", drop = true }, - { inv = inv, listname = "craft", drop = true }, - { inv = player_armor_inv, listname = "armor", drop = true }, - { inv = armor_armor_inv, listname = "armor", drop = false }, - } - for l=1,#lists do - local inv = lists[l].inv - local listname = lists[l].listname - local drop = lists[l].drop + + for l=1,#mcl_death_drop.registered_dropped_lists do + local inv = mcl_death_drop.registered_dropped_lists[l].inv + if inv == "PLAYER" then + inv = playerinv + elseif type(inv) == "function" then + inv = inv(player) + end + local listname = mcl_death_drop.registered_dropped_lists[l].listname + local drop = mcl_death_drop.registered_dropped_lists[l].drop if inv ~= nil then for i, stack in ipairs(inv:get_list(listname)) do - local x = math.random(0, 9)/3 - local z = math.random(0, 9)/3 + local x = random(0, 9)/3 + local z = random(0, 9)/3 pos.x = pos.x + x pos.z = pos.z + z if not void_deadly and drop and not mcl_enchanting.has_enchantment(stack, "curse_of_vanishing") then diff --git a/mods/PLAYER/mcl_hunger/init.lua b/mods/PLAYER/mcl_hunger/init.lua index 01d74a80d..5ae45591c 100644 --- a/mods/PLAYER/mcl_hunger/init.lua +++ b/mods/PLAYER/mcl_hunger/init.lua @@ -142,7 +142,7 @@ minetest.register_globalstep(function(dtime) timer = timer + dtime if main_timer > mcl_hunger.HUD_TICK or timer > 0.5 then if main_timer > mcl_hunger.HUD_TICK then main_timer = 0 end - for _,player in ipairs(minetest.get_connected_players()) do + for _,player in pairs(minetest.get_connected_players()) do local name = player:get_player_name() local h = tonumber(mcl_hunger.get_hunger(player)) diff --git a/mods/PLAYER/mcl_player/init.lua b/mods/PLAYER/mcl_player/init.lua index 449b062c5..210e2d19f 100644 --- a/mods/PLAYER/mcl_player/init.lua +++ b/mods/PLAYER/mcl_player/init.lua @@ -148,7 +148,7 @@ local player_attached = mcl_player.player_attached -- Check each player and apply animations minetest.register_globalstep(function(dtime) - for _, player in ipairs(minetest.get_connected_players()) do + for _, player in pairs(minetest.get_connected_players()) do local name = player:get_player_name() local model_name = player_model[name] local model = model_name and models[model_name] @@ -178,7 +178,7 @@ minetest.register_globalstep(function(dtime) -- Apply animations based on what the player is doing if player:get_hp() == 0 then - player_set_animation(player, "lay") + player_set_animation(player, "die") elseif walking and velocity.x > 0.35 or walking and velocity.x < -0.35 or walking and velocity.z > 0.35 or walking and velocity.z < -0.35 then if player_sneak[name] ~= controls.sneak then player_anim[name] = nil @@ -253,3 +253,28 @@ minetest.register_on_player_hpchange(function(player, hp_change, reason) end return hp_change end, true) + +minetest.register_on_respawnplayer(function(player) + local pos = player:get_pos() + minetest.add_particlespawner({ + amount = 50, + time = 0.001, + minpos = vector.add(pos, 0), + maxpos = vector.add(pos, 0), + minvel = vector.new(-5,-5,-5), + maxvel = vector.new(5,5,5), + minexptime = 1.1, + maxexptime = 1.5, + minsize = 1, + maxsize = 2, + collisiondetection = false, + vertical = false, + texture = "mcl_particles_mob_death.png^[colorize:#000000:255", + }) + + minetest.sound_play("mcl_mobs_mob_poof", { + pos = pos, + gain = 1.0, + max_hear_distance = 8, + }, true) +end) diff --git a/mods/PLAYER/mcl_playerinfo/init.lua b/mods/PLAYER/mcl_playerinfo/init.lua index 4c1454d95..5086f3195 100644 --- a/mods/PLAYER/mcl_playerinfo/init.lua +++ b/mods/PLAYER/mcl_playerinfo/init.lua @@ -52,7 +52,7 @@ minetest.register_globalstep(function(dtime) time = 0 -- check players - for _,player in ipairs(minetest.get_connected_players()) do + for _,player in pairs(minetest.get_connected_players()) do -- who am I? local name = player:get_player_name() diff --git a/mods/PLAYER/mcl_playerplus/init.lua b/mods/PLAYER/mcl_playerplus/init.lua index ab8487396..767b275e4 100644 --- a/mods/PLAYER/mcl_playerplus/init.lua +++ b/mods/PLAYER/mcl_playerplus/init.lua @@ -33,6 +33,53 @@ local dir_to_pitch = function(dir) return -math.atan2(-dir.y, xz) end +local player_vel_yaws = {} + +function limit_vel_yaw(player_vel_yaw, yaw) + if player_vel_yaw < 0 then + player_vel_yaw = player_vel_yaw + 360 + end + + if yaw < 0 then + yaw = yaw + 360 + end + + if math.abs(player_vel_yaw - yaw) > 40 then + local player_vel_yaw_nm, yaw_nm = player_vel_yaw, yaw + if player_vel_yaw > yaw then + player_vel_yaw_nm = player_vel_yaw - 360 + else + yaw_nm = yaw - 360 + end + if math.abs(player_vel_yaw_nm - yaw_nm) > 40 then + local diff = math.abs(player_vel_yaw - yaw) + if diff > 180 and diff < 185 or diff < 180 and diff > 175 then + player_vel_yaw = yaw + elseif diff < 180 then + if player_vel_yaw < yaw then + player_vel_yaw = yaw - 40 + else + player_vel_yaw = yaw + 40 + end + else + if player_vel_yaw < yaw then + player_vel_yaw = yaw + 40 + else + player_vel_yaw = yaw - 40 + end + end + end + end + + if player_vel_yaw < 0 then + player_vel_yaw = player_vel_yaw + 360 + elseif player_vel_yaw > 360 then + player_vel_yaw = player_vel_yaw - 360 + end + + return player_vel_yaw +end + local pitch, name, node_stand, node_stand_below, node_head, node_feet, pos minetest.register_globalstep(function(dtime) @@ -41,31 +88,40 @@ minetest.register_globalstep(function(dtime) -- Update jump status immediately since we need this info in real time. -- WARNING: This section is HACKY as hell since it is all just based on heuristics. - for _,player in ipairs(get_connected_players()) do + for _,player in pairs(get_connected_players()) do local controls = player:get_player_control() name = player:get_player_name() + local meta = player:get_meta() + local player_velocity = player:get_velocity() or player:get_player_velocity() + local wielded = player:get_wielded_item() + -- controls head bone - local pitch = degrees(player:get_look_vertical()) * -1 - local yaw = degrees(player:get_look_horizontal()) * -1 + local pitch = - degrees(player:get_look_vertical()) + local yaw = degrees(player:get_look_horizontal()) - local player_vel_yaw = 0 - - if degrees(dir_to_yaw(player_velocity)) == 0 then - yaw = 0 - else - player_vel_yaw = degrees(dir_to_yaw(player_velocity)) + local player_vel_yaw = degrees(dir_to_yaw(player_velocity)) + if player_vel_yaw == 0 then + player_vel_yaw = player_vel_yaws[name] or yaw end + player_vel_yaw = limit_vel_yaw(player_vel_yaw, yaw) + player_vel_yaws[name] = player_vel_yaw - -- controls right and left arms pitch when shooting a bow or punching - if string.find(player:get_wielded_item():get_name(), "mcl_bows:bow") and controls.RMB and not controls.LMB and not controls.up and not controls.down and not controls.left and not controls.right then + -- controls right and left arms pitch when shooting a bow + if string.find(wielded:get_name(), "mcl_bows:bow") and controls.RMB and not controls.LMB and not controls.up and not controls.down and not controls.left and not controls.right then player:set_bone_position("Arm_Right_Pitch_Control", vector.new(-3,5.785,0), vector.new(pitch+90,-30,pitch * -1 * .35)) player:set_bone_position("Arm_Left_Pitch_Control", vector.new(3.5,5.785,0), vector.new(pitch+90,43,pitch * .35)) + -- when punching elseif controls.LMB and player:get_attach() == nil then player:set_bone_position("Arm_Right_Pitch_Control", vector.new(-3,5.785,0), vector.new(pitch,0,0)) player:set_bone_position("Arm_Left_Pitch_Control", vector.new(3,5.785,0), vector.new(0,0,0)) + -- when holding an item. + elseif wielded:get_name() ~= "" then + player:set_bone_position("Arm_Right_Pitch_Control", vector.new(-3,5.785,0), vector.new(20,0,0)) + player:set_bone_position("Arm_Left_Pitch_Control", vector.new(3,5.785,0), vector.new(0,0,0)) + -- resets arms pitch else player:set_bone_position("Arm_Left_Pitch_Control", vector.new(3,5.785,0), vector.new(0,0,0)) player:set_bone_position("Arm_Right_Pitch_Control", vector.new(-3,5.785,0), vector.new(0,0,0)) @@ -80,42 +136,30 @@ minetest.register_globalstep(function(dtime) player:set_bone_position("Body_Control", vector.new(0,6.3,0), vector.new(0,0,0)) elseif get_item_group(mcl_playerinfo[name].node_head, "water") ~= 0 and player:get_attach() == nil and is_sprinting(name) == true then -- set head pitch and yaw when swimming - player:set_bone_position("Head", vector.new(0,6.3,0), vector.new(pitch+90-degrees(dir_to_pitch(player_velocity)),yaw - player_vel_yaw * -1,0)) + player:set_bone_position("Head", vector.new(0,6.3,0), vector.new(pitch+90-degrees(dir_to_pitch(player_velocity)),player_vel_yaw - yaw,0)) -- sets eye height, and nametag color accordingly player:set_properties({collisionbox = {-0.35,0,-0.35,0.35,0.8,0.35}, eye_height = 0.5, nametag_color = { r = 225, b = 225, a = 225, g = 225 }}) -- control body bone when swimming - player:set_bone_position("Body_Control", vector.new(0,6.3,0), vector.new(degrees(dir_to_pitch(player_velocity)) - 90,player_vel_yaw * -1 - yaw + 180,0)) + player:set_bone_position("Body_Control", vector.new(0,6.3,0), vector.new(degrees(dir_to_pitch(player_velocity)) - 90,-player_vel_yaw + yaw + 180,0)) elseif player:get_attach() == nil then -- sets eye height, and nametag color accordingly player:set_properties({collisionbox = {-0.35,0,-0.35,0.35,1.8,0.35}, eye_height = 1.5, nametag_color = { r = 225, b = 225, a = 225, g = 225 }}) - if player_velocity.x > 0.35 or player_velocity.z > 0.35 or player_velocity.x < -0.35 or player_velocity.z < -0.35 then - if player_vel_yaw * -1 - yaw < 90 or player_vel_yaw * -1 - yaw > 270 then - -- controls head and Body_Control bones while moving backwards - player:set_bone_position("Head", vector.new(0,6.3,0), vector.new(pitch,yaw - player_vel_yaw * -1,0)) - player:set_bone_position("Body_Control", vector.new(0,6.3,0), vector.new(0,player_vel_yaw * -1 - yaw,0)) - else - -- controls head and Body_Control bones while moving forwards - player:set_bone_position("Head", vector.new(0,6.3,0), vector.new(pitch,yaw - player_vel_yaw * -1 + 180,0)) - player:set_bone_position("Body_Control", vector.new(0,6.3,0), vector.new(0,player_vel_yaw * -1 - yaw + 180,0)) - end - else - player:set_bone_position("Head", vector.new(0,6.3,0), vector.new(pitch,0,0)) - player:set_bone_position("Body_Control", vector.new(0,6.3,0), vector.new(0,0,0)) - end + player:set_bone_position("Head", vector.new(0,6.3,0), vector.new(pitch, player_vel_yaw - yaw, 0)) + player:set_bone_position("Body_Control", vector.new(0,6.3,0), vector.new(0, -player_vel_yaw + yaw, 0)) else local attached = player:get_attach(parent) local attached_yaw = degrees(attached:get_yaw()) player:set_properties({collisionbox = {-0.35,0,-0.35,0.35,1.8,0.35}, eye_height = 1.5, nametag_color = { r = 225, b = 225, a = 225, g = 225 }}) - player:set_bone_position("Head", vector.new(0,6.3,0), vector.new(pitch,degrees(player:get_look_horizontal()) * -1 + attached_yaw,0)) + player:set_bone_position("Head", vector.new(0,6.3,0), vector.new(pitch, -limit_vel_yaw(yaw, attached_yaw) + attached_yaw, 0)) player:set_bone_position("Body_Control", vector.new(0,6.3,0), vector.new(0,0,0)) end if mcl_playerplus_internal[name].jump_cooldown > 0 then mcl_playerplus_internal[name].jump_cooldown = mcl_playerplus_internal[name].jump_cooldown - dtime end - if player:get_player_control().jump and mcl_playerplus_internal[name].jump_cooldown <= 0 then + if controls.jump and mcl_playerplus_internal[name].jump_cooldown <= 0 then pos = player:get_pos() @@ -173,7 +217,7 @@ minetest.register_globalstep(function(dtime) time = 0 -- check players - for _,player in ipairs(get_connected_players()) do + for _,player in pairs(get_connected_players()) do -- who am I? local name = player:get_player_name() @@ -208,13 +252,7 @@ minetest.register_globalstep(function(dtime) playerphysics.add_physics_factor(player, "speed", "mcl_playerplus:surface", 0.4) end end - else - -- Reset speed decrease - playerphysics.remove_physics_factor(player, "speed", "mcl_playerplus:surface") - end - - -- Swimming? Check if boots are enchanted with depth strider - if get_item_group(node_feet, "liquid") ~= 0 and mcl_enchanting.get_enchantment(player:get_inventory():get_stack("armor", 5), "depth_strider") then + elseif get_item_group(node_feet, "liquid") ~= 0 and mcl_enchanting.get_enchantment(player:get_inventory():get_stack("armor", 5), "depth_strider") then local boots = player:get_inventory():get_stack("armor", 5) local depth_strider = mcl_enchanting.get_enchantment(boots, "depth_strider") diff --git a/mods/PLAYER/mcl_skins/init.lua b/mods/PLAYER/mcl_skins/init.lua index ac770f8f5..5956aab7c 100644 --- a/mods/PLAYER/mcl_skins/init.lua +++ b/mods/PLAYER/mcl_skins/init.lua @@ -227,6 +227,9 @@ minetest.register_on_player_receive_fields(function(player, formname, fields) if mcl_skins.skin_count <= 6 then -- Change skin immediately if there are not many skins mcl_skins.cycle_skin(player) + if player:get_attach() ~= nil then + mcl_player.player_set_animation(player, "sit") + end else -- Show skin selection formspec otherwise mcl_skins.show_formspec(player:get_player_name()) @@ -237,7 +240,7 @@ end) mcl_skins.show_formspec = function(playername) local formspec = "size[7,8.5]" - formspec = formspec .. "label[2,2;" .. minetest.formspec_escape(minetest.colorize("#383838", S("Select player skin:"))) .. "]" + formspec = formspec .. "label[2,2;" .. minetest.formspec_escape(minetest.colorize(mcl_colors.DARK_GRAY, S("Select player skin:"))) .. "]" .. "textlist[0,2.5;6.8,6;skins_set;" local meta @@ -265,7 +268,7 @@ mcl_skins.show_formspec = function(playername) if meta then if meta.name and meta.name ~= "" then - formspec = formspec .. "label[2,0.5;" .. minetest.formspec_escape(minetest.colorize("#383838", S("Name: @1", meta.name))) .. "]" + formspec = formspec .. "label[2,0.5;" .. minetest.formspec_escape(minetest.colorize(mcl_colors.DARK_GRAY, S("Name: @1", meta.name))) .. "]" end end @@ -294,4 +297,3 @@ minetest.register_on_player_receive_fields(function(player, formname, fields) end) minetest.log("action", "[mcl_skins] Mod initialized with "..mcl_skins.skin_count.." custom skin(s)") - diff --git a/mods/PLAYER/mcl_spawn/init.lua b/mods/PLAYER/mcl_spawn/init.lua index 6a3d543d3..fe88cf3de 100644 --- a/mods/PLAYER/mcl_spawn/init.lua +++ b/mods/PLAYER/mcl_spawn/init.lua @@ -81,13 +81,7 @@ local dir_step = storage:get_int("mcl_spawn_dir_step") or 0 local dir_ind = storage:get_int("mcl_spawn_dir_ind") or 1 local emerge_pos1, emerge_pos2 --- Get world 'mapgen_limit' and 'chunksize' to calculate 'spawn_limit'. --- This accounts for how mapchunks are not generated if they or their shell exceed --- 'mapgen_limit'. - -local mapgen_limit = tonumber(minetest.get_mapgen_setting("mapgen_limit")) -local chunksize = tonumber(minetest.get_mapgen_setting("chunksize")) -local spawn_limit = math.max(mapgen_limit - (chunksize + 1) * 16, 0) +local spawn_limit = mcl_vars.mapgen_edge_max --Functions @@ -503,10 +497,17 @@ function mcl_spawn.shadow_worker() mcl_spawn.search() minetest.log("action", "[mcl_spawn] Started world spawn point search") end - if success and ((not good_for_respawn(wsp)) or (not can_find_tree(wsp))) then - success = false - minetest.log("action", "[mcl_spawn] World spawn position isn't safe anymore: "..minetest.pos_to_string(wsp)) - mcl_spawn.search() + + if success then + local wsp_node = minetest.get_node(wsp) + if wsp_node and wsp_node.name == "ignore" then + -- special case - respawn area unloaded from memory - it's okay, skip for now + + elseif ((not good_for_respawn(wsp)) or ((no_trees_area_counter >= 0) and not can_find_tree(wsp))) then + success = false + minetest.log("action", "[mcl_spawn] World spawn position isn't safe anymore: "..minetest.pos_to_string(wsp)) + mcl_spawn.search() + end end minetest.after(respawn_search_interval, mcl_spawn.shadow_worker) diff --git a/mods/PLAYER/wieldview/init.lua b/mods/PLAYER/wieldview/init.lua index 4514ca5e6..48f3f99bd 100644 --- a/mods/PLAYER/wieldview/init.lua +++ b/mods/PLAYER/wieldview/init.lua @@ -72,13 +72,13 @@ 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) minetest.register_globalstep(function() - for _,player in ipairs(minetest.get_connected_players()) do + for _,player in pairs(minetest.get_connected_players()) do wieldview:update_wielded_item(player) end 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 0b0145c7f..a19956796 100644 --- a/mods/PLAYER/wieldview/transform.lua +++ b/mods/PLAYER/wieldview/transform.lua @@ -1,42 +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_buckets:bucket_empty"]="R270", - ["mcl_buckets:bucket_water"]="R270", - ["mcl_buckets:bucket_river_water"]="R270", - ["mcl_buckets:bucket_lava"]="R270", - ["mcl_mobitems:milk_bucket"]="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", } diff --git a/settingtypes.txt b/settingtypes.txt index af0e18d85..67e686d1e 100644 --- a/settingtypes.txt +++ b/settingtypes.txt @@ -129,6 +129,9 @@ mcl_superflat_classic (Classic superflat map generation) bool false # If disabled, no ores will be generated. mcl_generate_ores (Generate Ores) bool true +# If disabled, command blocks will be unusuable (but still present). +mcl_enable_commandblocks (Enable Command Blocks) bool true + # Make some blocks emit decorative particles like flames. This setting # specifies the detail level of particles, with higher levels being # more CPU demanding.