diff --git a/API.md b/API.md index 344414b72..738fe52fa 100644 --- a/API.md +++ b/API.md @@ -39,7 +39,7 @@ A lot of things are possible by using one of the APIs in the mods. Note that not * Dispenser support: `ITEMS/REDSTONE/mcl_dispensers` ## Mobs -* Mobs: `ENTITIES/mcl_mods` +* Mobs: `ENTITIES/mcl_mobs` MineClone 2 uses its own mobs framework, called “Mobs Redo: MineClone 2 Edition” or “MRM” for short. This is a fork of Mobs Redo [`mobs`] by TenPlus1. @@ -67,6 +67,9 @@ chances are good that it works out of the box. * Get flowing direction of liquids: `CORE/flowlib` * `on_walk_over` callback for nodes: `CORE/walkover` * Get node names close to player (to reduce constant querying): `PLAYER/mcl_playerinfo` +* Explosion API +* Music discs API +* Flowers and flower pots ### Unstable APIs The following APIs may be subject to change in future. You could already use these APIs but there will probably be breaking changes in the future, or the API is not as fleshed out as it should be. Use at your own risk! @@ -79,12 +82,10 @@ The following APIs may be subject to change in future. You could already use the ### Planned APIs -* Flowers * Saplings and trees * Custom banner patterns * Custom dimensions * Custom portals -* Music discs * Dispenser and dropper support * Proper sky and weather APIs -* Explosion API + diff --git a/GROUPS.md b/GROUPS.md index f94b04979..8c0c3563e 100644 --- a/GROUPS.md +++ b/GROUPS.md @@ -21,7 +21,7 @@ The basic digging time groups determine by which tools a node can be dug. * `swordy=1`: Diggable by sword (any material), and this node is *not* a cobweb * `swordy_cobweb=1`: Diggable by sword (any material), and this node is a cobweb * `shearsy=1`: Diggable by shears, and this node is *not* wool -* `shearsy=wool=1`: Diggable by shears, and this node is wool +* `shearsy_wool=1`: Diggable by shears, and this node is wool * `handy=1`: Breakable by hand and this node gives it useful drop when dug by hand. All nodes which are breakable by pickaxe, axe, shovel, sword or shears are also automatically breakable by hand, but not neccess * `creative_breakable=1`: Block is breakable by hand in creative mode. This group is implied if the node belongs to any other digging group diff --git a/README.md b/README.md index c94081bf0..302c188fd 100644 --- a/README.md +++ b/README.md @@ -2,7 +2,7 @@ An unofficial Minecraft-like game for Minetest. Forked from MineClone by davedevils. Developed by many people. Not developed or endorsed by Mojang AB. -Version: 0.70.0 +Version: 0.71.0 ### Gameplay You start in a randomly-generated world made entirely of cubes. You can explore @@ -185,6 +185,11 @@ Please report all bugs and missing Minecraft features here: +## Chating with the community +Join our discord server at: + + + ## Other readme files * `LICENSE.txt`: The GPLv3 license text @@ -206,6 +211,7 @@ There are so many people to list (sorry). Check out the respective mod directori * [bzoss](https://github.com/bzoss): Status effects, potions, brewing stand * kay27 : Experience system, bugfixes, optimizations (Current maintainer) * [EliasFleckenstein03](https://github.com/EliasFleckenstein03): End crystals, enchanting, burning mobs / players, animated chests, bugfixes (Current maintainer) +* epCode: Better player animations, new logo * 2mac: Fix bug with powered rail * Lots of other people: TO BE WRITTEN (see mod directories for details) diff --git a/description.txt b/description.txt index 805bdb217..d45188894 100644 --- a/description.txt +++ b/description.txt @@ -1 +1 @@ -A survival sandbox game. Survive, gather, hunt, mine, build, explore, and do much more. Faithful clone of Minecraft 1.11. This is a work in progress! Expect bugs! +A survival sandbox game. Survive, gather, hunt, mine, build, explore, and do much more. Faithful clone of Minecraft 1.12. This is a work in progress! Expect bugs! diff --git a/menu/header.png b/menu/header.png index 5d34dd6a2..11435df51 100644 Binary files a/menu/header.png and b/menu/header.png differ diff --git a/minetest.conf b/minetest.conf index 90539659c..7e1ca9cd8 100644 --- a/minetest.conf +++ b/minetest.conf @@ -32,4 +32,13 @@ mgvalleys_spflags = noaltitude_chill,noaltitude_dry,nohumid_rivers,vary_river_de # MCL2-specific stuff keepInventory = false +# Performance settings 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 +csm_restriction_flags = 0 +enable_mod_channels = true diff --git a/mods/CORE/_mcl_autogroup/depends.txt b/mods/CORE/_mcl_autogroup/depends.txt deleted file mode 100644 index e69de29bb..000000000 diff --git a/mods/CORE/_mcl_autogroup/description.txt b/mods/CORE/_mcl_autogroup/description.txt deleted file mode 100644 index dbc4f3186..000000000 --- a/mods/CORE/_mcl_autogroup/description.txt +++ /dev/null @@ -1 +0,0 @@ -MineClone 2 core mod which automatically adds groups to all items. Very important for digging times. diff --git a/mods/CORE/_mcl_autogroup/mod.conf b/mods/CORE/_mcl_autogroup/mod.conf index fb171b765..11efdf9d1 100644 --- a/mods/CORE/_mcl_autogroup/mod.conf +++ b/mods/CORE/_mcl_autogroup/mod.conf @@ -1 +1,3 @@ name = _mcl_autogroup +author = Wuzzy +description = MineClone 2 core mod which automatically adds groups to all items. Very important for digging times. diff --git a/mods/CORE/biomeinfo/mod.conf b/mods/CORE/biomeinfo/mod.conf index 95be561a3..8e9f3b1d0 100644 --- a/mods/CORE/biomeinfo/mod.conf +++ b/mods/CORE/biomeinfo/mod.conf @@ -1,2 +1,3 @@ name = biomeinfo +author = Wuzzy description = Simple API to get data about biomes. diff --git a/mods/CORE/controls/init.lua b/mods/CORE/controls/init.lua index a219b794c..2ceb7e902 100644 --- a/mods/CORE/controls/init.lua +++ b/mods/CORE/controls/init.lua @@ -1,3 +1,6 @@ +local get_connected_players = minetest.get_connected_players +local clock = os.clock + controls = {} controls.players = {} @@ -42,7 +45,7 @@ minetest.register_on_leaveplayer(function(player) end) minetest.register_globalstep(function(dtime) - for _, player in pairs(minetest.get_connected_players()) do + for _, player in pairs(get_connected_players()) do local player_name = player:get_player_name() local player_controls = player:get_player_control() if controls.players[player_name] then @@ -53,15 +56,15 @@ minetest.register_globalstep(function(dtime) for _, func in pairs(controls.registered_on_press) do func(player, cname) end - controls.players[player_name][cname] = {true, os.clock()} + controls.players[player_name][cname] = {true, clock()} elseif cbool==true and controls.players[player_name][cname][1]==true then for _, func in pairs(controls.registered_on_hold) do - func(player, cname, os.clock()-controls.players[player_name][cname][2]) + func(player, cname, clock()-controls.players[player_name][cname][2]) end --Release a key elseif cbool==false and controls.players[player_name][cname][1]==true then for _, func in pairs(controls.registered_on_release) do - func(player, cname, os.clock()-controls.players[player_name][cname][2]) + func(player, cname, clock()-controls.players[player_name][cname][2]) end controls.players[player_name][cname] = {false} end diff --git a/mods/CORE/controls/mod.conf b/mods/CORE/controls/mod.conf index 8fab3aa2b..83ebb2e25 100644 --- a/mods/CORE/controls/mod.conf +++ b/mods/CORE/controls/mod.conf @@ -1 +1,4 @@ -name=controls +name = controls +author = Arcelmi +description = Controls framework by Arcelmi + diff --git a/mods/CORE/flowlib/mod.conf b/mods/CORE/flowlib/mod.conf index 0d982481c..7b3a325f3 100644 --- a/mods/CORE/flowlib/mod.conf +++ b/mods/CORE/flowlib/mod.conf @@ -1 +1,4 @@ name = flowlib +author = Qwertymine3 +description = Simple flow functions for use in Minetest mods by Qwertymine3 + diff --git a/mods/CORE/mcl_attached/description.txt b/mods/CORE/mcl_attached/description.txt deleted file mode 100644 index 3532db31d..000000000 --- a/mods/CORE/mcl_attached/description.txt +++ /dev/null @@ -1 +0,0 @@ -Adds additional ways for nodes to be attached. diff --git a/mods/CORE/mcl_attached/mod.conf b/mods/CORE/mcl_attached/mod.conf new file mode 100644 index 000000000..7ad1b4a4c --- /dev/null +++ b/mods/CORE/mcl_attached/mod.conf @@ -0,0 +1,3 @@ +name = mcl_attached +author = Wuzzy +description = Adds additional ways for nodes to be attached. diff --git a/mods/CORE/mcl_colors/init.lua b/mods/CORE/mcl_colors/init.lua new file mode 100644 index 000000000..e88f91d9d --- /dev/null +++ b/mods/CORE/mcl_colors/init.lua @@ -0,0 +1,36 @@ +mcl_colors = { + BLACK = "#000000", + DARK_BLUE = "#0000AA", + DARK_GREEN = "#00AA00", + DARK_AQUA = "#00AAAA", + DARK_RED = "#AA0000", + DARK_PURPLE = "#AA00AA", + GOLD = "#FFAA00", + GRAY = "#AAAAAA", + DARK_GRAY = "#555555", + BLUE = "#5555FF", + GREEN = "#55FF55", + AQUA = "#55FFFF", + RED = "#FF5555", + LIGHT_PURPLE = "#FF55FF", + YELLOW = "#FFFF55", + WHITE = "#FFFFFF", + background = { + BLACK = "#000000", + DARK_BLUE = "#00002A", + DARK_GREEN = "#002A00", + DARK_AQUA = "#002A2A", + DARK_RED = "#2A0000", + DARK_PURPLE = "#2A002A", + GOLD = "#2A2A00", + GRAY = "#2A2A2A", + DARK_GRAY = "#151515", + BLUE = "#15153F", + GREEN = "#153F15", + AQUA = "#153F3F", + RED = "#3F1515", + LIGHT_PURPLE = "#3F153F", + YELLOW = "#3F3F15", + WHITE = "#373501", + } +} diff --git a/mods/CORE/mcl_colors/mod.conf b/mods/CORE/mcl_colors/mod.conf new file mode 100644 index 000000000..549d94351 --- /dev/null +++ b/mods/CORE/mcl_colors/mod.conf @@ -0,0 +1,3 @@ +name = mcl_colors +author = Fleckenstein +description = The HTML sequences for the minecraft colors diff --git a/mods/CORE/mcl_explosions/init.lua b/mods/CORE/mcl_explosions/init.lua index 7607ecf0d..34375248e 100644 --- a/mods/CORE/mcl_explosions/init.lua +++ b/mods/CORE/mcl_explosions/init.lua @@ -18,6 +18,16 @@ local CONTENT_FIRE = minetest.get_content_id("mcl_fire:fire") local S = minetest.get_translator("mcl_explosions") +local hash_node_position = minetest.hash_node_position +local get_objects_inside_radius = minetest.get_objects_inside_radius +local get_position_from_hash = minetest.get_position_from_hash +local get_node_drops = minetest.get_node_drops +local get_name_from_content_id = minetest.get_name_from_content_id +local get_voxel_manip = minetest.get_voxel_manip +local bulk_set_node = minetest.bulk_set_node +local check_for_falling = minetest.check_for_falling +local add_item = minetest.add_item + -- Saved sphere explosion shapes for various radiuses local sphere_shapes = {} @@ -64,7 +74,7 @@ local function compute_sphere_rays(radius) local d = x * x + y * y + z * z if d <= radius * radius then local pos = { x = x, y = y, z = z } - sphere[minetest.hash_node_position(pos)] = pos + sphere[hash_node_position(pos)] = pos break end end @@ -79,7 +89,7 @@ local function compute_sphere_rays(radius) local d = x * x + y * y + z * z if d <= radius * radius then local pos = { x = x, y = y, z = z } - sphere[minetest.hash_node_position(pos)] = pos + sphere[hash_node_position(pos)] = pos break end end @@ -94,7 +104,7 @@ local function compute_sphere_rays(radius) local d = x * x + y * y + z * z if d <= radius * radius then local pos = { x = x, y = y, z = z } - sphere[minetest.hash_node_position(pos)] = pos + sphere[hash_node_position(pos)] = pos break end end @@ -149,12 +159,14 @@ end -- max_blast_resistance - The explosion will treat all non-indestructible nodes -- as having a blast resistance of no more than this -- value +-- grief_protected - If true, the explosion will also destroy nodes which have +-- been protected -- -- Note that this function has been optimized, it contains code which has been -- inlined to avoid function calls and unnecessary table creation. This was -- measured to give a significant performance increase. local function trace_explode(pos, strength, raydirs, radius, info, puncher) - local vm = minetest.get_voxel_manip() + local vm = get_voxel_manip() local emin, emax = vm:read_from_map(vector.subtract(pos, radius), vector.add(pos, radius)) @@ -178,6 +190,7 @@ local function trace_explode(pos, strength, raydirs, radius, info, puncher) local drop_chance = info.drop_chance local fire = info.fire local max_blast_resistance = info.max_blast_resistance + local grief_protected = info.grief_protected -- Trace rays for environment destruction if info.griefing then @@ -194,6 +207,7 @@ local function trace_explode(pos, strength, raydirs, radius, info, puncher) local npos_x = math.floor(rpos_x + 0.5) local npos_y = math.floor(rpos_y + 0.5) local npos_z = math.floor(rpos_z + 0.5) + local npos = { x = npos_x, y = npos_y, z = npos_z } local idx = (npos_z - emin_z) * zstride + (npos_y - emin_y) * ystride + npos_x - emin_x + 1 @@ -203,7 +217,7 @@ local function trace_explode(pos, strength, raydirs, radius, info, puncher) br = max_blast_resistance end - local hash = minetest.hash_node_position({x=npos_x, y=npos_y, z=npos_z}) + local hash = hash_node_position(npos) rpos_x = rpos_x + STEP_LENGTH * rdir_x rpos_y = rpos_y + STEP_LENGTH * rdir_y @@ -215,8 +229,10 @@ local function trace_explode(pos, strength, raydirs, radius, info, puncher) break end - if cid ~= minetest.CONTENT_AIR and not minetest.is_protected({x = npos_x, y = npos_y, z = npos_z}, "") then - destroy[hash] = idx + if cid ~= minetest.CONTENT_AIR then + if not minetest.is_protected(npos, "") or grief_protected then + destroy[hash] = idx + end end end end @@ -224,7 +240,7 @@ local function trace_explode(pos, strength, raydirs, radius, info, puncher) -- Entities in radius of explosion local punch_radius = 2 * strength - local objs = minetest.get_objects_inside_radius(pos, punch_radius) + local objs = get_objects_inside_radius(pos, punch_radius) -- Trace rays for entity damage for _, obj in pairs(objs) do @@ -329,13 +345,13 @@ local function trace_explode(pos, strength, raydirs, radius, info, puncher) minetest.after(0.3, function(obj, damage, impact, punch_dir) -- 0.2 is minimum delay for closing old formspec and open died formspec -- TODO: REMOVE THIS IN THE FUTURE if not obj then return end obj:punch(obj, 10, { damage_groups = { full_punch_interval = 1, fleshy = damage, knockback = impact * 20.0 } }, punch_dir) - obj:add_player_velocity(vector.multiply(punch_dir, impact * 20)) + obj:add_velocity(vector.multiply(punch_dir, impact * 20)) end, obj, damage, impact, vector.new(punch_dir)) else obj:punch(source, 10, { damage_groups = { full_punch_interval = 1, fleshy = damage, knockback = impact * 20.0 } }, punch_dir) if obj:is_player() then - obj:add_player_velocity(vector.multiply(punch_dir, impact * 20)) + obj:add_velocity(vector.multiply(punch_dir, impact * 20)) elseif ent.tnt_knockback then obj:add_velocity(vector.multiply(punch_dir, impact * 20)) end @@ -353,46 +369,46 @@ local function trace_explode(pos, strength, raydirs, radius, info, puncher) local remove = true if do_drop or on_blast ~= nil then - local npos = minetest.get_position_from_hash(hash) + local npos = get_position_from_hash(hash) if on_blast ~= nil then on_blast(npos, 1.0, do_drop) remove = false else - local name = minetest.get_name_from_content_id(data[idx]) - local drop = minetest.get_node_drops(name, "") + local name = get_name_from_content_id(data[idx]) + local drop = get_node_drops(name, "") for _, item in ipairs(drop) do if type(item) ~= "string" then item = item:get_name() .. item:get_count() end - minetest.add_item(npos, item) + add_item(npos, item) end end end if remove then if mod_fire and fire and math.random(1, 3) == 1 then - table.insert(fires, minetest.get_position_from_hash(hash)) + table.insert(fires, get_position_from_hash(hash)) else - table.insert(airs, minetest.get_position_from_hash(hash)) + table.insert(airs, get_position_from_hash(hash)) end end end -- We use bulk_set_node instead of LVM because we want to have on_destruct and -- on_construct being called if #airs > 0 then - minetest.bulk_set_node(airs, {name="air"}) + bulk_set_node(airs, {name="air"}) end if #fires > 0 then - minetest.bulk_set_node(fires, {name="mcl_fire:fire"}) + bulk_set_node(fires, {name="mcl_fire:fire"}) end -- Update falling nodes for a=1, #airs do local p = airs[a] - minetest.check_for_falling({x=p.x, y=p.y+1, z=p.z}) + check_for_falling({x=p.x, y=p.y+1, z=p.z}) end for f=1, #fires do local p = fires[f] - minetest.check_for_falling({x=p.x, y=p.y+1, z=p.z}) + check_for_falling({x=p.x, y=p.y+1, z=p.z}) end -- Log explosion @@ -418,6 +434,8 @@ end -- particles - If true, the explosion will create particles (default: true) -- fire - If true, 1/3 nodes become fire (default: false) -- griefing - If true, the explosion will destroy nodes (default: true) +-- grief_protected - If true, the explosion will also destroy nodes which have +-- been protected (default: false) function mcl_explosions.explode(pos, strength, info, puncher) if info == nil then info = {} @@ -437,6 +455,7 @@ function mcl_explosions.explode(pos, strength, info, puncher) if info.sound == nil then info.sound = true end if info.fire == nil then info.fire = false end if info.griefing == nil then info.griefing = true end + if info.grief_protected == nil then info.grief_protected = false end if info.max_blast_resistance == nil then info.max_blast_resistance = INDESTRUCT_BLASTRES end diff --git a/mods/CORE/mcl_explosions/mod.conf b/mods/CORE/mcl_explosions/mod.conf index 4ec206e17..5c203e621 100644 --- a/mods/CORE/mcl_explosions/mod.conf +++ b/mods/CORE/mcl_explosions/mod.conf @@ -1,4 +1,5 @@ name = mcl_explosions +author = ryvnf description = A common API to create explosions. depends = mcl_particles optional_depends = mcl_fire diff --git a/mods/CORE/mcl_init/description.txt b/mods/CORE/mcl_init/description.txt deleted file mode 100644 index 4ab7458f1..000000000 --- a/mods/CORE/mcl_init/description.txt +++ /dev/null @@ -1 +0,0 @@ -Initialization mod of MineClone 2. Defines some common shared variables and sets up initial default settings which have to be set at the beginning. diff --git a/mods/CORE/mcl_init/init.lua b/mods/CORE/mcl_init/init.lua index ebbfd5591..884ebfae1 100644 --- a/mods/CORE/mcl_init/init.lua +++ b/mods/CORE/mcl_init/init.lua @@ -46,6 +46,42 @@ local numcmax = math.max(math.floor((mapgen_limit_max - ccfmax) / chunk_size_in_ 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 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) +end + +function mcl_vars.pos_to_block(pos) + return { + x = coordinate_to_block(pos.x), + y = coordinate_to_block(pos.y), + z = coordinate_to_block(pos.z) + } +end + +function mcl_vars.pos_to_chunk(pos) + return { + x = coordinate_to_chunk(pos.x), + y = coordinate_to_chunk(pos.y), + z = coordinate_to_chunk(pos.z) + } +end + +local k_positive = math.ceil(mcl_vars.MAX_MAP_GENERATION_LIMIT / chunk_size_in_nodes) +local k_positive_z = k_positive * 2 +local k_positive_y = k_positive_z * k_positive_z + +function mcl_vars.get_chunk_number(pos) -- unsigned int + local c = mcl_vars.pos_to_chunk(pos) + return + (c.y + k_positive) * k_positive_y + + (c.z + k_positive) * k_positive_z + + c.x + k_positive +end + if not superflat and not singlenode then -- Normal mode --[[ Realm stacking (h is for height) @@ -91,7 +127,7 @@ else mcl_vars.mg_bedrock_is_rough = false end -mcl_vars.mg_overworld_max = 31000 +mcl_vars.mg_overworld_max = mcl_vars.mapgen_edge_max -- The Nether (around Y = -29000) mcl_vars.mg_nether_min = -29067 -- Carefully chosen to be at a mapchunk border diff --git a/mods/CORE/mcl_init/mod.conf b/mods/CORE/mcl_init/mod.conf index 5a3e4b6b2..a0e810a2f 100644 --- a/mods/CORE/mcl_init/mod.conf +++ b/mods/CORE/mcl_init/mod.conf @@ -1 +1,3 @@ name = mcl_init +author = Wuzzy +description = Initialization mod of MineClone 2. Defines some common shared variables and sets up initial default settings which have to be set at the beginning. diff --git a/mods/CORE/mcl_loot/description.txt b/mods/CORE/mcl_loot/description.txt deleted file mode 100644 index 30ba9a6f3..000000000 --- a/mods/CORE/mcl_loot/description.txt +++ /dev/null @@ -1 +0,0 @@ -API for filling a chest with random treasures. diff --git a/mods/CORE/mcl_loot/init.lua b/mods/CORE/mcl_loot/init.lua index e3db73be1..6db743740 100644 --- a/mods/CORE/mcl_loot/init.lua +++ b/mods/CORE/mcl_loot/init.lua @@ -111,14 +111,14 @@ end Returns a table of length `max_slot` and all natural numbers between 1 and `max_slot` in a random order. ]] -local function get_random_slots(max_slot) +local function get_random_slots(max_slot, pr) local slots = {} for s=1, max_slot do slots[s] = s end local slots_out = {} while #slots > 0 do - local r = math.random(1, #slots) + local r = pr and pr:next(1, #slots) or math.random(1, #slots) table.insert(slots_out, slots[r]) table.remove(slots, r) end @@ -135,9 +135,9 @@ Items will be added from start of the table to end. If the inventory already has occupied slots, or is too small, placement of some items might fail. ]] -function mcl_loot.fill_inventory(inv, listname, items) +function mcl_loot.fill_inventory(inv, listname, items, pr) local size = inv:get_size(listname) - local slots = get_random_slots(size) + local slots = get_random_slots(size, pr) local leftovers = {} -- 1st pass: Add items into random slots for i=1, math.min(#items, size) do diff --git a/mods/CORE/mcl_loot/mod.conf b/mods/CORE/mcl_loot/mod.conf index 8406dcc2f..82a41d0e5 100644 --- a/mods/CORE/mcl_loot/mod.conf +++ b/mods/CORE/mcl_loot/mod.conf @@ -1 +1,3 @@ name = mcl_loot +author = Wuzzy +description = API for filling a chest with random treasures. diff --git a/mods/CORE/mcl_particles/description.txt b/mods/CORE/mcl_particles/description.txt deleted file mode 100644 index 62d5cd61a..000000000 --- a/mods/CORE/mcl_particles/description.txt +++ /dev/null @@ -1 +0,0 @@ -Contains particle images of MineClone 2. No code. diff --git a/mods/CORE/mcl_particles/mod.conf b/mods/CORE/mcl_particles/mod.conf index f7be80395..b8252cbc5 100644 --- a/mods/CORE/mcl_particles/mod.conf +++ b/mods/CORE/mcl_particles/mod.conf @@ -1 +1,3 @@ name = mcl_particles +author = Wuzzy +description = Contains particle images of MineClone 2. No code. diff --git a/mods/CORE/mcl_sounds/description.txt b/mods/CORE/mcl_sounds/description.txt deleted file mode 100644 index 26c21e3b1..000000000 --- a/mods/CORE/mcl_sounds/description.txt +++ /dev/null @@ -1 +0,0 @@ -This mod contains the core sounds of MineClone 2 as well as helper function for mods to access them. diff --git a/mods/CORE/mcl_sounds/mod.conf b/mods/CORE/mcl_sounds/mod.conf index 3227e6126..33bcafd9f 100644 --- a/mods/CORE/mcl_sounds/mod.conf +++ b/mods/CORE/mcl_sounds/mod.conf @@ -1 +1,3 @@ name = mcl_sounds +author = Wuzzy +description = This mod contains the core sounds of MineClone 2 as well as helper function for mods to access them. diff --git a/mods/CORE/mcl_util/depends.txt b/mods/CORE/mcl_util/depends.txt deleted file mode 100644 index 3b355984e..000000000 --- a/mods/CORE/mcl_util/depends.txt +++ /dev/null @@ -1 +0,0 @@ -mcl_init diff --git a/mods/CORE/mcl_util/description.txt b/mods/CORE/mcl_util/description.txt deleted file mode 100644 index c778045c1..000000000 --- a/mods/CORE/mcl_util/description.txt +++ /dev/null @@ -1 +0,0 @@ -Helper functions for MineClone 2. diff --git a/mods/CORE/mcl_util/init.lua b/mods/CORE/mcl_util/init.lua index aedff5ef8..a43c3d5d0 100644 --- a/mods/CORE/mcl_util/init.lua +++ b/mods/CORE/mcl_util/init.lua @@ -406,52 +406,15 @@ function mcl_util.get_object_center(obj) return pos end -local get_node_emerge_queue = {} -local function ecb_get_far_node(blockpos, action, calls_remaining, param) - if calls_remaining <= 0 and param then - minetest.log("verbose","[mcl_util] ecb done for param = "..param.." node.name="..minetest.get_node(minetest.string_to_pos(param)).name) - get_node_emerge_queue[param] = nil +function mcl_util.get_color(colorstr) + local mc_color = mcl_colors[colorstr:upper()] + if mc_color then + colorstr = mc_color + elseif #colorstr ~= 7 or colorstr:sub(1, 1) ~= "#"then + return + end + local hex = tonumber(colorstr:sub(2, 7), 16) + if hex then + return colorstr, hex end end - -function mcl_util.get_far_node(pos, force) - local node = minetest.get_node(pos) - if node.name ~= "ignore" then - return node - end - - 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 - - local blockpos = vector.multiply(vector.floor(vector.divide(pos, mcl_vars.MAP_BLOCKSIZE)), mcl_vars.MAP_BLOCKSIZE) - local key = minetest.pos_to_string(blockpos) - - for i=1,2 do -- give engine 2 chances to emerge the data - if not get_node_emerge_queue[key] then - get_node_emerge_queue[key] = 1 - minetest.log("verbose","[mcl_util] emerge during get_far_node("..minetest.pos_to_string(pos).."), key="..key..", blockpos="..minetest.pos_to_string(blockpos)) - minetest.emerge_area(blockpos, vector.add(blockpos, mcl_vars.MAP_BLOCKSIZE-1), ecb_get_far_node, key) - end - - while not get_node_emerge_queue[key] do end - minetest.log("verbose","[mcl_util] emerge finished for node "..minetest.pos_to_string(pos)..", key="..key..", blockpos="..minetest.pos_to_string(blockpos)..", node.name="..mcl_util.get_far_node(pos).name) - - node = minetest.get_node(pos) - if node.name ~= "ignore" then - return node - end - - 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 - end - - node.name = "air" -- engine continuously returns "ignore" - probably it is a bug - minetest.swap_node(pos, node) -- engine continuously returns "ignore" - probably it is a bug - return node -- engine continuously returns "ignore" - probably it is a bug -end diff --git a/mods/CORE/mcl_util/mod.conf b/mods/CORE/mcl_util/mod.conf index e45f9124e..82f9137e4 100644 --- a/mods/CORE/mcl_util/mod.conf +++ b/mods/CORE/mcl_util/mod.conf @@ -1 +1,4 @@ name = mcl_util +author = Wuzzy +description = Helper functions for MineClone 2. +depends = mcl_init diff --git a/mods/CORE/mcl_worlds/depends.txt b/mods/CORE/mcl_worlds/depends.txt deleted file mode 100644 index 3b355984e..000000000 --- a/mods/CORE/mcl_worlds/depends.txt +++ /dev/null @@ -1 +0,0 @@ -mcl_init diff --git a/mods/CORE/mcl_worlds/description.txt b/mods/CORE/mcl_worlds/description.txt deleted file mode 100644 index 470cf7a84..000000000 --- a/mods/CORE/mcl_worlds/description.txt +++ /dev/null @@ -1 +0,0 @@ -Utility functions for worlds and the “dimensions”. diff --git a/mods/CORE/mcl_worlds/mod.conf b/mods/CORE/mcl_worlds/mod.conf new file mode 100644 index 000000000..4b979b4fe --- /dev/null +++ b/mods/CORE/mcl_worlds/mod.conf @@ -0,0 +1,5 @@ +name = mcl_worlds +author = Wuzzy +description = Utility functions for worlds and the “dimensions”. +depends = mcl_init + diff --git a/mods/CORE/walkover/init.lua b/mods/CORE/walkover/init.lua index 6bbd505d2..220157c8b 100644 --- a/mods/CORE/walkover/init.lua +++ b/mods/CORE/walkover/init.lua @@ -1,4 +1,10 @@ -- register extra flavours of a base nodedef + +local get_connected_players = minetest.get_connected_players +local get_node = minetest.get_node +local vector_add = vector.add +local ceil = math.ceil + walkover = {} walkover.registered_globals = {} @@ -6,25 +12,38 @@ function walkover.register_global(func) table.insert(walkover.registered_globals, func) end +local on_walk = {} +local registered_globals = {} + +minetest.register_on_mods_loaded(function() + for name,def in pairs(minetest.registered_nodes) do + if def.on_walk_over then + on_walk[name] = def.on_walk_over + end + end + for _,func in ipairs(walkover.registered_globals) do --cache registered globals + table.insert(registered_globals, func) + end +end) + local timer = 0 minetest.register_globalstep(function(dtime) timer = timer + dtime; if timer >= 0.3 then - for _,player in pairs(minetest.get_connected_players()) do + for _,player in pairs(get_connected_players()) do local pp = player:get_pos() - pp.y = math.ceil(pp.y) - local loc = vector.add(pp, {x=0,y=-1,z=0}) + pp.y = ceil(pp.y) + local loc = vector_add(pp, {x=0,y=-1,z=0}) if loc ~= nil then - local nodeiamon = minetest.get_node(loc) + local nodeiamon = get_node(loc) if nodeiamon ~= nil then - local def = minetest.registered_nodes[nodeiamon.name] - if def ~= nil and def.on_walk_over ~= nil then - def.on_walk_over(loc, nodeiamon, player) + if on_walk[nodeiamon.name] then + on_walk[nodeiamon.name](loc, nodeiamon, player) end - for _, func in ipairs(walkover.registered_globals) do - func(loc, nodeiamon, player) + for i = 1, #registered_globals do + registered_globals[i](loc, nodeiamon, player) end end end diff --git a/mods/CORE/walkover/mod.conf b/mods/CORE/walkover/mod.conf new file mode 100644 index 000000000..837d81365 --- /dev/null +++ b/mods/CORE/walkover/mod.conf @@ -0,0 +1,4 @@ +name = walkover +author = lordfingle +description = Some mode developers have shown an interest in having an `on_walk_over` event. This is useful for pressure-plates and the like. + diff --git a/mods/ENTITIES/drippingwater/depends.txt b/mods/ENTITIES/drippingwater/depends.txt deleted file mode 100644 index 315237e07..000000000 --- a/mods/ENTITIES/drippingwater/depends.txt +++ /dev/null @@ -1 +0,0 @@ -mcl_core diff --git a/mods/ENTITIES/drippingwater/mod.conf b/mods/ENTITIES/drippingwater/mod.conf new file mode 100644 index 000000000..1de118f4c --- /dev/null +++ b/mods/ENTITIES/drippingwater/mod.conf @@ -0,0 +1,4 @@ +name = drippingwater +author = kddekadenz +description = Drops are generated rarely under solid nodes +depends = mcl_core diff --git a/mods/ENTITIES/mcl_boats/README.txt b/mods/ENTITIES/mcl_boats/README.txt index 195a2241a..0d56aa0e1 100644 --- a/mods/ENTITIES/mcl_boats/README.txt +++ b/mods/ENTITIES/mcl_boats/README.txt @@ -20,4 +20,4 @@ Authors include: * Various Minetest / Minetest Game developers and contributors (2012-2016) * maikerumine (2017) * Wuzzy (2017) - +* Fleckenstein (2020-2021) diff --git a/mods/ENTITIES/mcl_boats/depends.txt b/mods/ENTITIES/mcl_boats/depends.txt deleted file mode 100644 index 7a3ef812e..000000000 --- a/mods/ENTITIES/mcl_boats/depends.txt +++ /dev/null @@ -1,3 +0,0 @@ -mcl_player -mcl_core? -doc_identifier? diff --git a/mods/ENTITIES/mcl_boats/description.txt b/mods/ENTITIES/mcl_boats/description.txt deleted file mode 100644 index 65a979e8a..000000000 --- a/mods/ENTITIES/mcl_boats/description.txt +++ /dev/null @@ -1 +0,0 @@ -Adds drivable boats. diff --git a/mods/ENTITIES/mcl_boats/init.lua b/mods/ENTITIES/mcl_boats/init.lua index 77708d8dc..9a9b65cc9 100644 --- a/mods/ENTITIES/mcl_boats/init.lua +++ b/mods/ENTITIES/mcl_boats/init.lua @@ -1,13 +1,24 @@ local S = minetest.get_translator("mcl_boats") --- --- Helper functions --- -local function is_water(pos) +local boat_visual_size = {x = 3, y = 3, z = 3} +local paddling_speed = 22 +local boat_y_offset = 0.35 +local boat_y_offset_ground = boat_y_offset + 0.6 +local boat_side_offset = 1.001 +local boat_max_hp = 4 + +local function is_group(pos, group) local nn = minetest.get_node(pos).name - return minetest.get_item_group(nn, "water") ~= 0 + return minetest.get_item_group(nn, group) ~= 0 end +local function is_water(pos) + return is_group(pos, "water") +end + +local function is_ice(pos) + return is_group(pos, "ice") +end local function get_sign(i) if i == 0 then @@ -17,26 +28,83 @@ local function get_sign(i) end end - local function get_velocity(v, yaw, y) local x = -math.sin(yaw) * v local z = math.cos(yaw) * v return {x = x, y = y, z = z} end - local function get_v(v) return math.sqrt(v.x ^ 2 + v.z ^ 2) end -local boat_visual_size = {x = 3, y = 3} --- Note: This mod assumes the default player visual_size is {x=1, y=1} -local driver_visual_size = { x = 1/boat_visual_size.x, y = 1/boat_visual_size.y } -local paddling_speed = 22 -local boat_y_offset = 0.35 -local boat_y_offset_ground = boat_y_offset + 0.6 -local boat_side_offset = 1.001 -local boat_max_hp = 4 +local function check_object(obj) + return obj and (obj:is_player() or obj:get_luaentity()) and obj +end + +local function get_visual_size(obj) + return obj:is_player() and {x = 1, y = 1, z = 1} or obj:get_luaentity()._old_visual_size or obj:get_properties().visual_size +end + +local function set_attach(boat) + boat._driver:set_attach(boat.object, "", + {x = 0, y = 0.42, z = -1}, {x = 0, y = 0, z = 0}) +end + +local function set_double_attach(boat) + boat._driver:set_attach(boat.object, "", + {x = 0, y = 0.42, z = 0.8}, {x = 0, y = 0, z = 0}) + boat._passenger:set_attach(boat.object, "", + {x = 0, y = 0.42, z = -2.2}, {x = 0, y = 0, z = 0}) +end + +local function attach_object(self, obj) + if self._driver then + if self._driver:is_player() then + self._passenger = obj + else + self._passenger = self._driver + self._driver = obj + end + set_double_attach(self) + else + self._driver = obj + set_attach(self) + end + + local visual_size = get_visual_size(obj) + local yaw = self.object:get_yaw() + obj:set_properties({visual_size = vector.divide(visual_size, boat_visual_size)}) + + if obj:is_player() then + local name = obj:get_player_name() + mcl_player.player_attached[name] = true + minetest.after(0.2, function(name) + local player = minetest.get_player_by_name(name) + if player then + mcl_player.player_set_animation(player, "sit" , 30) + end + end, name) + obj:set_look_horizontal(yaw) + mcl_tmp_message.message(obj, S("Sneak to dismount")) + else + obj:get_luaentity()._old_visual_size = visual_size + end +end + +local function detach_object(obj, change_pos) + obj:set_detach() + obj:set_properties({visual_size = get_visual_size(obj)}) + if obj:is_player() then + mcl_player.player_attached[obj:get_player_name()] = false + mcl_player.player_set_animation(obj, "stand" , 30) + else + obj:get_luaentity()._old_visual_size = nil + end + if change_pos then + obj:set_pos(vector.add(obj:get_pos(), vector.new(0, 0.2, 0))) + end +end -- -- Boat entity @@ -52,6 +120,7 @@ local boat = { textures = {"mcl_boats_texture_oak_boat.png"}, visual_size = boat_visual_size, hp_max = boat_max_hp, + damage_texture_modifier = "^[colorize:white:0", _driver = nil, -- Attached driver (player) or nil if none _passenger = nil, @@ -60,87 +129,31 @@ local boat = { _removed = false, -- If true, boat entity is considered removed (e.g. after punch) and should be ignored _itemstring = "mcl_boats:boat", -- Itemstring of the boat item (implies boat type) _animation = 0, -- 0: not animated; 1: paddling forwards; -1: paddling forwards + _regen_timer = 0, + _damage_anim = 0, } -local function detach_player(player, change_pos) - player:set_detach() - player:set_properties({visual_size = {x=1, y=1}}) - mcl_player.player_attached[player:get_player_name()] = false - mcl_player.player_set_animation(player, "stand" , 30) - if change_pos then - player:set_pos(vector.add(player:get_pos(), vector.new(0, 0.2, 0))) - end -end - -local function check_object(obj) - return obj and (obj:is_player() or obj:get_luaentity()) and obj -end - -local function set_attach(boat) - boat._driver:set_attach(boat.object, "", - {x = 0, y = 0.42, z = -1}, {x = 0, y = 0, z = 0}) -end - -local function set_double_attach(boat) - boat._driver:set_attach(boat.object, "", - {x = 0, y = 0.42, z = 0.8}, {x = 0, y = 0, z = 0}) - boat._passenger:set_attach(boat.object, "", - {x = 0, y = 0.42, z = -2.2}, {x = 0, y = 0, z = 0}) -end - -minetest.register_on_respawnplayer(detach_player) +minetest.register_on_respawnplayer(detach_object) function boat.on_rightclick(self, clicker) if self._passenger or not clicker or clicker:get_attach() then return end - local name = clicker:get_player_name() - --[[if attach and attach:get_luaentity() then - local luaentity = attach:get_luaentity() - if luaentity._driver then - luaentity._driver = nil - end - clicker:set_detach() - clicker:set_properties({visual_size = {x=1, y=1}}) - end--]] - if self._driver then - if self._driver:is_player() then - self._passenger = clicker - else - -- for later use: transport mobs in boats - self._passenger = self._driver - self._driver = clicker - end - set_double_attach(self) - else - self._driver = clicker - set_attach(self) - end - clicker:set_properties({ visual_size = driver_visual_size }) - mcl_player.player_attached[name] = true - minetest.after(0.2, function(name) - local player = minetest.get_player_by_name(name) - if player then - mcl_player.player_set_animation(player, "sit" , 30) - end - end, name) - clicker:set_look_horizontal(self.object:get_yaw()) - mcl_tmp_message.message(clicker, S("Sneak to dismount")) + attach_object(self, clicker) end function boat.on_activate(self, staticdata, dtime_s) - --self.object:set_armor_groups({immortal = 1}) + self.object:set_armor_groups({fleshy = 100}) local data = minetest.deserialize(staticdata) if type(data) == "table" then self._v = data.v self._last_v = self._v self._itemstring = data.itemstring - self.object:set_properties({textures = data.textures, damage_texture_modifier = ""}) + self.object:set_properties({textures = data.textures}) end end - function boat.get_staticdata(self) return minetest.serialize({ v = self._v, @@ -149,8 +162,9 @@ 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 @@ -160,43 +174,62 @@ function boat.on_death(self, killer) minetest.add_item(self.object:get_pos(), self._itemstring) end if self._driver then - detach_player(self._driver) + detach_object(self._driver) end if self._passenger then - detach_player(self._passenger) + detach_object(self._passenger) end self._driver = nil self._passenger = nil end +function boat.on_punch(self, puncher, time_from_last_punch, tool_capabilities, dir, damage) + if damage > 0 then + self._regen_timer = 0 + end +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 on_water = true - local in_water = false local v_factor = 1 local v_slowdown = 0.02 local p = self.object:get_pos() - if (not is_water({x=p.x, y=p.y-boat_y_offset, z=p.z})) then + local on_water = true + local on_ice = false + local in_water = is_water({x=p.x, y=p.y-boat_y_offset+1, z=p.z}) + local waterp = {x=p.x, y=p.y-boat_y_offset - 0.1, z=p.z} + if not is_water(waterp) then on_water = false - v_factor = 0.5 - v_slowdown = 0.04 - elseif (is_water({x=p.x, y=p.y-boat_y_offset+1, z=p.z})) then + if not in_water and is_ice(waterp) then + on_ice = true + else + v_slowdown = 0.04 + v_factor = 0.5 + end + elseif in_water then on_water = false in_water = true v_factor = 0.75 v_slowdown = 0.05 end - --local yaw = self.object:get_yaw() - --local hp = math.min(self.object:get_hp() + 2 * dtime, boat_max_hp) - --self.object:set_rotation(vector.new((boat_max_hp - hp) / boat_max_hp, 0, 0)) - self.object:set_hp(self.object:get_hp() + 2 * dtime) - --self.object:set_yaw(yaw) + local hp = self.object:get_hp() + local regen_timer = self._regen_timer + dtime + if hp >= boat_max_hp then + regen_timer = 0 + elseif regen_timer >= 0.5 then + hp = hp + 1 + self.object:set_hp(hp) + regen_timer = 0 + end + 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_node_group(minetest.get_node(pos).name, "dig_by_boat") > 0 then + if collision.type == "node" and minetest.get_item_group(minetest.get_node(pos).name, "dig_by_boat") > 0 then minetest.dig_node(pos) end end @@ -226,7 +259,7 @@ function boat.on_step(self, dtime, moveresult) end local ctrl = self._driver:get_player_control() if ctrl and ctrl.sneak then - detach_player(self._driver, true) + detach_object(self._driver, true) self._driver = nil return end @@ -275,11 +308,19 @@ function boat.on_step(self, dtime, moveresult) self.object:set_animation({x=0, y=40}, 0, 0, true) self._animation = 0 end + + 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) + break + end + end end local s = get_sign(self._v) - if not on_water and not in_water and math.abs(self._v) > 1.0 then - v_slowdown = math.min(math.abs(self._v) - 1.0, v_slowdown * 5) - elseif in_water and math.abs(self._v) > 1.5 then + if not on_ice and not on_water and not in_water and math.abs(self._v) > 2.0 then + v_slowdown = math.min(math.abs(self._v) - 2.0, v_slowdown * 5) + elseif not on_ice and in_water and math.abs(self._v) > 1.5 then v_slowdown = math.min(math.abs(self._v) - 1.5, v_slowdown * 5) end self._v = self._v - v_slowdown * s @@ -290,7 +331,7 @@ function boat.on_step(self, dtime, moveresult) p.y = p.y - boat_y_offset local new_velo local new_acce = {x = 0, y = 0, z = 0} - if not is_water(p) then + if not is_water(p) and not on_ice then -- Not on water or inside water: Free fall local nodedef = minetest.registered_nodes[minetest.get_node(p).name] new_acce = {x = 0, y = -9.8, z = 0} @@ -320,12 +361,17 @@ function boat.on_step(self, dtime, moveresult) end -- Terminal velocity: 8 m/s per axis of travel + local terminal_velocity = on_ice and 57.1 or 8.0 for _,axis in pairs({"z","y","x"}) do - if math.abs(new_velo[axis]) > 8 then - new_velo[axis] = 8 * get_sign(new_velo[axis]) + if math.abs(new_velo[axis]) > terminal_velocity then + new_velo[axis] = terminal_velocity * get_sign(new_velo[axis]) end end + local yaw = self.object:get_yaw() + local anim = (boat_max_hp - hp - regen_timer * 2) / boat_max_hp * math.pi / 4 + + self.object:set_rotation(vector.new(anim, yaw, anim)) self.object:set_velocity(new_velo) self.object:set_acceleration(new_acce) end diff --git a/mods/ENTITIES/mcl_boats/mod.conf b/mods/ENTITIES/mcl_boats/mod.conf index f14456c5f..251459186 100644 --- a/mods/ENTITIES/mcl_boats/mod.conf +++ b/mods/ENTITIES/mcl_boats/mod.conf @@ -1 +1,7 @@ name = mcl_boats +author = PilzAdam +description = Adds drivable boats. +depends = mcl_player +optional_depends = mcl_core, doc_identifier + + diff --git a/mods/ENTITIES/mcl_burning/engine.lua b/mods/ENTITIES/mcl_burning/api.lua similarity index 92% rename from mods/ENTITIES/mcl_burning/engine.lua rename to mods/ENTITIES/mcl_burning/api.lua index 5be11a254..723b29a8b 100644 --- a/mods/ENTITIES/mcl_burning/engine.lua +++ b/mods/ENTITIES/mcl_burning/api.lua @@ -34,7 +34,7 @@ function mcl_burning.is_burning(obj) end function mcl_burning.is_affected_by_rain(obj) - return mcl_weather.get_weather() == "rain" and mcl_weather.is_outdoor(obj:get_pos()) + return mcl_weather and mcl_weather.get_weather() == "rain" and mcl_weather.is_outdoor(obj:get_pos()) end function mcl_burning.get_collisionbox(obj, smaller) @@ -107,11 +107,7 @@ function mcl_burning.damage(obj) end if do_damage then - local damage = mcl_burning.get(obj, "float", "damage") - if damage == 0 then - damage = 1 - end - local new_hp = hp - damage + local new_hp = hp - 1 if health then luaentity.health = new_hp else @@ -120,7 +116,7 @@ function mcl_burning.damage(obj) end end -function mcl_burning.set_on_fire(obj, burn_time, damage, interval, reason) +function mcl_burning.set_on_fire(obj, burn_time, reason) local luaentity = obj:get_luaentity() if luaentity and luaentity.fire_resistant then return @@ -173,8 +169,6 @@ function mcl_burning.set_on_fire(obj, burn_time, damage, interval, reason) end end mcl_burning.set(obj, "float", "burn_time", burn_time) - mcl_burning.set(obj, "float", "damage", damage) - mcl_burning.set(obj, "float", "interval", interval) 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) @@ -208,8 +202,6 @@ function mcl_burning.extinguish(obj) obj:hud_remove(hud_id) end - mcl_burning.set(obj, "float", "damage") - mcl_burning.set(obj, "float", "interval") mcl_burning.set(obj, "string", "reason") mcl_burning.set(obj, "float", "burn_time") mcl_burning.set(obj, "float", "damage_timer") @@ -240,12 +232,7 @@ function mcl_burning.tick(obj, dtime) local damage_timer = mcl_burning.get(obj, "float", "damage_timer") + dtime - local interval = mcl_burning.get(obj, "float", "interval") - if interval == 0 then - interval = 1 - end - - if damage_timer >= interval then + if damage_timer >= 1 then damage_timer = 0 mcl_burning.damage(obj) end @@ -280,7 +267,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 1b341273e..672036c78 100644 --- a/mods/ENTITIES/mcl_burning/init.lua +++ b/mods/ENTITIES/mcl_burning/init.lua @@ -5,7 +5,7 @@ mcl_burning = { animation_frames = tonumber(minetest.settings:get("fire_animation_frames")) or 8 } -dofile(modpath .. "/engine.lua") +dofile(modpath .. "/api.lua") minetest.register_entity("mcl_burning:fire", { initial_properties = { @@ -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) @@ -33,4 +33,4 @@ end) minetest.register_on_leaveplayer(function(player) mcl_burning.set(player, "int", "hud_id") -end) \ No newline at end of file +end) diff --git a/mods/ENTITIES/mcl_falling_nodes/description.txt b/mods/ENTITIES/mcl_falling_nodes/description.txt deleted file mode 100644 index 8b436bf28..000000000 --- a/mods/ENTITIES/mcl_falling_nodes/description.txt +++ /dev/null @@ -1 +0,0 @@ -Falling node entities, Minecraft-style diff --git a/mods/ENTITIES/mcl_falling_nodes/mod.conf b/mods/ENTITIES/mcl_falling_nodes/mod.conf index 032b75023..068987194 100644 --- a/mods/ENTITIES/mcl_falling_nodes/mod.conf +++ b/mods/ENTITIES/mcl_falling_nodes/mod.conf @@ -1 +1,3 @@ name = mcl_falling_nodes +author = Wuzzy +description = Falling node entities, Minecraft-style diff --git a/mods/ENTITIES/mcl_item_entity/depends.txt b/mods/ENTITIES/mcl_item_entity/depends.txt deleted file mode 100644 index f80274858..000000000 --- a/mods/ENTITIES/mcl_item_entity/depends.txt +++ /dev/null @@ -1,2 +0,0 @@ -flowlib -mcl_enchanting diff --git a/mods/ENTITIES/mcl_item_entity/description.txt b/mods/ENTITIES/mcl_item_entity/description.txt deleted file mode 100644 index dba26fb6c..000000000 --- a/mods/ENTITIES/mcl_item_entity/description.txt +++ /dev/null @@ -1 +0,0 @@ -Dropped items will be attracted to the player like a magnet. diff --git a/mods/ENTITIES/mcl_item_entity/init.lua b/mods/ENTITIES/mcl_item_entity/init.lua index e5863abbc..7546bd01c 100644 --- a/mods/ENTITIES/mcl_item_entity/init.lua +++ b/mods/ENTITIES/mcl_item_entity/init.lua @@ -54,14 +54,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 @@ -785,7 +785,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_item_entity/mod.conf b/mods/ENTITIES/mcl_item_entity/mod.conf index 9f35f5ed9..acd9f00f3 100644 --- a/mods/ENTITIES/mcl_item_entity/mod.conf +++ b/mods/ENTITIES/mcl_item_entity/mod.conf @@ -1 +1,4 @@ name = mcl_item_entity +author = PilzAdam +description = Dropped items will be attracted to the player like a magnet. +depends = flowlib, mcl_enchanting diff --git a/mods/ENTITIES/mcl_minecarts/depends.txt b/mods/ENTITIES/mcl_minecarts/depends.txt deleted file mode 100644 index cdf7feb54..000000000 --- a/mods/ENTITIES/mcl_minecarts/depends.txt +++ /dev/null @@ -1,12 +0,0 @@ -mcl_explosions -mcl_core -mcl_sounds -mcl_player -mcl_achievements -mcl_chests -mcl_furnaces -mesecons_commandblock -mcl_hoppers -mcl_tnt -mesecons -doc_identifier? diff --git a/mods/ENTITIES/mcl_minecarts/description.txt b/mods/ENTITIES/mcl_minecarts/description.txt deleted file mode 100644 index 27f6c313d..000000000 --- a/mods/ENTITIES/mcl_minecarts/description.txt +++ /dev/null @@ -1 +0,0 @@ -Minecarts are vehicles to move players quickly on rails. diff --git a/mods/ENTITIES/mcl_minecarts/init.lua b/mods/ENTITIES/mcl_minecarts/init.lua index 7bea3bd46..9c61fa5ed 100644 --- a/mods/ENTITIES/mcl_minecarts/init.lua +++ b/mods/ENTITIES/mcl_minecarts/init.lua @@ -175,6 +175,19 @@ local function register_entity(entity_id, mesh, textures, drop, on_rightclick, o cart.on_activate_by_rail = on_activate_by_rail function cart:on_step(dtime) + local ctrl, player = nil, nil + if self._driver then + player = minetest.get_player_by_name(self._driver) + if player then + ctrl = player:get_player_control() + -- player detach + if ctrl.sneak then + detach_driver(self) + return + end + end + end + local vel = self.object:get_velocity() local update = {} if self._last_float_check == nil then @@ -190,18 +203,14 @@ local function register_entity(entity_id, mesh, textures, drop, on_rightclick, o node = minetest.get_node(rou_pos) local g = minetest.get_item_group(node.name, "connect_to_raillike") if g ~= self._railtype and self._railtype ~= nil then - local player -- Detach driver - if self._driver then + if player then if self._old_pos then self.object:set_pos(self._old_pos) end mcl_player.player_attached[self._driver] = nil - player = minetest.get_player_by_name(self._driver) - if player then - player:set_detach() - player:set_eye_offset({x=0, y=0, z=0},{x=0, y=0, z=0}) - end + player:set_detach() + player:set_eye_offset({x=0, y=0, z=0},{x=0, y=0, z=0}) end -- Explode if already ignited @@ -337,14 +346,6 @@ local function register_entity(entity_id, mesh, textures, drop, on_rightclick, o end end - local ctrl, player = nil, nil - if self._driver then - player = minetest.get_player_by_name(self._driver) - if player then - ctrl = player:get_player_control() - end - end - -- Stop cart if velocity vector flips if self._old_vel and self._old_vel.y == 0 and (self._old_vel.x * vel.x < 0 or self._old_vel.z * vel.z < 0) then @@ -643,6 +644,7 @@ register_minecart( if player then mcl_player.player_set_animation(player, "sit" , 30) player:set_eye_offset({x=0, y=-5.5, z=0},{x=0, y=-4, z=0}) + mcl_tmp_message.message(clicker, S("Sneak to dismount")) end end, name) end @@ -660,6 +662,8 @@ 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( @@ -715,6 +719,8 @@ 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", @@ -736,6 +742,8 @@ register_minecart( nil, nil, false ) +mcl_wip.register_wip_item("mcl_minecarts:command_block_minecart") + -- Minecart with Hopper register_minecart( "mcl_minecarts:hopper_minecart", @@ -754,6 +762,8 @@ register_minecart( nil, nil, false ) +mcl_wip.register_wip_item("mcl_minecarts:hopper_minecart") + -- Minecart with TNT register_minecart( "mcl_minecarts:tnt_minecart", diff --git a/mods/ENTITIES/mcl_minecarts/locale/mcl_minecarts.ru.tr b/mods/ENTITIES/mcl_minecarts/locale/mcl_minecarts.ru.tr index e8f914128..6189bac84 100644 --- a/mods/ENTITIES/mcl_minecarts/locale/mcl_minecarts.ru.tr +++ b/mods/ENTITIES/mcl_minecarts/locale/mcl_minecarts.ru.tr @@ -33,3 +33,4 @@ Activates minecarts when powered=Активирует особые вагоне Emits redstone power when a minecart is detected=Испускает энергию редстоуна при обнаружении вагонетки Vehicle for fast travel on rails=Быстрый железнодорожный транспорт Can be ignited by tools or powered activator rail=Можно воспламенить с помощью инструмента или подключенного рельсового активатора +Sneak to dismount=Нажмите [Красться] для высадки diff --git a/mods/ENTITIES/mcl_minecarts/locale/template.txt b/mods/ENTITIES/mcl_minecarts/locale/template.txt index 254189542..dff98587c 100644 --- a/mods/ENTITIES/mcl_minecarts/locale/template.txt +++ b/mods/ENTITIES/mcl_minecarts/locale/template.txt @@ -33,3 +33,4 @@ Activates minecarts when powered= Emits redstone power when a minecart is detected= Vehicle for fast travel on rails= Can be ignited by tools or powered activator rail= +Sneak to dismount= diff --git a/mods/ENTITIES/mcl_minecarts/mod.conf b/mods/ENTITIES/mcl_minecarts/mod.conf index 5661f8b9c..138fd18e6 100644 --- a/mods/ENTITIES/mcl_minecarts/mod.conf +++ b/mods/ENTITIES/mcl_minecarts/mod.conf @@ -1 +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 + diff --git a/mods/ENTITIES/mcl_mobs/api.lua b/mods/ENTITIES/mcl_mobs/api.lua index 460988972..3b929a119 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 @@ -396,7 +396,7 @@ local is_node_dangerous = function(self, nodename) return true end end - if minetest.registered_nodes[nn].damage_per_second and minetest.registered_nodes[nn].damage_per_second > 0 then + if minetest.registered_nodes[nn] and minetest.registered_nodes[nn].damage_per_second and minetest.registered_nodes[nn].damage_per_second > 0 then return true end return false @@ -751,10 +751,10 @@ local check_for_death = function(self, cause, cmi_cause) -- play damage sound if health was reduced and make mob flash red. if damaged then - add_texture_mod(self, "^[colorize:#FF000040") + add_texture_mod(self, "^[colorize:red:130") minetest.after(.2, function(self) if self and self.object then - remove_texture_mod(self, "^[colorize:#FF000040") + remove_texture_mod(self, "^[colorize:red:130") end end, self) mob_sound(self, "damage") @@ -1047,8 +1047,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,9 +1062,9 @@ 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, self.sunlight_damage or 1) + mcl_burning.set_on_fire(self.object, 10) else deal_light_damage(self, pos, self.sunlight_damage) return true @@ -2975,8 +2980,7 @@ local mob_punch = function(self, hitter, tflp, tool_capabilities, dir) if weapon then local fire_aspect_level = mcl_enchanting.get_enchantment(weapon, "fire_aspect") if fire_aspect_level > 0 then - local damage = fire_aspect_level * 4 - 1 - mcl_burning.set_on_fire(self.object, 4, 1, 4 / damage) + mcl_burning.set_on_fire(self.object, fire_aspect_level * 4) end end @@ -3712,6 +3716,7 @@ end minetest.register_entity(name, { + use_texture_alpha = def.use_texture_alpha, stepheight = def.stepheight or 0.6, name = name, type = def.type, @@ -4576,9 +4581,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_mobs/description.txt b/mods/ENTITIES/mcl_mobs/description.txt deleted file mode 100644 index a426a1006..000000000 --- a/mods/ENTITIES/mcl_mobs/description.txt +++ /dev/null @@ -1 +0,0 @@ -Adds a mob API for mods to add animals or monsters, etc. diff --git a/mods/ENTITIES/mcl_mobs/mod.conf b/mods/ENTITIES/mcl_mobs/mod.conf index c3d971374..0d622f6a9 100644 --- a/mods/ENTITIES/mcl_mobs/mod.conf +++ b/mods/ENTITIES/mcl_mobs/mod.conf @@ -1,3 +1,5 @@ name = mcl_mobs +author = PilzAdam +description = Adds a mob API for mods to add animals or monsters, etc. depends = mcl_particles optional_depends = mcl_weather, mcl_explosions, mcl_hunger, mcl_worlds, invisibility, lucky_block, cmi, doc_identifier, mcl_armor, mcl_portals, mcl_experience diff --git a/mods/ENTITIES/mcl_mobs/mount.lua b/mods/ENTITIES/mcl_mobs/mount.lua index 8c4a6aa55..d8ce484c3 100644 --- a/mods/ENTITIES/mcl_mobs/mount.lua +++ b/mods/ENTITIES/mcl_mobs/mount.lua @@ -154,7 +154,7 @@ function mobs.attach(entity, player) minetest.after(0.2, function(name) local player = minetest.get_player_by_name(name) if player then - mcl_player.player_set_animation(player, "sit" , 30) + mcl_player.player_set_animation(player, "sit_mount" , 30) end end, player:get_player_name()) diff --git a/mods/ENTITIES/mcl_paintings/init.lua b/mods/ENTITIES/mcl_paintings/init.lua index 6a3ccab4d..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 @@ -293,6 +301,8 @@ minetest.register_craftitem("mcl_paintings:painting", { end, }) +mcl_wip.register_wip_item("mcl_paintings:painting") + minetest.register_craft({ output = "mcl_paintings:painting", recipe = { diff --git a/mods/ENTITIES/mcl_paintings/mod.conf b/mods/ENTITIES/mcl_paintings/mod.conf index ea1d61c3d..2c6955360 100644 --- a/mods/ENTITIES/mcl_paintings/mod.conf +++ b/mods/ENTITIES/mcl_paintings/mod.conf @@ -1 +1,5 @@ name = mcl_paintings +author = Wuzzy +description = The paintings mod for MCL2 +depends = mcl_wip + 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/blaze.lua b/mods/ENTITIES/mobs_mc/blaze.lua index 2b9000de7..20fa86a1f 100644 --- a/mods/ENTITIES/mobs_mc/blaze.lua +++ b/mods/ENTITIES/mobs_mc/blaze.lua @@ -91,7 +91,7 @@ mobs:register_arrow("mobs_mc:blaze_fireball", { if rawget(_G, "armor") and armor.last_damage_types then armor.last_damage_types[player:get_player_name()] = "fireball" end - mcl_burning.set_on_fire(player, 5, 1, 5 / 4, "blaze") + mcl_burning.set_on_fire(player, 5, "blaze") player:punch(self.object, 1.0, { full_punch_interval = 1.0, damage_groups = {fleshy = 5}, @@ -99,7 +99,7 @@ mobs:register_arrow("mobs_mc:blaze_fireball", { end, hit_mob = function(self, mob) - mcl_burning.set_on_fire(mob, 5, 1, 5 / 4) + mcl_burning.set_on_fire(mob, 5) mob:punch(self.object, 1.0, { full_punch_interval = 1.0, damage_groups = {fleshy = 5}, diff --git a/mods/ENTITIES/mobs_mc/depends.txt b/mods/ENTITIES/mobs_mc/depends.txt deleted file mode 100644 index 4a2756661..000000000 --- a/mods/ENTITIES/mobs_mc/depends.txt +++ /dev/null @@ -1,12 +0,0 @@ -mcl_init -mcl_particles -default? -mcl_mobs -mcl_tnt? -mcl_bows? -mcl_throwing? -mcl_fishing? -bones? -mesecons_materials? -mobs_mc_gameconfig? -doc_items? diff --git a/mods/ENTITIES/mobs_mc/description.txt b/mods/ENTITIES/mobs_mc/description.txt deleted file mode 100644 index c57195fea..000000000 --- a/mods/ENTITIES/mobs_mc/description.txt +++ /dev/null @@ -1 +0,0 @@ -Adds Minecraft-like monsters and animals. diff --git a/mods/ENTITIES/mobs_mc/ender_dragon.lua b/mods/ENTITIES/mobs_mc/ender_dragon.lua index c579213a0..e62b0d16b 100644 --- a/mods/ENTITIES/mobs_mc/ender_dragon.lua +++ b/mods/ENTITIES/mobs_mc/ender_dragon.lua @@ -25,6 +25,7 @@ mobs:register_mob("mobs_mc:enderdragon", { view_range = 35, walk_velocity = 6, run_velocity = 6, + can_despawn = false, sounds = { -- TODO: more sounds shoot_attack = "mobs_mc_ender_dragon_shoot", @@ -104,3 +105,5 @@ mobs:register_arrow("mobs_mc:dragon_fireball", { }) mobs:register_egg("mobs_mc:enderdragon", S("Ender Dragon"), "mobs_mc_spawn_icon_dragon.png", 0, true) + +mcl_wip.register_wip_item("mobs_mc:enderdragon") diff --git a/mods/ENTITIES/mobs_mc/enderman.lua b/mods/ENTITIES/mobs_mc/enderman.lua index b2971ae45..efc789344 100644 --- a/mods/ENTITIES/mobs_mc/enderman.lua +++ b/mods/ENTITIES/mobs_mc/enderman.lua @@ -242,36 +242,39 @@ mobs:register_mob("mobs_mc:enderman", { }) end -- RAIN DAMAGE / EVASIVE WARP BEHAVIOUR HERE. - if mcl_weather.state == "rain" or mcl_weather.state == "lightning" then - local damage = true - local enderpos = self.object:get_pos() - enderpos.y = enderpos.y+2.89 - local height = {x=enderpos.x, y=enderpos.y+512,z=enderpos.z} - local ray = minetest.raycast(enderpos, height, true) - -- Check for blocks above enderman. - for pointed_thing in ray do - if pointed_thing.type == "node" then - local nn = minetest.get_node(minetest.get_pointed_thing_position(pointed_thing)).name - local def = minetest.registered_nodes[nn] - if (not def) or def.walkable then - -- There's a node in the way. Delete arrow without damage - damage = false - break + local dim = mcl_worlds.pos_to_dimension(enderpos) + if dim == "overworld" then + if mcl_weather.state == "rain" or mcl_weather.state == "lightning" then + local damage = true + local enderpos = self.object:get_pos() + enderpos.y = enderpos.y+2.89 + local height = {x=enderpos.x, y=enderpos.y+512,z=enderpos.z} + local ray = minetest.raycast(enderpos, height, true) + -- Check for blocks above enderman. + for pointed_thing in ray do + if pointed_thing.type == "node" then + local nn = minetest.get_node(minetest.get_pointed_thing_position(pointed_thing)).name + local def = minetest.registered_nodes[nn] + if (not def) or def.walkable then + -- There's a node in the way. Delete arrow without damage + damage = false + break + end end end - end - if damage == true then - self.state = "" - --rain hurts enderman - self.object:punch(self.object, 1.0, { - full_punch_interval=1.0, - damage_groups={fleshy=self._damage}, - }, nil) - --randomly teleport hopefully under something. - self:teleport(nil) + if damage == true then + self.state = "" + --rain hurts enderman + self.object:punch(self.object, 1.0, { + full_punch_interval=1.0, + damage_groups={fleshy=self._damage}, + }, nil) + --randomly teleport hopefully under something. + self:teleport(nil) + end end - end + else return end -- AGRESSIVELY WARP/CHASE PLAYER BEHAVIOUR HERE. if self.state == "attack" then --if (minetest.get_timeofday() * 24000) > 5001 and (minetest.get_timeofday() * 24000) < 19000 then diff --git a/mods/ENTITIES/mobs_mc/horse.lua b/mods/ENTITIES/mobs_mc/horse.lua index b9d82660c..a59ed80d4 100644 --- a/mods/ENTITIES/mobs_mc/horse.lua +++ b/mods/ENTITIES/mobs_mc/horse.lua @@ -450,7 +450,7 @@ mobs:spawn_specific("mobs_mc:donkey", mobs_mc.spawn.grassland_savanna, {"air"}, -- spawn eggs mobs:register_egg("mobs_mc:horse", S("Horse"), "mobs_mc_spawn_icon_horse.png", 0) -mobs:register_egg("mobs_mc:skeleton_horse", S("Skeleton Horse"), "mobs_mc_spawn_icon_horse_skeleton.png", 0) -mobs:register_egg("mobs_mc:zombie_horse", S("Zombie Horse"), "mobs_mc_spawn_icon_horse_zombie.png", 0) +--mobs:register_egg("mobs_mc:skeleton_horse", S("Skeleton Horse"), "mobs_mc_spawn_icon_horse_skeleton.png", 0) +--mobs:register_egg("mobs_mc:zombie_horse", S("Zombie Horse"), "mobs_mc_spawn_icon_horse_zombie.png", 0) mobs:register_egg("mobs_mc:donkey", S("Donkey"), "mobs_mc_spawn_icon_donkey.png", 0) mobs:register_egg("mobs_mc:mule", S("Mule"), "mobs_mc_spawn_icon_mule.png", 0) diff --git a/mods/ENTITIES/mobs_mc/mod.conf b/mods/ENTITIES/mobs_mc/mod.conf index cd4f98c75..98f48b388 100644 --- a/mods/ENTITIES/mobs_mc/mod.conf +++ b/mods/ENTITIES/mobs_mc/mod.conf @@ -1 +1,6 @@ name = mobs_mc +author = maikerumine +description = Adds Minecraft-like monsters and animals. +depends = mcl_init, mcl_particles, mcl_mobs, mcl_wip +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/slime+magma_cube.lua b/mods/ENTITIES/mobs_mc/slime+magma_cube.lua index 98c29870c..54269b46e 100644 --- a/mods/ENTITIES/mobs_mc/slime+magma_cube.lua +++ b/mods/ENTITIES/mobs_mc/slime+magma_cube.lua @@ -110,6 +110,7 @@ local slime_big = { 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/textures/mobs_mc_horse_skeleton.png b/mods/ENTITIES/mobs_mc/textures/mobs_mc_horse_skeleton.png deleted file mode 100644 index 7fa9ce1de..000000000 Binary files a/mods/ENTITIES/mobs_mc/textures/mobs_mc_horse_skeleton.png and /dev/null differ diff --git a/mods/ENTITIES/mobs_mc/textures/mobs_mc_horse_zombie.png b/mods/ENTITIES/mobs_mc/textures/mobs_mc_horse_zombie.png deleted file mode 100644 index 846769e23..000000000 Binary files a/mods/ENTITIES/mobs_mc/textures/mobs_mc_horse_zombie.png and /dev/null differ diff --git a/mods/ENTITIES/mobs_mc/textures/mobs_mc_slime.png b/mods/ENTITIES/mobs_mc/textures/mobs_mc_slime.png index 82ed08719..278fafb9d 100644 Binary files a/mods/ENTITIES/mobs_mc/textures/mobs_mc_slime.png and b/mods/ENTITIES/mobs_mc/textures/mobs_mc_slime.png differ diff --git a/mods/ENTITIES/mobs_mc/villager.lua b/mods/ENTITIES/mobs_mc/villager.lua index 7e6921f90..0021a1adb 100644 --- a/mods/ENTITIES/mobs_mc/villager.lua +++ b/mods/ENTITIES/mobs_mc/villager.lua @@ -412,6 +412,7 @@ local init_trades = function(self, inv) offered_stack = mcl_enchanting.get_uniform_randomly_enchanted_book({"soul_speed"}) else mcl_enchanting.enchant_randomly(offered_stack, math.random(5, 19), false, false, true) + mcl_enchanting.unload_enchantments(offered_stack) end end @@ -457,7 +458,9 @@ local set_trade = function(trader, player, inv, concrete_tradenum) player_tradenum[name] = concrete_tradenum local trade = trades[concrete_tradenum] inv:set_stack("wanted", 1, ItemStack(trade.wanted[1])) - inv:set_stack("offered", 1, ItemStack(trade.offered)) + local offered = ItemStack(trade.offered) + mcl_enchanting.load_enchantments(offered) + inv:set_stack("offered", 1, offered) if trade.wanted[2] then local wanted2 = ItemStack(trade.wanted[2]) inv:set_stack("wanted", 2, wanted2) diff --git a/mods/ENTITIES/mobs_mc/witch.lua b/mods/ENTITIES/mobs_mc/witch.lua index e95357564..05f5098e5 100644 --- a/mods/ENTITIES/mobs_mc/witch.lua +++ b/mods/ENTITIES/mobs_mc/witch.lua @@ -104,3 +104,5 @@ mobs:register_arrow("mobs_mc:potion_arrow", { -- spawn eggs mobs:register_egg("mobs_mc:witch", S("Witch"), "mobs_mc_spawn_icon_witch.png", 0, true) + +mcl_wip.register_wip_item("mobs_mc:witch") diff --git a/mods/ENTITIES/mobs_mc/wither.lua b/mods/ENTITIES/mobs_mc/wither.lua index 28c1a2138..3fbf65955 100644 --- a/mods/ENTITIES/mobs_mc/wither.lua +++ b/mods/ENTITIES/mobs_mc/wither.lua @@ -43,6 +43,7 @@ mobs:register_mob("mobs_mc:wither", { dogshoot_switch = 1, dogshoot_count_max =1, attack_animals = true, + can_despawn = false, drops = { {name = mobs_mc.items.nether_star, chance = 1, @@ -105,3 +106,5 @@ mobs:register_arrow("mobs_mc:wither_skull", { --Spawn egg mobs:register_egg("mobs_mc:wither", S("Wither"), "mobs_mc_spawn_icon_wither.png", 0, true) + +mcl_wip.register_wip_item("mobs_mc:wither") \ No newline at end of file diff --git a/mods/ENTITIES/mobs_mc_gameconfig/depends.txt b/mods/ENTITIES/mobs_mc_gameconfig/depends.txt deleted file mode 100644 index 2f89674f3..000000000 --- a/mods/ENTITIES/mobs_mc_gameconfig/depends.txt +++ /dev/null @@ -1,2 +0,0 @@ -mcl_init -mcl_core diff --git a/mods/ENTITIES/mobs_mc_gameconfig/mod.conf b/mods/ENTITIES/mobs_mc_gameconfig/mod.conf new file mode 100644 index 000000000..a9d0d3d7b --- /dev/null +++ b/mods/ENTITIES/mobs_mc_gameconfig/mod.conf @@ -0,0 +1,4 @@ +name = mobs_mc_gameconfig +author = Wuzzy +description = mobs_mc game configuration for MCL2 +depends = mcl_init, mcl_core diff --git a/mods/ENVIRONMENT/lightning/depends.txt b/mods/ENVIRONMENT/lightning/depends.txt deleted file mode 100644 index 356c2f185..000000000 --- a/mods/ENVIRONMENT/lightning/depends.txt +++ /dev/null @@ -1,2 +0,0 @@ -mcl_fire -mcl_death_messages? diff --git a/mods/ENVIRONMENT/lightning/description.txt b/mods/ENVIRONMENT/lightning/description.txt deleted file mode 100644 index 98fdb3626..000000000 --- a/mods/ENVIRONMENT/lightning/description.txt +++ /dev/null @@ -1 +0,0 @@ -A mod that adds thunder and lightning effects. diff --git a/mods/ENVIRONMENT/lightning/init.lua b/mods/ENVIRONMENT/lightning/init.lua index 5c9fe7e61..345f733d5 100644 --- a/mods/ENVIRONMENT/lightning/init.lua +++ b/mods/ENVIRONMENT/lightning/init.lua @@ -11,6 +11,18 @@ of the license, or (at your option) any later version. local S = minetest.get_translator("lightning") +local has_mcl_death_msg = minetest.get_modpath("mcl_death_messages") +local get_connected_players = minetest.get_connected_players +local line_of_sight = minetest.line_of_sight +local get_node = minetest.get_node +local set_node = minetest.set_node +local sound_play = minetest.sound_play +local add_particlespawner = minetest.add_particlespawner +local after = minetest.after +local add_entity = minetest.add_entity +local get_objects_inside_radius = minetest.get_objects_inside_radius +local get_item_group = minetest.get_item_group + lightning = {} lightning.interval_low = 17 @@ -45,7 +57,7 @@ minetest.register_globalstep(revertsky) -- select a random strike point, midpoint local function choose_pos(pos) if not pos then - local playerlist = minetest.get_connected_players() + local playerlist = get_connected_players() local playercount = table.getn(playerlist) -- nobody on @@ -67,14 +79,14 @@ local function choose_pos(pos) pos.z = math.floor(pos.z - (lightning.range_h / 2) + rng:next(1, lightning.range_h)) end - local b, pos2 = minetest.line_of_sight(pos, {x = pos.x, y = pos.y - lightning.range_v, z = pos.z}, 1) + local b, pos2 = line_of_sight(pos, {x = pos.x, y = pos.y - lightning.range_v, z = pos.z}, 1) -- nothing but air found if b then return nil, nil end - local n = minetest.get_node({x = pos2.x, y = pos2.y - 1/2, z = pos2.z}) + local n = get_node({x = pos2.x, y = pos2.y - 1/2, z = pos2.z}) if n.name == "air" or n.name == "ignore" then return nil, nil end @@ -87,7 +99,7 @@ end -- * returns: bool - success if a strike happened lightning.strike = function(pos) if lightning.auto then - minetest.after(rng:next(lightning.interval_low, lightning.interval_high), lightning.strike) + after(rng:next(lightning.interval_low, lightning.interval_high), lightning.strike) end local pos2 @@ -97,7 +109,7 @@ lightning.strike = function(pos) return false end - minetest.add_particlespawner({ + add_particlespawner({ amount = 1, time = 0.2, -- make it hit the top of a block exactly with the bottom @@ -120,16 +132,16 @@ lightning.strike = function(pos) glow = minetest.LIGHT_MAX, }) - minetest.sound_play({ name = "lightning_thunder", gain = 10 }, { pos = pos, max_hear_distance = 500 }, true) + sound_play({ name = "lightning_thunder", gain = 10 }, { pos = pos, max_hear_distance = 500 }, true) -- damage nearby objects, transform mobs - local objs = minetest.get_objects_inside_radius(pos2, 3.5) + local objs = get_objects_inside_radius(pos2, 3.5) for o=1, #objs do local obj = objs[o] local lua = obj:get_luaentity() if obj:is_player() then -- Player damage - if minetest.get_modpath("mcl_death_messages") then + if has_mcl_death_msg then mcl_death_messages.player_damage(obj, S("@1 was struck by lightning.", obj:get_player_name())) end obj:set_hp(obj:get_hp()-5, { type = "punch", from = "mod" }) @@ -139,7 +151,7 @@ lightning.strike = function(pos) if lua.name == "mobs_mc:pig" then local rot = obj:get_yaw() obj:remove() - obj = minetest.add_entity(pos2, "mobs_mc:pigman") + obj = add_entity(pos2, "mobs_mc:pigman") obj:set_yaw(rot) -- mooshroom: toggle color red/brown (no damage) elseif lua.name == "mobs_mc:mooshroom" then @@ -163,7 +175,7 @@ lightning.strike = function(pos) elseif lua.name == "mobs_mc:creeper" then local rot = obj:get_yaw() obj:remove() - obj = minetest.add_entity(pos2, "mobs_mc:creeper_charged") + obj = add_entity(pos2, "mobs_mc:creeper_charged") obj:set_yaw(rot) -- Other mobs: Just damage else @@ -172,7 +184,7 @@ lightning.strike = function(pos) end end - local playerlist = minetest.get_connected_players() + local playerlist = get_connected_players() for i = 1, #playerlist do local player = playerlist[i] local sky = {} @@ -197,25 +209,25 @@ lightning.strike = function(pos) if rng:next(1,100) <= 3 then skeleton_lightning = true end - if minetest.get_item_group(minetest.get_node({x = pos2.x, y = pos2.y - 1, z = pos2.z}).name, "liquid") < 1 then - if minetest.get_node(pos2).name == "air" then + if get_item_group(get_node({x = pos2.x, y = pos2.y - 1, z = pos2.z}).name, "liquid") < 1 then + if get_node(pos2).name == "air" then -- Low chance for a lightning to spawn skeleton horse + skeletons if skeleton_lightning then - minetest.add_entity(pos2, "mobs_mc:skeleton_horse") + add_entity(pos2, "mobs_mc:skeleton_horse") local angle, posadd angle = math.random(0, math.pi*2) for i=1,3 do posadd = {x=math.cos(angle),y=0,z=math.sin(angle)} posadd = vector.normalize(posadd) - local mob = minetest.add_entity(vector.add(pos2, posadd), "mobs_mc:skeleton") + local mob = add_entity(vector.add(pos2, posadd), "mobs_mc:skeleton") mob:set_yaw(angle-math.pi/2) angle = angle + (math.pi*2) / 3 end -- Cause a fire else - minetest.set_node(pos2, {name = "mcl_fire:fire"}) + set_node(pos2, {name = "mcl_fire:fire"}) end end end @@ -223,9 +235,9 @@ lightning.strike = function(pos) end -- if other mods disable auto lightning during initialization, don't trigger the first lightning. -minetest.after(5, function(dtime) +after(5, function(dtime) if lightning.auto then - minetest.after(rng:next(lightning.interval_low, + after(rng:next(lightning.interval_low, lightning.interval_high), lightning.strike) end end) diff --git a/mods/ENVIRONMENT/lightning/mod.conf b/mods/ENVIRONMENT/lightning/mod.conf index 948a40751..b0d756318 100644 --- a/mods/ENVIRONMENT/lightning/mod.conf +++ b/mods/ENVIRONMENT/lightning/mod.conf @@ -1 +1,6 @@ name = lightning +author = sofar +description = A mod that adds thunder and lightning effects. +depends = mcl_fire +optional_depends = mcl_death_messages + diff --git a/mods/ENVIRONMENT/mcl_moon/mod.conf b/mods/ENVIRONMENT/mcl_moon/mod.conf index 9ff8c04ba..92541d72c 100644 --- a/mods/ENVIRONMENT/mcl_moon/mod.conf +++ b/mods/ENVIRONMENT/mcl_moon/mod.conf @@ -1,2 +1,3 @@ name = mcl_moon +author = Wuzzy description = Adds moon phases to the game diff --git a/mods/ENVIRONMENT/mcl_void_damage/depends.txt b/mods/ENVIRONMENT/mcl_void_damage/depends.txt deleted file mode 100644 index e134aeef6..000000000 --- a/mods/ENVIRONMENT/mcl_void_damage/depends.txt +++ /dev/null @@ -1,2 +0,0 @@ -mcl_worlds -mcl_death_messages diff --git a/mods/ENVIRONMENT/mcl_void_damage/description.txt b/mods/ENVIRONMENT/mcl_void_damage/description.txt deleted file mode 100644 index ac7e3d8c4..000000000 --- a/mods/ENVIRONMENT/mcl_void_damage/description.txt +++ /dev/null @@ -1 +0,0 @@ -Deal damage to entities stuck in the deep void diff --git a/mods/ENVIRONMENT/mcl_void_damage/init.lua b/mods/ENVIRONMENT/mcl_void_damage/init.lua index 205198a46..ee40ed702 100644 --- a/mods/ENVIRONMENT/mcl_void_damage/init.lua +++ b/mods/ENVIRONMENT/mcl_void_damage/init.lua @@ -1,6 +1,14 @@ local S = minetest.get_translator("mcl_void_damage") local enable_damage = minetest.settings:get_bool("enable_damage") +local pos_to_dim = mcl_worlds.pos_to_dimension +local dim_change = mcl_worlds.dimension_change +local is_in_void = mcl_worlds.is_in_void +local get_spawn_pos = mcl_spawn.get_player_spawn_pos +local death_msg = mcl_death_messages.player_damage +local send_chat = minetest.chat_send_player +local get_connected = minetest.get_connected_players + local voidtimer = 0 local VOID_DAMAGE_FREQ = 0.5 local VOID_DAMAGE = 4 @@ -33,7 +41,7 @@ minetest.register_on_mods_loaded(function() self._void_timer = 0 local pos = obj:get_pos() - local void, void_deadly = mcl_worlds.is_in_void(pos) + local void, void_deadly = is_in_void(pos) if void_deadly then local ent = obj:get_luaentity() obj:remove() @@ -51,11 +59,11 @@ minetest.register_globalstep(function(dtime) if voidtimer > VOID_DAMAGE_FREQ then voidtimer = 0 local enable_damage = minetest.settings:get_bool("enable_damage") - local players = minetest.get_connected_players() + local players = get_connected() for p=1, #players do local player = players[p] local pos = player:get_pos() - local void, void_deadly = mcl_worlds.is_in_void(pos) + local void, void_deadly = is_in_void(pos) if void_deadly then local immortal_val = player:get_armor_groups().immortal local is_immortal = false @@ -65,14 +73,14 @@ minetest.register_globalstep(function(dtime) if is_immortal or not enable_damage then -- If damage is disabled, we can't kill players. -- So we just teleport the player back to spawn. - local spawn = mcl_spawn.get_player_spawn_pos(player) + local spawn = get_spawn_pos(player) player:set_pos(spawn) - mcl_worlds.dimension_change(player, mcl_worlds.pos_to_dimension(spawn)) - minetest.chat_send_player(player:get_player_name(), S("The void is off-limits to you!")) + dim_change(player, pos_to_dim(spawn)) + send_chat(player:get_player_name(), S("The void is off-limits to you!")) elseif enable_damage and not is_immortal then -- Damage enabled, not immortal: Deal void damage (4 HP / 0.5 seconds) if player:get_hp() > 0 then - mcl_death_messages.player_damage(player, S("@1 fell into the endless void.", player:get_player_name())) + death_msg(player, S("@1 fell into the endless void.", player:get_player_name())) player:set_hp(player:get_hp() - VOID_DAMAGE) end end diff --git a/mods/ENVIRONMENT/mcl_void_damage/mod.conf b/mods/ENVIRONMENT/mcl_void_damage/mod.conf index 7e0ea4bac..3f34fa5a1 100644 --- a/mods/ENVIRONMENT/mcl_void_damage/mod.conf +++ b/mods/ENVIRONMENT/mcl_void_damage/mod.conf @@ -1 +1,4 @@ name = mcl_void_damage +author = Wuzzy +description = Deal damage to entities stuck in the deep void +depends = mcl_worlds, mcl_death_messages diff --git a/mods/ENVIRONMENT/mcl_weather/depends.txt b/mods/ENVIRONMENT/mcl_weather/depends.txt deleted file mode 100644 index 0e5110c41..000000000 --- a/mods/ENVIRONMENT/mcl_weather/depends.txt +++ /dev/null @@ -1,3 +0,0 @@ -mcl_init -mcl_worlds -lightning? diff --git a/mods/ENVIRONMENT/mcl_weather/description.txt b/mods/ENVIRONMENT/mcl_weather/description.txt deleted file mode 100644 index 3f28b271e..000000000 --- a/mods/ENVIRONMENT/mcl_weather/description.txt +++ /dev/null @@ -1 +0,0 @@ -Weather and sky handling: Rain, snow, thunderstorm, End and Nether ambience diff --git a/mods/ENVIRONMENT/mcl_weather/mod.conf b/mods/ENVIRONMENT/mcl_weather/mod.conf index 4cc16984e..4f1102b7a 100644 --- a/mods/ENVIRONMENT/mcl_weather/mod.conf +++ b/mods/ENVIRONMENT/mcl_weather/mod.conf @@ -1 +1,5 @@ name = mcl_weather +author = xeranas +description = Weather and sky handling: Rain, snow, thunderstorm, End and Nether ambience +depends = mcl_init, mcl_worlds +optional_depends = lightning 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/HELP/doc/description.txt b/mods/HELP/doc/description.txt deleted file mode 100644 index 59a7a4c21..000000000 --- a/mods/HELP/doc/description.txt +++ /dev/null @@ -1 +0,0 @@ -Provides an extensible in-game help with texts about gameplay basics (such a crafting), items and advanced usage. diff --git a/mods/HELP/doc/doc/mod.conf b/mods/HELP/doc/doc/mod.conf index 302fd83d1..0f65ddff7 100644 --- a/mods/HELP/doc/doc/mod.conf +++ b/mods/HELP/doc/doc/mod.conf @@ -1,3 +1,4 @@ name = doc -optional_depends = unified_inventory, sfinv_buttons, central_message, inventory_plus +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 diff --git a/mods/HELP/doc/doc_identifier/mod.conf b/mods/HELP/doc/doc_identifier/mod.conf index 4a7626a4e..28a09d07e 100644 --- a/mods/HELP/doc/doc_identifier/mod.conf +++ b/mods/HELP/doc/doc_identifier/mod.conf @@ -1,4 +1,5 @@ name = doc_identifier +author = Wuzzy +description = Adds a tool which shows help entries about almost anything which it punches. depends = doc, doc_items optional_depends = doc_basics, mcl_core -description = Adds a tool which shows help entries about almost anything which it punches. diff --git a/mods/HELP/doc/doc_items/mod.conf b/mods/HELP/doc/doc_items/mod.conf index f1c0fbbc5..65d6e8366 100644 --- a/mods/HELP/doc/doc_items/mod.conf +++ b/mods/HELP/doc/doc_items/mod.conf @@ -1,3 +1,4 @@ name = doc_items -depends = doc +author = Wuzzy description = Adds automatically generated help texts for items. +depends = doc diff --git a/mods/HELP/doc/modpack.conf b/mods/HELP/doc/modpack.conf index 5e2f43080..f1268957d 100644 --- a/mods/HELP/doc/modpack.conf +++ b/mods/HELP/doc/modpack.conf @@ -1 +1,2 @@ name = doc +description = Provides an extensible in-game help with texts about gameplay basics (such a crafting), items and advanced usage. diff --git a/mods/HELP/mcl_craftguide/depends.txt b/mods/HELP/mcl_craftguide/depends.txt deleted file mode 100644 index 5bff11578..000000000 --- a/mods/HELP/mcl_craftguide/depends.txt +++ /dev/null @@ -1,6 +0,0 @@ -mcl_core -mcl_compass -mcl_clock -doc -sfinv? -sfinv_buttons? diff --git a/mods/HELP/mcl_craftguide/description.txt b/mods/HELP/mcl_craftguide/description.txt deleted file mode 100644 index b5c05403c..000000000 --- a/mods/HELP/mcl_craftguide/description.txt +++ /dev/null @@ -1,2 +0,0 @@ -The most comprehensive Crafting Guide -on Minetest. diff --git a/mods/HELP/mcl_craftguide/mod.conf b/mods/HELP/mcl_craftguide/mod.conf index d51c45413..b7ab8882c 100644 --- a/mods/HELP/mcl_craftguide/mod.conf +++ b/mods/HELP/mcl_craftguide/mod.conf @@ -1 +1,5 @@ name = mcl_craftguide +author = kilbith +description = The most comprehensive Crafting Guide on Minetest. +depends = mcl_core, mcl_compass, mcl_clock, doc +optional_depends = sfinv, sfinv_buttons diff --git a/mods/HELP/mcl_doc/depends.txt b/mods/HELP/mcl_doc/depends.txt deleted file mode 100644 index 93440a299..000000000 --- a/mods/HELP/mcl_doc/depends.txt +++ /dev/null @@ -1,2 +0,0 @@ -doc -doc_items diff --git a/mods/HELP/mcl_doc/description.txt b/mods/HELP/mcl_doc/description.txt deleted file mode 100644 index 4ae29f507..000000000 --- a/mods/HELP/mcl_doc/description.txt +++ /dev/null @@ -1 +0,0 @@ -This MineClone 2 mod sets up and configures the Help modpack mods to tailor the help towards MineClone 2. diff --git a/mods/HELP/mcl_doc/mod.conf b/mods/HELP/mcl_doc/mod.conf index f5c27d080..d939761d5 100644 --- a/mods/HELP/mcl_doc/mod.conf +++ b/mods/HELP/mcl_doc/mod.conf @@ -1 +1,4 @@ name = mcl_doc +author = Wuzzy +description = This MineClone 2 mod sets up and configures the Help modpack mods to tailor the help towards MineClone 2. +depends = doc, doc_items diff --git a/mods/HELP/mcl_doc_basics/mod.conf b/mods/HELP/mcl_doc_basics/mod.conf index 525619045..c23a0ad55 100644 --- a/mods/HELP/mcl_doc_basics/mod.conf +++ b/mods/HELP/mcl_doc_basics/mod.conf @@ -1,3 +1,4 @@ name = mcl_doc_basics -depends = doc +author = Wuzzy description = Adds some help texts explaining how to use MineClone 2. +depends = doc diff --git a/mods/HELP/mcl_tt/depends.txt b/mods/HELP/mcl_tt/depends.txt deleted file mode 100644 index 12e5a198d..000000000 --- a/mods/HELP/mcl_tt/depends.txt +++ /dev/null @@ -1,2 +0,0 @@ -tt -mcl_enchanting diff --git a/mods/HELP/mcl_tt/mod.conf b/mods/HELP/mcl_tt/mod.conf new file mode 100644 index 000000000..3a33b70dc --- /dev/null +++ b/mods/HELP/mcl_tt/mod.conf @@ -0,0 +1,4 @@ +name = mcl_tt +author = Wuzzy +description = Add MCL2 tooltips +depends = tt, mcl_enchanting diff --git a/mods/HELP/tt/mod.conf b/mods/HELP/tt/mod.conf index d5c8c2eb1..23ce15369 100644 --- a/mods/HELP/tt/mod.conf +++ b/mods/HELP/tt/mod.conf @@ -1,2 +1,3 @@ name = tt +author = Wuzzy description = Support for custom tooltip extensions for items diff --git a/mods/HUD/awards/api.lua b/mods/HUD/awards/api.lua index 325c35165..9b0261b65 100644 --- a/mods/HUD/awards/api.lua +++ b/mods/HUD/awards/api.lua @@ -213,7 +213,8 @@ function awards.unlock(name, award) end -- Get award - minetest.log("action", name.." has gotten award "..name) + 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) .. "]"))) data.unlocked[award] = award awards.save() diff --git a/mods/HUD/awards/depends.txt b/mods/HUD/awards/depends.txt deleted file mode 100644 index 80a448a44..000000000 --- a/mods/HUD/awards/depends.txt +++ /dev/null @@ -1,2 +0,0 @@ -sfinv? -unified_inventory? diff --git a/mods/HUD/awards/description.txt b/mods/HUD/awards/description.txt deleted file mode 100644 index f2b9944c7..000000000 --- a/mods/HUD/awards/description.txt +++ /dev/null @@ -1 +0,0 @@ -Adds achievements to Minetest, and an API to register new ones. diff --git a/mods/HUD/awards/locale/awards.fr.tr b/mods/HUD/awards/locale/awards.fr.tr index 0c2925db7..c227a9c07 100644 --- a/mods/HUD/awards/locale/awards.fr.tr +++ b/mods/HUD/awards/locale/awards.fr.tr @@ -12,9 +12,9 @@ = = A Cat in a Pop-Tart?!=A Cat in a Pop-Tart?! -Achievement gotten!=Succès obtenue! -Achievement gotten:=Succès obtenue: -Achievement gotten: @1=Succès obtenue: @1 +Achievement gotten!=Succès obtenu ! +Achievement gotten:=Succès obtenu : +Achievement gotten: @1=Succès obtenu : @1 Achievement not found.=Succès inconnu All your awards and statistics have been cleared. You can now start again.=Toutes vos récompenses et statistiques ont été effacées. Vous pouvez maintenant recommencer. Awards=Récompenses @@ -28,9 +28,9 @@ Join the game.=Rejoignez le jeu. List awards in chat (deprecated)=Liste des récompenses dans le chat (obsolète) Place a block: @1=Placer un bloc: @1 Place blocks: @1×@2=Placer des blocs: @1×@2 -Secret Achievement gotten!=Succès secret obtenu! -Secret Achievement gotten:=Succès secret obtenu: -Secret Achievement gotten: @1=Succès secret obtenu: @1 +Secret Achievement gotten!=Succès secret obtenu ! +Secret Achievement gotten:=Succès secret obtenu : +Secret Achievement gotten: @1=Succès secret obtenu : @1 Show details of an achievement=Afficher les détails d'un succès Show, clear, disable or enable your achievements=Affichez, effacez, désactivez ou activez vos succès Get this achievement to find out what it is.=Obtenez ce succès pour découvrir de quoi il s'agit. @@ -38,8 +38,8 @@ Write @1 chat messages.=Écrivez @1 messages de chat. Write something in chat.=Écrivez quelque chose dans le chat. You have disabled your achievements.=Vous avez désactivé vos succès. You have enabled your achievements.=Vous avez activé vos succès. -You have not gotten any awards.=Vous n'avez reçu aucun prix. -You've disabled awards. Type /awards enable to reenable.=Vous avez désactivé les récompenses. Type /awards enable pour les activer. +You have not gotten any awards.=Vous n'avez reçu aucune récompense. +You've disabled awards. Type /awards enable to reenable.=Vous avez désactivé les récompenses. Tapez "/awards enable" pour les réactiver. [c|clear|disable|enable]=[c|clear|disable|enable] OK=OK Error: No awards available.=Erreur: aucune récompense disponible. @@ -52,10 +52,10 @@ Eat @1 item(s).=Manger @1 aliment(s). Craft @1 item(s).=Fabriquer @1 objet(s). Can give achievements to any player=Peut donner des succès à n'importe quel joueur (grant ( | all)) | list=(grant ( | all)) | list -Give achievement to player or list all achievements=Donner un succès a un joueur ou répertorier toutes les succès +Give achievement to player or list all achievements=Donner un succès à un joueur ou répertorier tous les succès @1 (@2)=@1 (@2) Invalid syntax.=Syntaxe invalide. Invalid action.=Action invalide. Player is not online.=Le joueur n'est pas en ligne. Done.=Terminé. -Achievement “@1” does not exist.=La réalisation «@1» n'existe pas. +Achievement “@1” does not exist.=Le succès «@1» n'existe pas. diff --git a/mods/HUD/awards/locale/awards.ru.tr b/mods/HUD/awards/locale/awards.ru.tr index 19623f391..8495c270f 100644 --- a/mods/HUD/awards/locale/awards.ru.tr +++ b/mods/HUD/awards/locale/awards.ru.tr @@ -59,3 +59,4 @@ Invalid action.=Непредусмотренное действие. Player is not online.=Игрок не подключён. Done.=Сделано. Achievement “@1” does not exist.=Достижения “@1” не существует. +@1 has made the achievement @2=@1 получил(а) достижение @2 diff --git a/mods/HUD/awards/locale/template.txt b/mods/HUD/awards/locale/template.txt index 529d524c0..a1505b349 100644 --- a/mods/HUD/awards/locale/template.txt +++ b/mods/HUD/awards/locale/template.txt @@ -59,3 +59,4 @@ Invalid action.= Player is not online.= Done.= Achievement “@1” does not exist.= +@1 has made the achievement @2= diff --git a/mods/HUD/awards/mod.conf b/mods/HUD/awards/mod.conf index 24042f267..8b1534692 100644 --- a/mods/HUD/awards/mod.conf +++ b/mods/HUD/awards/mod.conf @@ -5,3 +5,4 @@ description = Adds achievements to Minetest, and an API to register new ones. license = LGPL 2.1 or later forum = https://forum.minetest.net/viewtopic.php?t=4870 version = 2.3.0 +optional_depends = sfinv, unified_inventory diff --git a/mods/HUD/hudbars/init.lua b/mods/HUD/hudbars/init.lua index 44c826656..e1ff3f5f1 100644 --- a/mods/HUD/hudbars/init.lua +++ b/mods/HUD/hudbars/init.lua @@ -46,7 +46,7 @@ end -- Load default settings dofile(minetest.get_modpath("hudbars").."/default_settings.lua") -if minetest.get_modpath("mcl_experience") then +if minetest.get_modpath("mcl_experience") and not minetest.is_creative_enabled("") then -- reserve some space for experience bar: hb.settings.start_offset_left.y = hb.settings.start_offset_left.y - 20 hb.settings.start_offset_right.y = hb.settings.start_offset_right.y - 20 @@ -511,9 +511,9 @@ local function update_health(player) end -- update built-in HUD bars -local function update_hud(player) +local function update_hud(player, has_damage) if not player_exists(player) then return end - if minetest.settings:get_bool("enable_damage") then + if has_damage then if hb.settings.forceload_default_hudbars then hb.unhide_hudbar(player, "health") end @@ -564,10 +564,11 @@ minetest.register_globalstep(function(dtime) if main_timer > hb.settings.tick or timer > 4 then if main_timer > hb.settings.tick then main_timer = 0 end -- only proceed if damage is enabled - if minetest.settings:get_bool("enable_damage") or hb.settings.forceload_default_hudbars then + local has_dmg = minetest.settings:get_bool("enable_damage") + if has_dmg or hb.settings.forceload_default_hudbars then for _, player in pairs(hb.players) do -- update all hud elements - update_hud(player) + update_hud(player, has_dmg) end end end diff --git a/mods/HUD/hudbars/mod.conf b/mods/HUD/hudbars/mod.conf index 5fa238a83..9d49f65ec 100644 --- a/mods/HUD/hudbars/mod.conf +++ b/mods/HUD/hudbars/mod.conf @@ -1,2 +1,3 @@ name = hudbars +author = Wuzzy description = Replaces the health and breath symbols in the HUD by “progress bars” and shows exact values. Other mods can add more progress bars for custom player stats. diff --git a/mods/HUD/mcl_achievements/depends.txt b/mods/HUD/mcl_achievements/depends.txt deleted file mode 100644 index 203a4c0ab..000000000 --- a/mods/HUD/mcl_achievements/depends.txt +++ /dev/null @@ -1 +0,0 @@ -awards diff --git a/mods/HUD/mcl_achievements/mod.conf b/mods/HUD/mcl_achievements/mod.conf index b9d5af185..ed11618d7 100644 --- a/mods/HUD/mcl_achievements/mod.conf +++ b/mods/HUD/mcl_achievements/mod.conf @@ -1 +1,4 @@ name = mcl_achievements +author = Wuzzy +description = Adds MCL2 Archivements +depends = awards diff --git a/mods/HUD/mcl_base_textures/description.txt b/mods/HUD/mcl_base_textures/description.txt deleted file mode 100644 index bfd0d06bb..000000000 --- a/mods/HUD/mcl_base_textures/description.txt +++ /dev/null @@ -1 +0,0 @@ -Provides core textures needed by Minetest. diff --git a/mods/HUD/mcl_base_textures/mod.conf b/mods/HUD/mcl_base_textures/mod.conf index 492aeca87..b36dccfe4 100644 --- a/mods/HUD/mcl_base_textures/mod.conf +++ b/mods/HUD/mcl_base_textures/mod.conf @@ -1 +1,3 @@ name = mcl_base_textures +author = Wuzzy +description = Provides core textures needed by Minetest. diff --git a/mods/HUD/mcl_death_messages/description.txt b/mods/HUD/mcl_death_messages/description.txt deleted file mode 100644 index 7c322f644..000000000 --- a/mods/HUD/mcl_death_messages/description.txt +++ /dev/null @@ -1 +0,0 @@ -Shows messages in chat when a player dies. diff --git a/mods/HUD/mcl_death_messages/init.lua b/mods/HUD/mcl_death_messages/init.lua index dfc5191a6..b2c656ac4 100644 --- a/mods/HUD/mcl_death_messages/init.lua +++ b/mods/HUD/mcl_death_messages/init.lua @@ -1,281 +1,297 @@ -local S = minetest.get_translator("mcl_death_messages") -local N = function(s) return s end - -mcl_death_messages = {} - --- Death messages -local msgs = { - ["arrow"] = { - N("@1 was fatally hit by an arrow."), - N("@1 has been killed by an arrow."), - }, - ["arrow_name"] = { - N("@1 was shot by an arrow from @2."), - }, - ["arrow_skeleton"] = { - N("@1 was shot by an arrow from a skeleton."), - }, - ["arrow_stray"] = { - N("@1 was shot by an arrow from a stray."), - }, - ["arrow_illusioner"] = { - N("@1 was shot by an arrow from an illusioner."), - }, - ["arrow_mob"] = { - N("@1 was shot by an arrow."), - }, - ["drown"] = { - N("@1 forgot to breathe."), - N("@1 drowned."), - N("@1 ran out of oxygen."), - }, - ["murder"] = { - N("@1 was killed by @2."), - }, - ["murder_any"] = { - N("@1 was killed."), - }, - ["mob_kill"] = { - N("@1 was killed by a mob."), - }, - ["blaze_fireball"] = { - N("@1 was burned to death by a blaze's fireball."), - N("@1 was killed by a fireball from a blaze."), - }, - ["fire_charge"] = { - N("@1 was burned by a fire charge."), - }, - ["ghast_fireball"] = { - N("A ghast scared @1 to death."), - N("@1 has been fireballed by a ghast."), - }, - ["fall"] = { - N("@1 fell from a high cliff."), - N("@1 took fatal fall damage."), - N("@1 fell victim to gravity."), - }, - ["other"] = { - N("@1 died."), - } -} - -local mobkills = { - ["mobs_mc:zombie"] = N("@1 was killed by a zombie."), - ["mobs_mc:baby_zombie"] = N("@1 was killed by a baby zombie."), - ["mobs_mc:blaze"] = N("@1 was killed by a blaze."), - ["mobs_mc:slime"] = N("@1 was killed by a slime."), - ["mobs_mc:witch"] = N("@1 was killed by a witch."), - ["mobs_mc:magma_cube_tiny"] = N("@1 was killed by a magma cube."), - ["mobs_mc:magma_cube_small"] = N("@1 was killed by a magma cube."), - ["mobs_mc:magma_cube_big"] = N("@1 was killed by a magma cube."), - ["mobs_mc:wolf"] = N("@1 was killed by a wolf."), - ["mobs_mc:cat"] = N("@1 was killed by a cat."), - ["mobs_mc:ocelot"] = N("@1 was killed by an ocelot."), - ["mobs_mc:enderdragon"] = N("@1 was killed by an ender dragon."), - ["mobs_mc:wither"] = N("@1 was killed by a wither."), - ["mobs_mc:enderman"] = N("@1 was killed by an enderman."), - ["mobs_mc:endermite"] = N("@1 was killed by an endermite."), - ["mobs_mc:ghast"] = N("@1 was killed by a ghast."), - ["mobs_mc:guardian_elder"] = N("@1 was killed by an elder guardian."), - ["mobs_mc:guardian"] = N("@1 was killed by a guardian."), - ["mobs_mc:iron_golem"] = N("@1 was killed by an iron golem."), - ["mobs_mc:polar_bear"] = N("@1 was killed by a polar_bear."), - ["mobs_mc:killer_bunny"] = N("@1 was killed by a killer bunny."), - ["mobs_mc:shulker"] = N("@1 was killed by a shulker."), - ["mobs_mc:silverfish"] = N("@1 was killed by a silverfish."), - ["mobs_mc:skeleton"] = N("@1 was killed by a skeleton."), - ["mobs_mc:stray"] = N("@1 was killed by a stray."), - ["mobs_mc:slime_tiny"] = N("@1 was killed by a slime."), - ["mobs_mc:slime_small"] = N("@1 was killed by a slime."), - ["mobs_mc:slime_big"] = N("@1 was killed by a slime."), - ["mobs_mc:spider"] = N("@1 was killed by a spider."), - ["mobs_mc:cave_spider"] = N("@1 was killed by a cave spider."), - ["mobs_mc:vex"] = N("@1 was killed by a vex."), - ["mobs_mc:evoker"] = N("@1 was killed by an evoker."), - ["mobs_mc:illusioner"] = N("@1 was killed by an illusioner."), - ["mobs_mc:vindicator"] = N("@1 was killed by a vindicator."), - ["mobs_mc:villager_zombie"] = N("@1 was killed by a zombie villager."), - ["mobs_mc:husk"] = N("@1 was killed by a husk."), - ["mobs_mc:baby_husk"] = N("@1 was killed by a baby husk."), - ["mobs_mc:pigman"] = N("@1 was killed by a zombie pigman."), - ["mobs_mc:baby_pigman"] = N("@1 was killed by a baby zombie pigman."), -} - --- Select death message -local dmsg = function(mtype, ...) - local r = math.random(1, #msgs[mtype]) - return S(msgs[mtype][r], ...) -end - --- Select death message for death by mob -local mmsg = function(mtype, ...) - if mobkills[mtype] then - return S(mobkills[mtype], ...) - else - return dmsg("mob_kill", ...) - end -end - -local last_damages = { } - -minetest.register_on_dieplayer(function(player, reason) - -- Death message - local message = minetest.settings:get_bool("mcl_showDeathMessages") - if message == nil then - message = true - end - if message then - local name = player:get_player_name() - if not name then - return - end - local msg - if last_damages[name] then - -- custom message - msg = last_damages[name].message - elseif reason.type == "node_damage" then - local pos = player:get_pos() - -- Check multiple nodes because players occupy multiple nodes - -- (we add one additional node because the check may fail if the player was - -- just barely touching the node with the head) - local posses = { pos, {x=pos.x,y=pos.y+1,z=pos.z}, {x=pos.x,y=pos.y+2,z=pos.z}} - local highest_damage = 0 - local highest_damage_def = nil - -- Show message for node that dealt the most damage - for p=1, #posses do - local def = minetest.registered_nodes[minetest.get_node(posses[p]).name] - local dmg = def.damage_per_second - if dmg and dmg > highest_damage then - highest_damage = dmg - highest_damage_def = def - end - end - if highest_damage_def and highest_damage_def._mcl_node_death_message then - local field = highest_damage_def._mcl_node_death_message - local field_msg - if type(field) == "table" then - field_msg = field[math.random(1, #field)] - else - field_msg = field - end - local textdomain - if highest_damage_def.mod_origin then - textdomain = highest_damage_def.mod_origin - else - textdomain = "mcl_death_messages" - end - -- We assume the textdomain of the death message in the node definition - -- equals the modname. - msg = minetest.translate(textdomain, field_msg, name) - end - elseif reason.type == "drown" then - msg = dmsg("drown", name) - elseif reason.type == "punch" then - -- Punches - local hitter = reason.object - local hittername, hittertype, hittersubtype, shooter - -- Custom message - if last_damages[name] then - msg = last_damages[name].message - -- Unknown hitter - elseif hitter == nil then - msg = dmsg("murder_any", name) - -- Player - elseif hitter:is_player() then - hittername = hitter:get_player_name() - if hittername ~= nil then - msg = dmsg("murder", name, hittername) - else - msg = dmsg("murder_any", name) - end - -- Mob (according to Common Mob Interface) - elseif hitter:get_luaentity()._cmi_is_mob then - if hitter:get_luaentity().nametag and hitter:get_luaentity().nametag ~= "" then - hittername = hitter:get_luaentity().nametag - end - hittersubtype = hitter:get_luaentity().name - if hittername then - msg = dmsg("murder", name, hittername) - elseif hittersubtype ~= nil and hittersubtype ~= "" then - msg = mmsg(hittersubtype, name) - else - msg = dmsg("murder_any", name) - end - -- Arrow - elseif hitter:get_luaentity().name == "mcl_bows:arrow_entity" or hitter:get_luaentity().name == "mobs_mc:arrow_entity" then - local shooter - if hitter:get_luaentity()._shooter then - shooter = hitter:get_luaentity()._shooter - end - local is_mob = false - local s_ent = shooter and shooter:get_luaentity() - if shooter == nil then - msg = dmsg("arrow", name) - elseif shooter:is_player() then - msg = dmsg("arrow_name", name, shooter:get_player_name()) - elseif s_ent and s_ent._cmi_is_mob then - if s_ent.nametag ~= "" then - msg = dmsg("arrow_name", name, shooter:get_player_name()) - elseif s_ent.name == "mobs_mc:skeleton" then - msg = dmsg("arrow_skeleton", name) - elseif s_ent.name == "mobs_mc:stray" then - msg = dmsg("arrow_stray", name) - elseif s_ent.name == "mobs_mc:illusioner" then - msg = dmsg("arrow_illusioner", name) - else - msg = dmsg("arrow_mob", name) - end - else - msg = dmsg("arrow", name) - end - -- Blaze fireball - elseif hitter:get_luaentity().name == "mobs_mc:blaze_fireball" then - if hitter:get_luaentity()._shot_from_dispenser then - msg = dmsg("fire_charge", name) - else - msg = dmsg("blaze_fireball", name) - end - -- Ghast fireball - elseif hitter:get_luaentity().name == "mobs_monster:fireball" then - msg = dmsg("ghast_fireball", name) - end - -- Falling - elseif reason.type == "fall" then - msg = dmsg("fall", name) - -- Other - elseif reason.type == "set_hp" then - if last_damages[name] then - msg = last_damages[name].message - end - end - if not msg then - msg = dmsg("other", name) - end - minetest.chat_send_all(msg) - last_damages[name] = nil - end -end) - --- dmg_sequence_number is used to discard old damage events -local dmg_sequence_number = 0 -local start_damage_reset_countdown = function (player, sequence_number) - minetest.after(1, function(playername, sequence_number) - if last_damages[playername] and last_damages[playername].sequence_number == sequence_number then - last_damages[playername] = nil - end - end, player:get_player_name(), sequence_number) -end - --- Send a custom death mesage when damaging a player via set_hp or punch. --- To be called directly BEFORE damaging a player via set_hp or punch. --- The next time the player dies due to a set_hp, the message will be shown. --- The player must die via set_hp within 0.1 seconds, otherwise the message will be discarded. -function mcl_death_messages.player_damage(player, message) - last_damages[player:get_player_name()] = { message = message, sequence_number = dmg_sequence_number } - start_damage_reset_countdown(player, dmg_sequence_number) - dmg_sequence_number = dmg_sequence_number + 1 - if dmg_sequence_number >= 65535 then - dmg_sequence_number = 0 - end -end - +local S = minetest.get_translator("mcl_death_messages") +local N = function(s) return s end + +local function get_tool_name(item) + local name = item:get_meta():get_string("name") + if name ~= "" then + return name + end + local def = item:get_definition() + return def._tt_original_description or def.description + end + +mcl_death_messages = {} + +-- Death messages +local msgs = { + ["arrow"] = { + N("@1 was fatally hit by an arrow."), + N("@1 has been killed by an arrow."), + }, + ["arrow_name"] = { + N("@1 was shot by @2 using [@3]"), + }, + ["arrow_skeleton"] = { + N("@1 was shot by Skeleton."), + }, + ["arrow_stray"] = { + N("@1 was shot by Stray."), + }, + ["arrow_illusioner"] = { + N("@1 was shot by Illusioner."), + }, + ["arrow_mob"] = { + N("@1 was shot."), + }, + ["drown"] = { + N("@1 forgot to breathe."), + N("@1 drowned."), + N("@1 ran out of oxygen."), + }, + ["murder"] = { + N("@1 was slain by @2 using [@3]"), + }, + ["murder_any"] = { + N("@1 was killed."), + }, + ["mob_kill"] = { + N("@1 was slain by a mob."), + }, + ["blaze_fireball"] = { + N("@1 was burned to death by a Blaze's fireball."), + N("@1 was fireballed by a Blaze"), + }, + ["fire_charge"] = { + N("@1 was burned by a fire charge."), + }, + ["ghast_fireball"] = { + N("A Ghast scared @1 to death."), + N("@1 has been fireballed by a Ghast."), + }, + ["fall"] = { + N("@1 fell from a high cliff."), + N("@1 took fatal fall damage."), + N("@1 fell victim to gravity."), + N("@1 hit the ground too hard.") + }, + + ["other"] = { + N("@1 died."), + } +} + +local mobkills = { + ["mobs_mc:zombie"] = N("@1 was slain by Zombie."), + ["mobs_mc:baby_zombie"] = N("@1 was slain by Baby Zombie."), + ["mobs_mc:blaze"] = N("@1 was burnt to a crisp while fighting Blaze."), + ["mobs_mc:slime"] = N("@1 was slain by Slime."), + ["mobs_mc:witch"] = N("@1 was slain by Witch using magic."), + ["mobs_mc:magma_cube_tiny"] = N("@1 was slain by Magma Cube."), + ["mobs_mc:magma_cube_small"] = N("@1 was slain by Magma Cube."), + ["mobs_mc:magma_cube_big"] = N("@1 was slain by Magma Cube."), + ["mobs_mc:wolf"] = N("@1 was slain by Wolf."), + ["mobs_mc:cat"] = N("@1 was slain by Cat."), + ["mobs_mc:ocelot"] = N("@1 was slain by Ocelot."), + ["mobs_mc:enderdragon"] = N("@1 was slain by Enderdragon."), + ["mobs_mc:wither"] = N("@1 was slain by Wither."), + ["mobs_mc:enderman"] = N("@1 was slain by Enderman."), + ["mobs_mc:endermite"] = N("@1 was slain by Endermite."), + ["mobs_mc:ghast"] = N("@1 was fireballed by a Ghast."), + ["mobs_mc:guardian_elder"] = N("@1 was slain by Elder Guardian."), + ["mobs_mc:guardian"] = N("@1 was slain by Guardian."), + ["mobs_mc:iron_golem"] = N("@1 was slain by Iron Golem."), + ["mobs_mc:polar_bear"] = N("@1 was slain by Polar Bear."), + ["mobs_mc:killer_bunny"] = N("@1 was slain by Killer Bunny."), + ["mobs_mc:shulker"] = N("@1 was slain by Shulker."), + ["mobs_mc:silverfish"] = N("@1 was slain by Silverfish."), + ["mobs_mc:skeleton"] = N("@1 was shot by Skeleton."), + ["mobs_mc:stray"] = N("@1 was shot by Stray."), + ["mobs_mc:slime_tiny"] = N("@1 was slain by Slime."), + ["mobs_mc:slime_small"] = N("@1 was slain by Slime."), + ["mobs_mc:slime_big"] = N("@1 was slain by Slime."), + ["mobs_mc:spider"] = N("@1 was slain by Spider."), + ["mobs_mc:cave_spider"] = N("@1 was slain by Cave Spider."), + ["mobs_mc:vex"] = N("@1 was slain by Vex."), + ["mobs_mc:evoker"] = N("@1 was slain by Evoker."), + ["mobs_mc:illusioner"] = N("@1 was slain by Illusioner."), + ["mobs_mc:vindicator"] = N("@1 was slain by Vindicator."), + ["mobs_mc:villager_zombie"] = N("@1 was slain by Zombie Villager."), + ["mobs_mc:husk"] = N("@1 was slain by Husk."), + ["mobs_mc:baby_husk"] = N("@1 was slain by Baby Husk."), + ["mobs_mc:pigman"] = N("@1 was slain by Zombie Pigman."), + ["mobs_mc:baby_pigman"] = N("@1 was slain by Baby Zombie Pigman."), +} + +-- Select death message +local dmsg = function(mtype, ...) + local r = math.random(1, #msgs[mtype]) + return S(msgs[mtype][r], ...) +end + +-- Select death message for death by mob +local mmsg = function(mtype, ...) + if mobkills[mtype] then + return S(mobkills[mtype], ...) + else + return dmsg("mob_kill", ...) + end +end + +local last_damages = { } + +minetest.register_on_dieplayer(function(player, reason) + -- Death message + local message = minetest.settings:get_bool("mcl_showDeathMessages") + if message == nil then + message = true + end + if message then + local name = player:get_player_name() + if not name then + return + end + local msg + if last_damages[name] then + -- custom message + msg = last_damages[name].message + elseif reason.type == "node_damage" then + local pos = player:get_pos() + -- Check multiple nodes because players occupy multiple nodes + -- (we add one additional node because the check may fail if the player was + -- just barely touching the node with the head) + local posses = { pos, {x=pos.x,y=pos.y+1,z=pos.z}, {x=pos.x,y=pos.y+2,z=pos.z}} + local highest_damage = 0 + local highest_damage_def = nil + -- Show message for node that dealt the most damage + for p=1, #posses do + local def = minetest.registered_nodes[minetest.get_node(posses[p]).name] + local dmg = def.damage_per_second + if dmg and dmg > highest_damage then + highest_damage = dmg + highest_damage_def = def + end + end + if highest_damage_def and highest_damage_def._mcl_node_death_message then + local field = highest_damage_def._mcl_node_death_message + local field_msg + if type(field) == "table" then + field_msg = field[math.random(1, #field)] + else + field_msg = field + end + local textdomain + if highest_damage_def.mod_origin then + textdomain = highest_damage_def.mod_origin + else + textdomain = "mcl_death_messages" + end + -- We assume the textdomain of the death message in the node definition + -- equals the modname. + msg = minetest.translate(textdomain, field_msg, name) + end + elseif reason.type == "drown" then + msg = dmsg("drown", name) + elseif reason.type == "punch" then + -- Punches + local hitter = reason.object + + -- Player was slain by potions + if not hitter then return end + + local hittername, hittertype, hittersubtype, shooter + local hitter_toolname = get_tool_name(hitter:get_wielded_item()) + + -- Custom message + if last_damages[name] then + msg = last_damages[name].message + -- Unknown hitter + elseif hitter == nil then + msg = dmsg("murder_any", name) + -- Player + elseif hitter:is_player() then + hittername = hitter:get_player_name() + if hittername ~= nil then + msg = dmsg("murder", name, hittername, minetest.colorize("#00FFFF", hitter_toolname)) + else + msg = dmsg("murder_any", name) + end + -- Mob (according to Common Mob Interface) + elseif hitter:get_luaentity()._cmi_is_mob then + if hitter:get_luaentity().nametag and hitter:get_luaentity().nametag ~= "" then + hittername = hitter:get_luaentity().nametag + end + hittersubtype = hitter:get_luaentity().name + if hittername then + msg = dmsg("murder", name, hittername) + elseif hittersubtype ~= nil and hittersubtype ~= "" then + msg = mmsg(hittersubtype, name) + else + msg = dmsg("murder_any", name) + end + -- Arrow + elseif hitter:get_luaentity().name == "mcl_bows:arrow_entity" or hitter:get_luaentity().name == "mobs_mc:arrow_entity" and not killed_by_potion then + local shooter + if hitter:get_luaentity()._shooter then + shooter = hitter:get_luaentity()._shooter + end + local is_mob = false + local s_ent = shooter and shooter:get_luaentity() + 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()))) + 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())) + elseif s_ent.name == "mobs_mc:skeleton" then + msg = dmsg("arrow_skeleton", name) + elseif s_ent.name == "mobs_mc:stray" then + msg = dmsg("arrow_stray", name) + elseif s_ent.name == "mobs_mc:illusioner" then + msg = dmsg("arrow_illusioner", name) + else + msg = dmsg("arrow_mob", name) + end + else + msg = dmsg("arrow", name) + end + -- Blaze fireball + elseif hitter:get_luaentity().name == "mobs_mc:blaze_fireball" then + if hitter:get_luaentity()._shot_from_dispenser then + msg = dmsg("fire_charge", name) + else + msg = dmsg("blaze_fireball", name) + end + -- Ghast fireball + elseif hitter:get_luaentity().name == "mobs_monster:fireball" then + msg = dmsg("ghast_fireball", name) + end + -- Falling + elseif reason.type == "fall" then + msg = dmsg("fall", name) + -- Other + elseif reason.type == "set_hp" then + if last_damages[name] then + msg = last_damages[name].message + end + end + if not msg then + msg = dmsg("other", name) + end + minetest.chat_send_all(msg) + last_damages[name] = nil + end +end) + +-- dmg_sequence_number is used to discard old damage events +local dmg_sequence_number = 0 +local start_damage_reset_countdown = function (player, sequence_number) + minetest.after(1, function(playername, sequence_number) + if last_damages[playername] and last_damages[playername].sequence_number == sequence_number then + last_damages[playername] = nil + end + end, player:get_player_name(), sequence_number) +end + +-- Send a custom death mesage when damaging a player via set_hp or punch. +-- To be called directly BEFORE damaging a player via set_hp or punch. +-- The next time the player dies due to a set_hp, the message will be shown. +-- The player must die via set_hp within 0.1 seconds, otherwise the message will be discarded. +function mcl_death_messages.player_damage(player, message) + last_damages[player:get_player_name()] = { message = message, sequence_number = dmg_sequence_number } + start_damage_reset_countdown(player, dmg_sequence_number) + dmg_sequence_number = dmg_sequence_number + 1 + if dmg_sequence_number >= 65535 then + dmg_sequence_number = 0 + end +end \ No newline at end of file diff --git a/mods/HUD/mcl_death_messages/mod.conf b/mods/HUD/mcl_death_messages/mod.conf index 4e4396074..23d2852e7 100644 --- a/mods/HUD/mcl_death_messages/mod.conf +++ b/mods/HUD/mcl_death_messages/mod.conf @@ -1 +1,3 @@ name = mcl_death_messages +author = 4Evergreen4 +description = Shows messages in chat when a player dies. diff --git a/mods/HUD/mcl_experience/init.lua b/mods/HUD/mcl_experience/init.lua index 32c2d9424..df733e138 100644 --- a/mods/HUD/mcl_experience/init.lua +++ b/mods/HUD/mcl_experience/init.lua @@ -66,6 +66,9 @@ end) -- create instance of new hud hud_manager.add_hud = function(player,hud_name,def) local name = player:get_player_name() + if minetest.is_creative_enabled(name) then + return + end local local_hud = player:hud_add({ hud_elem_type = def.hud_elem_type, position = def.position, @@ -181,7 +184,7 @@ minetest.register_on_joinplayer(function(player) hud_elem_type = "text", position = {x=0.5, y=1}, name = "xp_level", text = tostring(temp_pool.level), number = 0x80FF20, - offset = {x = 0, y = -(48 + 24 + 24)}, + offset = {x = 0, y = -(48 + 24 + 24)}, z_index = 12, }) end) @@ -309,7 +312,7 @@ function mcl_experience.add_experience(player, experience) temp_pool.xp = math.min(math.max(temp_pool.xp + experience, 0), max_xp) if (temp_pool.xp < temp_pool.xp_next_level) and (temp_pool.xp >= old_xp) then - temp_pool.bar = mcl_experience.xp_to_bar(temp_pool.xp, temp_pool.level) + temp_pool.bar = temp_pool.bar + temp_pool.bar_step * experience else temp_pool.level = mcl_experience.xp_to_level(temp_pool.xp) temp_pool.bar, temp_pool.bar_step, temp_pool.xp_next_level = mcl_experience.xp_to_bar(temp_pool.xp, temp_pool.level) @@ -614,9 +617,26 @@ minetest.register_entity("mcl_experience:bottle",{ local pos = self.object:get_pos() local node = minetest.get_node(pos) local n = node.name - if n ~= "air" and n ~= "mcl_portals:portal" and n ~= "mcl_portals:portal_end" and minetest.get_node_group(n, "liquid") == 0 then + if n ~= "air" and n ~= "mcl_portals:portal" and n ~= "mcl_portals:portal_end" and minetest.get_item_group(n, "liquid") == 0 then minetest.sound_play("mcl_potions_breaking_glass", {pos = pos, max_hear_distance = 16, gain = 1}) mcl_experience.throw_experience(pos, math.random(3, 11)) + minetest.add_particlespawner({ + amount = 50, + time = 0.1, + minpos = vector.add(pos, vector.new(-0.1, 0.5, -0.1)), + maxpos = vector.add(pos, vector.new( 0.1, 0.6, 0.1)), + minvel = vector.new(-2, 0, -2), + maxvel = vector.new( 2, 2, 2), + minacc = vector.new(0, 0, 0), + maxacc = vector.new(0, 0, 0), + minexptime = 0.5, + maxexptime = 1.25, + minsize = 1, + maxsize = 2, + collisiondetection = true, + vertical = false, + texture = "mcl_particles_effect.png^[colorize:blue:127", + }) self.object:remove() end end, diff --git a/mods/HUD/mcl_experience/mod.conf b/mods/HUD/mcl_experience/mod.conf new file mode 100644 index 000000000..211249b30 --- /dev/null +++ b/mods/HUD/mcl_experience/mod.conf @@ -0,0 +1,3 @@ +name = mcl_experience +author = oilboi +description = eXPerience mod diff --git a/mods/HUD/mcl_formspec/mod.conf b/mods/HUD/mcl_formspec/mod.conf index 9d614403f..8bc1ca7c3 100644 --- a/mods/HUD/mcl_formspec/mod.conf +++ b/mods/HUD/mcl_formspec/mod.conf @@ -1 +1,3 @@ +name = mcl_formspec +author = Wuzzy description = Helper mod to simplify creation of formspecs a little bit diff --git a/mods/HUD/mcl_formspec_prepend/depends.txt b/mods/HUD/mcl_formspec_prepend/depends.txt deleted file mode 100644 index 3b355984e..000000000 --- a/mods/HUD/mcl_formspec_prepend/depends.txt +++ /dev/null @@ -1 +0,0 @@ -mcl_init diff --git a/mods/HUD/mcl_formspec_prepend/mod.conf b/mods/HUD/mcl_formspec_prepend/mod.conf index c576d4493..544ab4ec7 100644 --- a/mods/HUD/mcl_formspec_prepend/mod.conf +++ b/mods/HUD/mcl_formspec_prepend/mod.conf @@ -1 +1,4 @@ name = mcl_formspec_prepend +author = Wuzzy +description = Formspec prepend for MCL2 +depends = mcl_init diff --git a/mods/HUD/mcl_hbarmor/description.txt b/mods/HUD/mcl_hbarmor/description.txt deleted file mode 100644 index 02a8a34f9..000000000 --- a/mods/HUD/mcl_hbarmor/description.txt +++ /dev/null @@ -1 +0,0 @@ -Adds a HUD bar displaying the current damage of the player's armor. 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_hbarmor/mod.conf b/mods/HUD/mcl_hbarmor/mod.conf index de5a2f20a..258395875 100644 --- a/mods/HUD/mcl_hbarmor/mod.conf +++ b/mods/HUD/mcl_hbarmor/mod.conf @@ -1,2 +1,4 @@ name = mcl_hbarmor +author = BlockMen +description = Adds a HUD bar displaying the current damage of the player's armor. depends = hudbars, mcl_armor diff --git a/mods/HUD/mcl_inventory/creative.lua b/mods/HUD/mcl_inventory/creative.lua index 1ab6eda08..1cebed0cd 100644 --- a/mods/HUD/mcl_inventory/creative.lua +++ b/mods/HUD/mcl_inventory/creative.lua @@ -331,7 +331,7 @@ mcl_inventory.set_creative_formspec = function(player, start_i, pagenum, inv_siz -- Show armor and player image local player_preview - if minetest.settings:get_bool("3d_player_preview") then + if minetest.settings:get_bool("3d_player_preview", true) then player_preview = mcl_player.get_player_formspec_model(player, 3.9, 1.4, 1.2333, 2.4666, "") else local img, img_player diff --git a/mods/HUD/mcl_inventory/depends.txt b/mods/HUD/mcl_inventory/depends.txt deleted file mode 100644 index 27231e5df..000000000 --- a/mods/HUD/mcl_inventory/depends.txt +++ /dev/null @@ -1,8 +0,0 @@ -mcl_init -mcl_formspec -mcl_player? -_mcl_autogroup? -mcl_armor? -mcl_brewing? -mcl_potions? -mcl_enchanting diff --git a/mods/HUD/mcl_inventory/description.txt b/mods/HUD/mcl_inventory/description.txt deleted file mode 100644 index 207a3fa5e..000000000 --- a/mods/HUD/mcl_inventory/description.txt +++ /dev/null @@ -1 +0,0 @@ -Adds the player inventory and creative inventory. diff --git a/mods/HUD/mcl_inventory/init.lua b/mods/HUD/mcl_inventory/init.lua index 60ed8ba50..054424051 100644 --- a/mods/HUD/mcl_inventory/init.lua +++ b/mods/HUD/mcl_inventory/init.lua @@ -65,7 +65,7 @@ local function set_inventory(player, armor_change_only) -- Show armor and player image local player_preview - if minetest.settings:get_bool("3d_player_preview") then + if minetest.settings:get_bool("3d_player_preview", true) then player_preview = mcl_player.get_player_formspec_model(player, 1.0, 0.0, 2.25, 4.5, "") else local img, img_player diff --git a/mods/HUD/mcl_inventory/mod.conf b/mods/HUD/mcl_inventory/mod.conf index 2900f85c5..fa6b2c2f4 100644 --- a/mods/HUD/mcl_inventory/mod.conf +++ b/mods/HUD/mcl_inventory/mod.conf @@ -1 +1,6 @@ name = mcl_inventory +author = BlockMen +description = Adds the player inventory and creative inventory. +depends = mcl_init, mcl_formspec +optional_depends = mcl_player, _mcl_autogroup, mcl_armor, mcl_brewing, mcl_potions, mcl_enchanting + diff --git a/mods/HUD/mcl_tmp_message/mod.conf b/mods/HUD/mcl_tmp_message/mod.conf new file mode 100644 index 000000000..ad453643e --- /dev/null +++ b/mods/HUD/mcl_tmp_message/mod.conf @@ -0,0 +1,3 @@ +name = mcl_tmp_message +author = Fleckenstein +description = A simple API to show a temporary message to a player diff --git a/mods/HUD/show_wielded_item/depends.txt b/mods/HUD/show_wielded_item/depends.txt deleted file mode 100644 index 3e1d5c201..000000000 --- a/mods/HUD/show_wielded_item/depends.txt +++ /dev/null @@ -1 +0,0 @@ -hudbars? diff --git a/mods/HUD/show_wielded_item/description.txt b/mods/HUD/show_wielded_item/description.txt deleted file mode 100644 index 361cab6ce..000000000 --- a/mods/HUD/show_wielded_item/description.txt +++ /dev/null @@ -1 +0,0 @@ -Displays the name of the wielded item. diff --git a/mods/HUD/show_wielded_item/mod.conf b/mods/HUD/show_wielded_item/mod.conf index fdedae0f7..50648dc6a 100644 --- a/mods/HUD/show_wielded_item/mod.conf +++ b/mods/HUD/show_wielded_item/mod.conf @@ -1 +1,4 @@ name = show_wielded_item +author = 4aiman +description = Displays the name of the wielded item. +optional_depends = hudbars diff --git a/mods/ITEMS/REDSTONE/mcl_comparators/init.lua b/mods/ITEMS/REDSTONE/mcl_comparators/init.lua index a8fab81d7..cd194b0d1 100644 --- a/mods/ITEMS/REDSTONE/mcl_comparators/init.lua +++ b/mods/ITEMS/REDSTONE/mcl_comparators/init.lua @@ -303,6 +303,7 @@ for _, state in pairs{mesecon.state.on, mesecon.state.off} do end minetest.register_node(nodename, nodedef) + mcl_wip.register_wip_item(nodename) end end diff --git a/mods/ITEMS/REDSTONE/mcl_comparators/mod.conf b/mods/ITEMS/REDSTONE/mcl_comparators/mod.conf index e0a6a9bbb..28d8926a0 100644 --- a/mods/ITEMS/REDSTONE/mcl_comparators/mod.conf +++ b/mods/ITEMS/REDSTONE/mcl_comparators/mod.conf @@ -1 +1,2 @@ name = mcl_comparators +depends = mcl_wip 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/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/mcl_anvils/depends.txt b/mods/ITEMS/mcl_anvils/depends.txt deleted file mode 100644 index 89b87aa2d..000000000 --- a/mods/ITEMS/mcl_anvils/depends.txt +++ /dev/null @@ -1,7 +0,0 @@ -mcl_init -mcl_formspec -mcl_sounds -mcl_core? -screwdriver? -tt -mcl_enchanting diff --git a/mods/ITEMS/mcl_anvils/init.lua b/mods/ITEMS/mcl_anvils/init.lua index 91f4eaa80..f95ddabac 100644 --- a/mods/ITEMS/mcl_anvils/init.lua +++ b/mods/ITEMS/mcl_anvils/init.lua @@ -101,14 +101,14 @@ local function update_anvil_slots(meta) end local can_combine = mcl_enchanting.combine(input1, input2) - + if can_combine then -- Add tool health together plus a small bonus if def1.type == "tool" and def2.type == "tool" then local new_wear = calculate_repair(input1:get_wear(), input2:get_wear(), SAME_TOOL_REPAIR_BOOST) input1:set_wear(new_wear) end - + name_item = input1 new_output = name_item -- Tool + repair item @@ -318,11 +318,11 @@ local anvildef = { _mcl_after_falling = damage_anvil_by_falling, after_dig_node = function(pos, oldnode, oldmetadata, digger) - local meta = minetest.get_meta(pos) - local meta2 = meta + local meta = minetest.get_meta(pos) + local meta2 = meta:to_table() meta:from_table(oldmetadata) drop_anvil_items(pos, meta) - meta:from_table(meta2:to_table()) + meta:from_table(meta2) end, allow_metadata_inventory_take = function(pos, listname, index, stack, player) local name = player:get_player_name() diff --git a/mods/ITEMS/mcl_anvils/mod.conf b/mods/ITEMS/mcl_anvils/mod.conf index 7712df190..cd4fa02a8 100644 --- a/mods/ITEMS/mcl_anvils/mod.conf +++ b/mods/ITEMS/mcl_anvils/mod.conf @@ -1 +1,5 @@ name = mcl_anvils +author = Wuzzy +description = Anvils mods for MCL2 +depends = mcl_init, mcl_formspec, mcl_sounds, tt, mcl_enchanting +optional_depends = mcl_core, screwdriver diff --git a/mods/ITEMS/mcl_armor/armor.lua b/mods/ITEMS/mcl_armor/armor.lua index aac3a0e2b..943f57e9d 100644 --- a/mods/ITEMS/mcl_armor/armor.lua +++ b/mods/ITEMS/mcl_armor/armor.lua @@ -151,8 +151,8 @@ armor.set_player_armor = function(self, player) if level then local texture = def.texture or item:gsub("%:", "_") local enchanted_addition = (mcl_enchanting.is_enchanted(item) and mcl_enchanting.overlay or "") - table.insert(textures, "("..texture..".png"..enchanted_addition..")") - preview = "(player.png^[opacity:0^"..texture.."_preview.png"..enchanted_addition..")"..(preview and "^"..preview or "") + table.insert(textures, texture..".png"..enchanted_addition) + preview = "player.png^[opacity:0^"..texture.."_preview.png"..enchanted_addition..""..(preview and "^"..preview or "") armor_level = armor_level + level items = items + 1 mcl_armor_points = mcl_armor_points + (def.groups["mcl_armor_points"] or 0) @@ -368,6 +368,35 @@ mcl_player.player_register_model("mcl_armor_character.b3d", { swim_mine = {x=411, y=430}, run_walk = {x=440, y=459}, run_walk_mine = {x=461, y=480}, + sit_mount = {x=484, y=484}, + }, +}) + +mcl_player.player_register_model("mcl_armor_character_female.b3d", { + animation_speed = 30, + textures = { + armor.default_skin..".png", + "blank.png", + "blank.png", + }, + animations = { + stand = {x=0, y=79}, + lay = {x=162, y=166}, + walk = {x=168, y=187}, + mine = {x=189, y=198}, + walk_mine = {x=200, y=219}, + sit = {x=81, y=160}, + sneak_stand = {x=222, y=302}, + sneak_mine = {x=346, y=365}, + sneak_walk = {x=304, y=323}, + sneak_walk_mine = {x=325, y=344}, + swim_walk = {x=368, y=387}, + swim_walk_mine = {x=389, y=408}, + swim_stand = {x=434, y=434}, + swim_mine = {x=411, y=430}, + run_walk = {x=440, y=459}, + run_walk_mine = {x=461, y=480}, + sit_mount = {x=484, y=484}, }, }) @@ -529,12 +558,7 @@ minetest.register_on_player_hpchange(function(player, hp_change, reason) return hp_change end - local regular_reduction = reason.type ~= "drown" and reason.type ~= "fall" - - -- Account for potion effects (armor doesn't save the target) - if reason.other == "poison" or reason.other == "harming" then - return hp_change - end + local regular_reduction = reason.type ~= "drown" and reason.type ~= "fall" and reason.other ~= "harming" and reason.other ~= "poison" local heal_max = 0 local items = 0 diff --git a/mods/ITEMS/mcl_armor/depends.txt b/mods/ITEMS/mcl_armor/depends.txt deleted file mode 100644 index 067cf61b1..000000000 --- a/mods/ITEMS/mcl_armor/depends.txt +++ /dev/null @@ -1,6 +0,0 @@ -mcl_core -mcl_player -mcl_fire? -ethereal? -bakedclay? -mcl_enchanting diff --git a/mods/ITEMS/mcl_armor/description.txt b/mods/ITEMS/mcl_armor/description.txt deleted file mode 100644 index b0a9b0a5a..000000000 --- a/mods/ITEMS/mcl_armor/description.txt +++ /dev/null @@ -1 +0,0 @@ -Adds craftable armor that is visible to other players. diff --git a/mods/ITEMS/mcl_armor/mod.conf b/mods/ITEMS/mcl_armor/mod.conf new file mode 100644 index 000000000..9264e8362 --- /dev/null +++ b/mods/ITEMS/mcl_armor/mod.conf @@ -0,0 +1,5 @@ +name = mcl_armor +author = stu +description = Adds craftable armor that is visible to other players. +depends = mcl_core, mcl_player, mcl_enchanting +optional_depends = mcl_fire, ethereal, bakedclay diff --git a/mods/ITEMS/mcl_armor/models/mcl_armor_character.b3d b/mods/ITEMS/mcl_armor/models/mcl_armor_character.b3d index 2f9426fc3..c6a1274c5 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 97b1bf08b..88db35cf5 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 new file mode 100644 index 000000000..cd2fca988 Binary files /dev/null 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 new file mode 100644 index 000000000..098417b42 Binary files /dev/null and b/mods/ITEMS/mcl_armor/models/mcl_armor_character_female.blend differ diff --git a/mods/ITEMS/mcl_armor_stand/depends.txt b/mods/ITEMS/mcl_armor_stand/depends.txt deleted file mode 100644 index 02ce27d73..000000000 --- a/mods/ITEMS/mcl_armor_stand/depends.txt +++ /dev/null @@ -1,5 +0,0 @@ -mcl_armor -mcl_core -mcl_sounds -mcl_stairs -screwdriver? diff --git a/mods/ITEMS/mcl_armor_stand/mod.conf b/mods/ITEMS/mcl_armor_stand/mod.conf new file mode 100644 index 000000000..eb803dc56 --- /dev/null +++ b/mods/ITEMS/mcl_armor_stand/mod.conf @@ -0,0 +1,5 @@ +name = mcl_armor_stand +author = stujones11 +description = Adds an armor stand for armor storage and display. +depends = mcl_armor, mcl_core, mcl_sounds, mcl_stairs +optional_depends = screwdriver diff --git a/mods/ITEMS/mcl_banners/depends.txt b/mods/ITEMS/mcl_banners/depends.txt deleted file mode 100644 index d7ac71050..000000000 --- a/mods/ITEMS/mcl_banners/depends.txt +++ /dev/null @@ -1,6 +0,0 @@ -mcl_sounds? -mcl_core? -mcl_wool? -mcl_cauldrons? -doc? -screwdriver? diff --git a/mods/ITEMS/mcl_banners/description.txt b/mods/ITEMS/mcl_banners/description.txt deleted file mode 100644 index 5e748a2ea..000000000 --- a/mods/ITEMS/mcl_banners/description.txt +++ /dev/null @@ -1 +0,0 @@ -Adds decorative banners in different colors which can be emblazoned with patterns, offering a countless number of combinations. diff --git a/mods/ITEMS/mcl_banners/mod.conf b/mods/ITEMS/mcl_banners/mod.conf index 211266581..cee7bace7 100644 --- a/mods/ITEMS/mcl_banners/mod.conf +++ b/mods/ITEMS/mcl_banners/mod.conf @@ -1 +1,4 @@ name = mcl_banners +author = 22i +description = Adds decorative banners in different colors which can be emblazoned with patterns, offering a countless number of combinations. +optional_depends = mcl_sounds, mcl_core, mcl_wool, mcl_cauldrons, doc, screwdriver diff --git a/mods/ITEMS/mcl_beds/depends.txt b/mods/ITEMS/mcl_beds/depends.txt deleted file mode 100644 index c7c874fd1..000000000 --- a/mods/ITEMS/mcl_beds/depends.txt +++ /dev/null @@ -1,9 +0,0 @@ -playerphysics -mcl_sounds? -mcl_worlds? -mcl_wool? -mcl_dye? -mcl_explosions? -mcl_weather? -mcl_spawn? -doc? diff --git a/mods/ITEMS/mcl_beds/functions.lua b/mods/ITEMS/mcl_beds/functions.lua index 8b1b82dfc..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 @@ -358,6 +357,7 @@ minetest.register_on_joinplayer(function(player) end) minetest.register_on_leaveplayer(function(player) + lay_down(player, nil, nil, false, true) local players = minetest.get_connected_players() local name = player:get_player_name() for n, player in ipairs(players) do diff --git a/mods/ITEMS/mcl_beds/mod.conf b/mods/ITEMS/mcl_beds/mod.conf index 62645f3b4..c3378d1f0 100644 --- a/mods/ITEMS/mcl_beds/mod.conf +++ b/mods/ITEMS/mcl_beds/mod.conf @@ -1 +1,5 @@ name = mcl_beds +author = BlockMen +description = +depends = playerphysics +optional_depends = mcl_sounds, mcl_worlds, mcl_wool, mcl_dye, mcl_explosions, mcl_weather, mcl_spawn, doc diff --git a/mods/ITEMS/mcl_books/depends.txt b/mods/ITEMS/mcl_books/depends.txt deleted file mode 100644 index e1ecc48c7..000000000 --- a/mods/ITEMS/mcl_books/depends.txt +++ /dev/null @@ -1,5 +0,0 @@ -mcl_init? -mcl_core? -mcl_sounds? -mcl_mobitems? -mcl_dye? diff --git a/mods/ITEMS/mcl_books/mod.conf b/mods/ITEMS/mcl_books/mod.conf index 9597005c1..7c4513b00 100644 --- a/mods/ITEMS/mcl_books/mod.conf +++ b/mods/ITEMS/mcl_books/mod.conf @@ -1 +1,4 @@ name = mcl_books +author = celeron55 +description = Books mod for MCL2 +optional_depends = mcl_init, mcl_core, mcl_sounds, mcl_mobitems, mcl_dye diff --git a/mods/ITEMS/mcl_bows/arrow.lua b/mods/ITEMS/mcl_bows/arrow.lua index ba9158078..61cb26f33 100644 --- a/mods/ITEMS/mcl_bows/arrow.lua +++ b/mods/ITEMS/mcl_bows/arrow.lua @@ -15,6 +15,26 @@ local dir_to_pitch = function(dir) return -math.atan2(-dir.y, xz) end +local random_arrow_positions = function(positions, placement) + local min = 0 + local max = 0 + if positions == 'x' then + min = -4 + max = 4 + elseif positions == 'y' then + min = 0 + max = 10 + end + if placement == 'front' and positions == 'z' then + min = 3 + max = 3 + elseif placement == 'back' and positions == 'z' then + min = -3 + max = -3 + end + return math.random(max, min) +end + local mod_awards = minetest.get_modpath("awards") and minetest.get_modpath("mcl_achievements") local mod_button = minetest.get_modpath("mesecons_button") @@ -35,53 +55,13 @@ S("Arrows might get stuck on solid blocks and can be retrieved again. They are a end, }) --- This is a fake node, used as model for the arrow entity. --- It's not supposed to be usable as item or real node. --- TODO: Use a proper mesh for the arrow entity -minetest.register_node("mcl_bows:arrow_box", { - drawtype = "nodebox", - is_ground_content = false, - node_box = { - type = "fixed", - fixed = { - -- Shaft - {-6.5/17, -1.5/17, -1.5/17, -4.5/17, 1.5/17, 1.5/17}, - {-4.5/17, -0.5/17, -0.5/17, 5.5/17, 0.5/17, 0.5/17}, - {5.5/17, -1.5/17, -1.5/17, 6.5/17, 1.5/17, 1.5/17}, - -- Tip - {-4.5/17, 2.5/17, 2.5/17, -3.5/17, -2.5/17, -2.5/17}, - {-8.5/17, 0.5/17, 0.5/17, -6.5/17, -0.5/17, -0.5/17}, - -- Fletching - {6.5/17, 1.5/17, 1.5/17, 7.5/17, 2.5/17, 2.5/17}, - {7.5/17, -2.5/17, 2.5/17, 6.5/17, -1.5/17, 1.5/17}, - {7.5/17, 2.5/17, -2.5/17, 6.5/17, 1.5/17, -1.5/17}, - {6.5/17, -1.5/17, -1.5/17, 7.5/17, -2.5/17, -2.5/17}, - - {7.5/17, 2.5/17, 2.5/17, 8.5/17, 3.5/17, 3.5/17}, - {8.5/17, -3.5/17, 3.5/17, 7.5/17, -2.5/17, 2.5/17}, - {8.5/17, 3.5/17, -3.5/17, 7.5/17, 2.5/17, -2.5/17}, - {7.5/17, -2.5/17, -2.5/17, 8.5/17, -3.5/17, -3.5/17}, - } - }, - tiles = {"mcl_bows_arrow.png^[transformFX", "mcl_bows_arrow.png^[transformFX", "mcl_bows_arrow_back.png", "mcl_bows_arrow_front.png", "mcl_bows_arrow.png", "mcl_bows_arrow.png^[transformFX"}, - use_texture_alpha = minetest.features.use_texture_alpha_string_modes and "opaque" or false, - paramtype = "light", - paramtype2 = "facedir", - sunlight_propagates = true, - groups = {not_in_creative_inventory=1, dig_immediate=3}, - drop = "", - node_placement_prediction = "", - on_construct = function(pos) - minetest.log("error", "[mcl_bows] Trying to construct mcl_bows:arrow_box at "..minetest.pos_to_string(pos)) - minetest.remove_node(pos) - end, -}) - local ARROW_ENTITY={ physical = true, - visual = "wielditem", - visual_size = {x=0.4, y=0.4}, - textures = {"mcl_bows:arrow_box"}, + pointable = false, + visual = "mesh", + mesh = "mcl_bows_arrow.obj", + visual_size = {x=-1, y=1}, + textures = {"mcl_bows_arrow.png"}, collisionbox = {-0.19, -0.125, -0.19, 0.19, 0.125, 0.19}, collide_with_objects = false, _fire_damage_resistant = true, @@ -136,11 +116,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 @@ -185,6 +177,25 @@ 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 and self._in_player == false then + minetest.add_particlespawner({ + amount = 1, + time = .001, + minpos = pos, + maxpos = pos, + minvel = vector.new(-0.1,-0.1,-0.1), + maxvel = vector.new(0.1,0.1,0.1), + minexptime = 0.5, + maxexptime = 0.5, + minsize = 2, + maxsize = 2, + collisiondetection = false, + vertical = false, + texture = "mobs_mc_arrow_particle.png", + glow = 1, + }) + end -- We just check for any hurtable objects nearby. -- The radius of 3 is fairly liberal, but anything lower than than will cause -- arrow to hilariously go through mobs often. @@ -201,10 +212,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 @@ -222,11 +233,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) @@ -251,19 +263,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 mcl_burning.is_burning(self.object) then - mcl_burning.set_on_fire(obj, 5, 1, 5 / 4) + 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 + 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 - obj:punch(self.object, 1.0, { - full_punch_interval=1.0, - damage_groups={fleshy=self._damage}, - }, self.object:get_velocity()) 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 @@ -280,10 +333,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 mcl_burning.extinguish(self.object) - self.object:remove() + if not obj:is_player() then + self.object:remove() + end return end end @@ -410,6 +467,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/depends.txt b/mods/ITEMS/mcl_bows/depends.txt deleted file mode 100644 index a797e7184..000000000 --- a/mods/ITEMS/mcl_bows/depends.txt +++ /dev/null @@ -1,11 +0,0 @@ -controls -awards? -mcl_achievements? -mcl_core? -mcl_mobitems? -playerphysics? -doc? -doc_identifier? -mesecons_button? -mcl_particles -mcl_enchanting diff --git a/mods/ITEMS/mcl_bows/mod.conf b/mods/ITEMS/mcl_bows/mod.conf new file mode 100644 index 000000000..cfb423474 --- /dev/null +++ b/mods/ITEMS/mcl_bows/mod.conf @@ -0,0 +1,6 @@ +name = mcl_bows +author = Arcelmi +description = This mod adds bows and arrows for MineClone 2. +depends = controls, mcl_particles, mcl_enchanting +optional_depends = awards, mcl_achievements, mcl_core, mcl_mobitems, playerphysics, doc, doc_identifier, mesecons_button + diff --git a/mods/ITEMS/mcl_bows/models/mcl_bows_arrow.obj b/mods/ITEMS/mcl_bows/models/mcl_bows_arrow.obj new file mode 100644 index 000000000..8530efa78 --- /dev/null +++ b/mods/ITEMS/mcl_bows/models/mcl_bows_arrow.obj @@ -0,0 +1,56 @@ +# Blender v2.91.0 OBJ File: '' +# www.blender.org +mtllib mcl_bows_arrow.mtl +o Plane +v -3.782006 -1.443249 0.000500 +v -3.782006 1.444249 0.000500 +v 3.782006 1.444249 0.000500 +v 3.782006 -1.443249 0.000500 +v 3.331104 1.069925 1.085017 +v 3.331104 -1.100076 1.085017 +v 3.331104 1.069925 -1.064830 +v 3.331104 -1.100076 -1.064829 +v 3.782006 0.001000 1.443749 +v 3.782006 0.001000 -1.443750 +v -3.782006 0.001000 -1.443749 +v -3.782006 0.001000 1.443750 +v 3.782006 0.000000 -1.443750 +v 3.782006 0.000000 1.443749 +v -3.782006 0.000000 1.443750 +v -3.782006 0.000000 -1.443749 +v 3.782006 1.444249 -0.000500 +v 3.782006 -1.443249 -0.000500 +v -3.782006 -1.443249 -0.000500 +v -3.782006 1.444249 -0.000500 +vt 0.000000 0.300000 +vt 0.000000 0.700000 +vt 1.000000 0.700000 +vt 1.000000 0.300000 +vt -0.007553 -0.000373 +vt 0.296712 -0.000373 +vt 0.296712 0.298611 +vt -0.007553 0.298611 +vt 0.000000 0.300000 +vt 1.000000 0.300000 +vt 1.000000 0.700000 +vt 0.000000 0.700000 +vt 0.000000 0.300000 +vt 1.000000 0.300000 +vt 1.000000 0.700000 +vt 0.000000 0.700000 +vt 0.000000 0.300000 +vt 0.000000 0.700000 +vt 1.000000 0.700000 +vt 1.000000 0.300000 +vn -0.0000 -0.0000 -1.0000 +vn 1.0000 -0.0000 0.0000 +vn 0.0000 1.0000 0.0000 +vn 0.0000 0.0000 1.0000 +vn 0.0000 -1.0000 0.0000 +usemtl Material.002 +s off +f 17/1/1 18/2/1 19/3/1 20/4/1 +f 8/5/2 7/6/2 5/7/2 6/8/2 +f 10/9/3 11/10/3 12/11/3 9/12/3 +f 3/13/4 2/14/4 1/15/4 4/16/4 +f 13/17/5 14/18/5 15/19/5 16/20/5 diff --git a/mods/ITEMS/mcl_bows/textures/mcl_bows_arrow.png b/mods/ITEMS/mcl_bows/textures/mcl_bows_arrow.png index 278d910f2..244405288 100644 Binary files a/mods/ITEMS/mcl_bows/textures/mcl_bows_arrow.png and b/mods/ITEMS/mcl_bows/textures/mcl_bows_arrow.png differ diff --git a/mods/ITEMS/mcl_bows/textures/mcl_bows_arrow_back.png b/mods/ITEMS/mcl_bows/textures/mcl_bows_arrow_back.png index 18164e90a..4fa82ce26 100644 Binary files a/mods/ITEMS/mcl_bows/textures/mcl_bows_arrow_back.png and b/mods/ITEMS/mcl_bows/textures/mcl_bows_arrow_back.png differ diff --git a/mods/ITEMS/mcl_bows/textures/mcl_bows_arrow_overlay.png b/mods/ITEMS/mcl_bows/textures/mcl_bows_arrow_overlay.png index 2ca26c58a..a043eb37e 100644 Binary files a/mods/ITEMS/mcl_bows/textures/mcl_bows_arrow_overlay.png and b/mods/ITEMS/mcl_bows/textures/mcl_bows_arrow_overlay.png differ diff --git a/mods/ITEMS/mcl_brewing/mod.conf b/mods/ITEMS/mcl_brewing/mod.conf index 28df9cf42..2c27c979e 100644 --- a/mods/ITEMS/mcl_brewing/mod.conf +++ b/mods/ITEMS/mcl_brewing/mod.conf @@ -1,3 +1,4 @@ name = mcl_brewing +author = bzoss depends = mcl_init, mcl_formspec, mcl_sounds, mcl_potions, mcl_mobitems optional_depends = mcl_core, doc, screwdriver diff --git a/mods/ITEMS/mcl_buckets/API.md b/mods/ITEMS/mcl_buckets/API.md new file mode 100644 index 000000000..69ee4b21d --- /dev/null +++ b/mods/ITEMS/mcl_buckets/API.md @@ -0,0 +1,21 @@ +# mcl_buckets +Add an API to register buckets to mcl + +## mcl_buckets.register_liquid(def) + +Register a new liquid +Accept folowing params: +* 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 + +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/depends.txt b/mods/ITEMS/mcl_buckets/depends.txt deleted file mode 100644 index eb9bca8d8..000000000 --- a/mods/ITEMS/mcl_buckets/depends.txt +++ /dev/null @@ -1,4 +0,0 @@ -mcl_worlds -mcl_core? -mclx_core? -doc? diff --git a/mods/ITEMS/mcl_buckets/init.lua b/mods/ITEMS/mcl_buckets/init.lua index 3a06272b3..30e4075c8 100644 --- a/mods/ITEMS/mcl_buckets/init.lua +++ b/mods/ITEMS/mcl_buckets/init.lua @@ -1,4 +1,5 @@ local S = minetest.get_translator("mcl_buckets") +local modpath = minetest.get_modpath(minetest.get_current_modname()) -- Minetest 0.4 mod: bucket -- See README.txt for licensing and other information. @@ -45,43 +46,27 @@ local place_liquid = function(pos, itemstring) minetest.add_node(pos, {name=itemstring, param2=fullness}) end --- Register a new liquid --- 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 --- --- This function can be called from any mod (which depends on this one) -function mcl_buckets.register_liquid(source_place, source_take, itemname, inventory_image, name, longdesc, usagehelp, tt_help, extra_check, groups) - for i=1, #source_take do - mcl_buckets.liquids[source_take[i]] = { - source_place = source_place, - source_take = source_take[i], - itemname = itemname, +function mcl_buckets.register_liquid(def) + for i=1, #def.source_take do + mcl_buckets.liquids[def.source_take[i]] = { + source_place = def.source_place, + source_take = def.source_take[i], + itemname = def.itemname, } - if type(source_place) == "string" then - mcl_buckets.liquids[source_place] = mcl_buckets.liquids[source_take[i]] + if type(def.source_place) == "string" then + mcl_buckets.liquids[def.source_place] = mcl_buckets.liquids[def.source_take[i]] end end - if itemname ~= nil then - minetest.register_craftitem(itemname, { - description = name, - _doc_items_longdesc = longdesc, - _doc_items_usagehelp = usagehelp, - _tt_help = tt_help, - inventory_image = inventory_image, - stack_max = 16, - groups = groups, + if def.itemname ~= nil then + minetest.register_craftitem(def.itemname, { + description = def.name, + _doc_items_longdesc = def.longdesc, + _doc_items_usagehelp = def.usagehelp, + _tt_help = def.tt_help, + inventory_image = def.inventory_image, + stack_max = 1, + groups = def.groups, on_place = function(itemstack, user, pointed_thing) -- Must be pointing to node if pointed_thing.type ~= "node" then @@ -99,15 +84,15 @@ function mcl_buckets.register_liquid(source_place, source_take, itemname, invent end local node_place - if type(source_place) == "function" then - node_place = source_place(place_pos) + if type(def.source_place) == "function" then + node_place = def.source_place(place_pos) else - node_place = source_place + node_place = def.source_place end -- 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 @@ -163,17 +148,17 @@ function mcl_buckets.register_liquid(source_place, source_take, itemname, invent end, _on_dispense = function(stack, pos, droppos, dropnode, dropdir) local iname = stack:get_name() - local buildable = minetest.registered_nodes[dropnode.name].buildable_to + local buildable = minetest.registered_nodes[dropnode.name].buildable_to or dropnode.name == "mcl_portals:portal" - if extra_check and extra_check(droppos, nil) == false then + if def.extra_check and def.extra_check(droppos, nil) == false then -- Fail placement of liquid elseif buildable then -- buildable; replace the node local node_place - if type(source_place) == "function" then - node_place = source_place(droppos) + if type(def.source_place) == "function" then + node_place = def.source_place(droppos) else - node_place = source_place + node_place = def.source_place end place_liquid(droppos, node_place) stack:set_name("mcl_buckets:bucket_empty") @@ -292,114 +277,4 @@ minetest.register_craftitem("mcl_buckets:bucket_empty", { end, }) -if mod_mcl_core then - -- Lava bucket - mcl_buckets.register_liquid( - function(pos) - local dim = mcl_worlds.pos_to_dimension(pos) - if dim == "nether" then - return "mcl_nether:nether_lava_source" - else - return "mcl_core:lava_source" - end - end, - {"mcl_core:lava_source", "mcl_nether:nether_lava_source"}, - "mcl_buckets:bucket_lava", - "bucket_lava.png", - S("Lava Bucket"), - S("A bucket can be used to collect and release liquids. This one is filled with hot lava, safely contained inside. Use with caution."), - S("Get in a safe distance and place the bucket to empty it and create a lava source at this spot. Don't burn yourself!"), - S("Places a lava source") - ) - - -- Water bucket - mcl_buckets.register_liquid( - "mcl_core:water_source", - {"mcl_core:water_source"}, - "mcl_buckets:bucket_water", - "bucket_water.png", - S("Water Bucket"), - S("A bucket can be used to collect and release liquids. This one is filled with water."), - S("Place it to empty the bucket and create a water source."), - S("Places a water source"), - function(pos, placer) - -- Check protection - local placer_name = "" - if placer ~= nil then - placer_name = placer:get_player_name() - end - if placer and minetest.is_protected(pos, placer_name) then - minetest.record_protection_violation(pos, placer_name) - return false - end - local nn = minetest.get_node(pos).name - -- Pour water into cauldron - if minetest.get_item_group(nn, "cauldron") ~= 0 then - -- Put water into cauldron - if nn ~= "mcl_cauldrons:cauldron_3" then - minetest.set_node(pos, {name="mcl_cauldrons:cauldron_3"}) - end - sound_place("mcl_core:water_source", pos) - return false - -- Evaporate water if used in Nether (except on cauldron) - else - local dim = mcl_worlds.pos_to_dimension(pos) - if dim == "nether" then - minetest.sound_play("fire_extinguish_flame", {pos = pos, gain = 0.25, max_hear_distance = 16}, true) - return false - end - end - end, - { water_bucket = 1 } - ) -end - -if mod_mclx_core then - -- River water bucket - mcl_buckets.register_liquid( - "mclx_core:river_water_source", - {"mclx_core:river_water_source"}, - "mcl_buckets:bucket_river_water", - "bucket_river_water.png", - S("River Water Bucket"), - S("A bucket can be used to collect and release liquids. This one is filled with river water."), - S("Place it to empty the bucket and create a river water source."), - S("Places a river water source"), - function(pos, placer) - -- Check protection - local placer_name = "" - if placer ~= nil then - placer_name = placer:get_player_name() - end - if placer and minetest.is_protected(pos, placer_name) then - minetest.record_protection_violation(pos, placer_name) - return false - end - local nn = minetest.get_node(pos).name - -- Pour into cauldron - if minetest.get_item_group(nn, "cauldron") ~= 0 then - -- Put water into cauldron - if nn ~= "mcl_cauldrons:cauldron_3r" then - minetest.set_node(pos, {name="mcl_cauldrons:cauldron_3r"}) - end - sound_place("mcl_core:water_source", pos) - return false - else - -- Evaporate water if used in Nether (except on cauldron) - local dim = mcl_worlds.pos_to_dimension(pos) - if dim == "nether" then - minetest.sound_play("fire_extinguish_flame", {pos = pos, gain = 0.25, max_hear_distance = 16}, true) - return false - end - end - end, - { water_bucket = 1 } - ) -end - -minetest.register_craft({ - type = "fuel", - recipe = "mcl_buckets:bucket_lava", - burntime = 1000, - replacements = {{"mcl_buckets:bucket_lava", "mcl_buckets:bucket_empty"}}, -}) +dofile(modpath.."/register.lua") diff --git a/mods/ITEMS/mcl_buckets/mod.conf b/mods/ITEMS/mcl_buckets/mod.conf new file mode 100644 index 000000000..5a78e70ad --- /dev/null +++ b/mods/ITEMS/mcl_buckets/mod.conf @@ -0,0 +1,6 @@ +name = mcl_buckets +author = Kahrl +description = +depends = mcl_worlds +optional_depends = mcl_core, mclx_core, doc + diff --git a/mods/ITEMS/mcl_buckets/register.lua b/mods/ITEMS/mcl_buckets/register.lua new file mode 100644 index 000000000..b5d86ac0e --- /dev/null +++ b/mods/ITEMS/mcl_buckets/register.lua @@ -0,0 +1,129 @@ +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({ + source_place = function(pos) + local dim = mcl_worlds.pos_to_dimension(pos) + if dim == "nether" then + return "mcl_nether:nether_lava_source" + else + return "mcl_core:lava_source" + end + end, + source_take = {"mcl_core:lava_source", "mcl_nether:nether_lava_source"}, + itemname = "mcl_buckets:bucket_lava", + inventory_image = "bucket_lava.png", + name = S("Lava Bucket"), + longdesc = S("A bucket can be used to collect and release liquids. This one is filled with hot lava, safely contained inside. Use with caution."), + usagehelp = S("Get in a safe distance and place the bucket to empty it and create a lava source at this spot. Don't burn yourself!"), + tt_help = S("Places a lava source") + }) + + -- Water bucket + mcl_buckets.register_liquid({ + source_place = "mcl_core:water_source", + source_take = {"mcl_core:water_source"}, + itemname = "mcl_buckets:bucket_water", + inventory_image = "bucket_water.png", + name = S("Water Bucket"), + longdesc = S("A bucket can be used to collect and release liquids. This one is filled with water."), + usagehelp = S("Place it to empty the bucket and create a water source."), + tt_help = S("Places a water source"), + extra_check = function(pos, placer) + -- Check protection + local placer_name = "" + if placer ~= nil then + placer_name = placer:get_player_name() + end + if placer and minetest.is_protected(pos, placer_name) then + minetest.record_protection_violation(pos, placer_name) + return false + end + local nn = minetest.get_node(pos).name + -- Pour water into cauldron + if minetest.get_item_group(nn, "cauldron") ~= 0 then + -- Put water into cauldron + if nn ~= "mcl_cauldrons:cauldron_3" then + minetest.set_node(pos, {name="mcl_cauldrons:cauldron_3"}) + end + sound_place("mcl_core:water_source", pos) + return false + -- Evaporate water if used in Nether (except on cauldron) + else + local dim = mcl_worlds.pos_to_dimension(pos) + if dim == "nether" then + minetest.sound_play("fire_extinguish_flame", {pos = pos, gain = 0.25, max_hear_distance = 16}, true) + return false + end + end + end, + groups = { water_bucket = 1 }, + }) +end + +if mod_mclx_core then + -- River water bucket + mcl_buckets.register_liquid({ + source_place = "mclx_core:river_water_source", + source_take = {"mclx_core:river_water_source"}, + itemname = "mcl_buckets:bucket_river_water", + inventory_image = "bucket_river_water.png", + name = S("River Water Bucket"), + longdesc = S("A bucket can be used to collect and release liquids. This one is filled with river water."), + usagehelp = S("Place it to empty the bucket and create a river water source."), + tt_help = S("Places a river water source"), + extra_check = function(pos, placer) + -- Check protection + local placer_name = "" + if placer ~= nil then + placer_name = placer:get_player_name() + end + if placer and minetest.is_protected(pos, placer_name) then + minetest.record_protection_violation(pos, placer_name) + return false + end + local nn = minetest.get_node(pos).name + -- Pour into cauldron + if minetest.get_item_group(nn, "cauldron") ~= 0 then + -- Put water into cauldron + if nn ~= "mcl_cauldrons:cauldron_3r" then + minetest.set_node(pos, {name="mcl_cauldrons:cauldron_3r"}) + end + sound_place("mcl_core:water_source", pos) + return false + else + -- Evaporate water if used in Nether (except on cauldron) + local dim = mcl_worlds.pos_to_dimension(pos) + if dim == "nether" then + minetest.sound_play("fire_extinguish_flame", {pos = pos, gain = 0.25, max_hear_distance = 16}, true) + return false + end + end + end, + groups = { water_bucket = 1 }, + }) +end + +minetest.register_craft({ + type = "fuel", + recipe = "mcl_buckets:bucket_lava", + burntime = 1000, + replacements = {{"mcl_buckets:bucket_lava", "mcl_buckets:bucket_empty"}}, +}) diff --git a/mods/ITEMS/mcl_cake/depends.txt b/mods/ITEMS/mcl_cake/depends.txt deleted file mode 100644 index 1ed0ada15..000000000 --- a/mods/ITEMS/mcl_cake/depends.txt +++ /dev/null @@ -1,7 +0,0 @@ -mcl_core -mcl_sounds -mcl_hunger -mcl_buckets -mcl_farming -mcl_mobitems -doc? diff --git a/mods/ITEMS/mcl_cake/mod.conf b/mods/ITEMS/mcl_cake/mod.conf index 2a76657f5..e7260468e 100644 --- a/mods/ITEMS/mcl_cake/mod.conf +++ b/mods/ITEMS/mcl_cake/mod.conf @@ -1 +1,4 @@ name = mcl_cake +description = Add cakes to mcl +depends = mcl_core, mcl_sounds, mcl_hunger, mcl_buckets, mcl_farming, mcl_mobitems +optional_depends = 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_chests/init.lua b/mods/ITEMS/mcl_chests/init.lua index 852a47fec..fb8c59f28 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 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_cocoas/depends.txt b/mods/ITEMS/mcl_cocoas/depends.txt deleted file mode 100644 index 812afabce..000000000 --- a/mods/ITEMS/mcl_cocoas/depends.txt +++ /dev/null @@ -1,3 +0,0 @@ -mcl_sounds -mcl_core -doc? diff --git a/mods/ITEMS/mcl_cocoas/description.txt b/mods/ITEMS/mcl_cocoas/description.txt deleted file mode 100644 index 1af5d7ce0..000000000 --- a/mods/ITEMS/mcl_cocoas/description.txt +++ /dev/null @@ -1 +0,0 @@ -Cocoa pods which grow at jungle trees. Does not include cocoa beans. diff --git a/mods/ITEMS/mcl_cocoas/init.lua b/mods/ITEMS/mcl_cocoas/init.lua index 4395b7779..d0d96b300 100644 --- a/mods/ITEMS/mcl_cocoas/init.lua +++ b/mods/ITEMS/mcl_cocoas/init.lua @@ -3,10 +3,7 @@ local S = minetest.get_translator("mcl_cocoas") mcl_cocoas = {} -- Place cocoa -function mcl_cocoas.place(itemstack, placer, pointed_thing, plantname) - - local pt = pointed_thing - +function mcl_cocoas.place(itemstack, placer, pt, plantname) -- check if pointing at a node if not pt or pt.type ~= "node" then return diff --git a/mods/ITEMS/mcl_cocoas/mod.conf b/mods/ITEMS/mcl_cocoas/mod.conf index 923ea9785..867636191 100644 --- a/mods/ITEMS/mcl_cocoas/mod.conf +++ b/mods/ITEMS/mcl_cocoas/mod.conf @@ -1 +1,4 @@ name = mcl_cocoas +description = Cocoa pods which grow at jungle trees. Does not include cocoa beans. +depends = mcl_sounds, mcl_core +optional_depends = doc \ No newline at end of file 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_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/locale/mcl_core.fr.tr b/mods/ITEMS/mcl_core/locale/mcl_core.fr.tr index 4d97fe223..86bc489cd 100644 --- a/mods/ITEMS/mcl_core/locale/mcl_core.fr.tr +++ b/mods/ITEMS/mcl_core/locale/mcl_core.fr.tr @@ -84,7 +84,7 @@ Dark oak leaves are grown from dark oak trees.=Les feuilles de chêne noir sont Dark oak saplings can grow into dark oaks, but only in groups. A lonely dark oak sapling won't grow. A group of four dark oak saplings grows into a dark oak after some time when they are placed on soil (such as dirt) in a 2×2 square and exposed to light.=Les pousses de chêne noir peuvent devenir des chênes noirs, mais seulement en groupes. Une pousse de chêne noir solitaire ne poussera pas. Un groupe de quatre pousses de chêne noir se transforme en chêne noir après un certain temps lorsqu'ils sont placés sur le sol (comme la terre) dans un carré 2×2 et exposés à la lumière. Dead Bush=Arbuste mort Dead bushes are unremarkable plants often found in dry areas. They can be harvested for sticks.=Les buissons morts sont des plantes inhabituelles que l'on trouve souvent dans les zones sèches. Ils peuvent être récoltés avec des bâtons. -Diamond=Diamamnt +Diamond=Diamant Diamond Ore=Minerai de Diamant Diamond ore is rare and can be found in clusters near the bottom of the world.=Le minerai de diamant est rare et peut être trouvé en filons près du fond du monde. Diamonds are precious minerals and useful to create the highest tier of armor and tools.=Les diamants sont des minéraux précieux et utiles pour créer le plus haut niveau d'armure et d'outils. diff --git a/mods/ITEMS/mcl_core/mod.conf b/mods/ITEMS/mcl_core/mod.conf index 575c46655..9227d607e 100644 --- a/mods/ITEMS/mcl_core/mod.conf +++ b/mods/ITEMS/mcl_core/mod.conf @@ -1 +1 @@ -name = mcl_core +name = mcl_core \ No newline at end of file diff --git a/mods/ITEMS/mcl_core/textures/default_diamond.png b/mods/ITEMS/mcl_core/textures/default_diamond.png index 9016a8194..69db99dd1 100644 Binary files a/mods/ITEMS/mcl_core/textures/default_diamond.png and b/mods/ITEMS/mcl_core/textures/default_diamond.png differ diff --git a/mods/ITEMS/mcl_core/textures/default_water_flowing_animated.png b/mods/ITEMS/mcl_core/textures/default_water_flowing_animated.png index 1ad7aeb31..7c2ffaba1 100644 Binary files a/mods/ITEMS/mcl_core/textures/default_water_flowing_animated.png and b/mods/ITEMS/mcl_core/textures/default_water_flowing_animated.png differ diff --git a/mods/ITEMS/mcl_core/textures/mcl_core_emerald.png b/mods/ITEMS/mcl_core/textures/mcl_core_emerald.png index 7c196ad0e..9b3fd263b 100644 Binary files a/mods/ITEMS/mcl_core/textures/mcl_core_emerald.png and b/mods/ITEMS/mcl_core/textures/mcl_core_emerald.png differ diff --git a/mods/ITEMS/mcl_crafting_table/depends.txt b/mods/ITEMS/mcl_crafting_table/depends.txt deleted file mode 100644 index 97aafc582..000000000 --- a/mods/ITEMS/mcl_crafting_table/depends.txt +++ /dev/null @@ -1,3 +0,0 @@ -mcl_init -mcl_formspec -mcl_sounds diff --git a/mods/ITEMS/mcl_crafting_table/description.txt b/mods/ITEMS/mcl_crafting_table/description.txt deleted file mode 100644 index 5f2a79786..000000000 --- a/mods/ITEMS/mcl_crafting_table/description.txt +++ /dev/null @@ -1 +0,0 @@ -Adds a crafting table. diff --git a/mods/ITEMS/mcl_crafting_table/init.lua b/mods/ITEMS/mcl_crafting_table/init.lua index 09c4838cd..4ad581774 100644 --- a/mods/ITEMS/mcl_crafting_table/init.lua +++ b/mods/ITEMS/mcl_crafting_table/init.lua @@ -1,5 +1,36 @@ 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 itemslot_bg = mcl_formspec.get_itemslot_bg +mcl_crafting_table = {} +function mcl_crafting_table.show_crafting_form(player) + player:get_inventory():set_width("craft", 3) + player:get_inventory():set_size("craft", 9) + + 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" + "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;]".. + itemslot_bg(0,7.74,9,1).. + "label[1.75,0;"..formspec_escape(C(text_color, S("Crafting"))).."]".. + "list[current_player;craft;1.75,0.5;3,3;]".. + itemslot_bg(1.75,0.5,3,3).. + "list[current_player;craftpreview;6.1,1.5;1,1;]".. + itemslot_bg(6.1,1.5,1,1).. + "image_button[0.75,1.5;1,1;craftguide_book.png;__mcl_craftguide;]".. + "tooltip[__mcl_craftguide;"..formspec_escape(S("Recipe book")).."]".. + "listring[current_player;main]".. + "listring[current_player;craft]" + ) +end + +local show_crafting_form = mcl_crafting_table.show_crafting_form --cache function for better performances minetest.register_node("mcl_crafting_table:crafting_table", { description = S("Crafting Table"), _tt_help = S("3×3 crafting grid"), @@ -12,27 +43,7 @@ minetest.register_node("mcl_crafting_table:crafting_table", { paramtype2 = "facedir", groups = {handy=1,axey=1, deco_block=1, material_wood=1,flammable=-1}, on_rightclick = function(pos, node, player, itemstack) - player:get_inventory():set_width("craft", 3) - player:get_inventory():set_size("craft", 9) - - local form = "size[9,8.75]".. - "image[4.7,1.5;1.5,1;gui_crafting_arrow.png]".. - "label[0,4;"..minetest.formspec_escape(minetest.colorize("#313131", 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[1.75,0;"..minetest.formspec_escape(minetest.colorize("#313131", S("Crafting"))).."]".. - "list[current_player;craft;1.75,0.5;3,3;]".. - mcl_formspec.get_itemslot_bg(1.75,0.5,3,3).. - "list[current_player;craftpreview;6.1,1.5;1,1;]".. - mcl_formspec.get_itemslot_bg(6.1,1.5,1,1).. - "image_button[0.75,1.5;1,1;craftguide_book.png;__mcl_craftguide;]".. - "tooltip[__mcl_craftguide;"..minetest.formspec_escape(S("Recipe book")).."]".. - "listring[current_player;main]".. - "listring[current_player;craft]" - - minetest.show_formspec(player:get_player_name(), "main", form) + show_crafting_form(player) end, sounds = mcl_sounds.node_sound_wood_defaults(), _mcl_blast_resistance = 2.5, diff --git a/mods/ITEMS/mcl_crafting_table/mod.conf b/mods/ITEMS/mcl_crafting_table/mod.conf index db5ab14a1..03b3174ab 100644 --- a/mods/ITEMS/mcl_crafting_table/mod.conf +++ b/mods/ITEMS/mcl_crafting_table/mod.conf @@ -1 +1,4 @@ name = mcl_crafting_table +description = Adds a crafting table. +depends = mcl_init, mcl_formspec, mcl_sounds +optional_depends = 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_dye/init.lua b/mods/ITEMS/mcl_dye/init.lua index e84e75d91..2897e96ec 100644 --- a/mods/ITEMS/mcl_dye/init.lua +++ b/mods/ITEMS/mcl_dye/init.lua @@ -356,6 +356,7 @@ minetest.register_craftitem("mcl_dye:white", { end return stack end, + _dispense_into_walkable = true }) minetest.register_craftitem("mcl_dye:brown", { diff --git a/mods/ITEMS/mcl_enchanting/enchantments.lua b/mods/ITEMS/mcl_enchanting/enchantments.lua index 203c403d0..893ce58d4 100644 --- a/mods/ITEMS/mcl_enchanting/enchantments.lua +++ b/mods/ITEMS/mcl_enchanting/enchantments.lua @@ -124,8 +124,8 @@ mcl_enchanting.enchantments.curse_of_vanishing = { inv_tool_tab = true, } --- unimplemented ---[[mcl_enchanting.enchantments.depth_strider = { +-- implemented in mcl_playerplus +mcl_enchanting.enchantments.depth_strider = { name = S("Depth Strider"), max_level = 3, primary = {}, @@ -141,7 +141,7 @@ mcl_enchanting.enchantments.curse_of_vanishing = { power_range_table = {{10, 25}, {20, 35}, {30, 45}}, inv_combat_tab = true, inv_tool_tab = false, -}]]-- +} -- implemented via on_enchant mcl_enchanting.enchantments.efficiency = { @@ -215,8 +215,7 @@ minetest.register_on_punchplayer(function(player, hitter, time_from_last_punch, if wielditem then local fire_aspect_level = mcl_enchanting.get_enchantment(wielditem, "fire_aspect") if fire_aspect_level > 0 then - local damage = fire_aspect_level * 4 - 1 - mcl_burning.set_on_fire(player, 4, 1, 4 / damage, hitter:get_player_name()) + mcl_burning.set_on_fire(player, fire_aspect_level * 4, hitter:get_player_name()) end end end diff --git a/mods/ITEMS/mcl_enchanting/engine.lua b/mods/ITEMS/mcl_enchanting/engine.lua index 5bb5884ce..791527c5e 100644 --- a/mods/ITEMS/mcl_enchanting/engine.lua +++ b/mods/ITEMS/mcl_enchanting/engine.lua @@ -9,14 +9,21 @@ function mcl_enchanting.get_enchantments(itemstack) return minetest.deserialize(itemstack:get_meta():get_string("mcl_enchanting:enchantments")) or {} end -function mcl_enchanting.set_enchantments(itemstack, enchantments) - itemstack:get_meta():set_string("mcl_enchanting:enchantments", minetest.serialize(enchantments)) +function mcl_enchanting.unload_enchantments(itemstack) local itemdef = itemstack:get_definition() + if itemdef.tool_capabilities then + itemstack:get_meta():set_tool_capabilities(itemdef.tool_capabilities) + end + local meta = itemstack:get_meta() + if meta:get_string("name") == "" then + meta:set_string("description", "") + end +end + +function mcl_enchanting.load_enchantments(itemstack, enchantments) if not mcl_enchanting.is_book(itemstack:get_name()) then - if itemdef.tool_capabilities then - itemstack:get_meta():set_tool_capabilities(itemdef.tool_capabilities) - end - for enchantment, level in pairs(enchantments) do + mcl_enchanting.unload_enchantments(itemstack) + for enchantment, level in pairs(enchantments or mcl_enchanting.get_enchantments(itemstack)) do local enchantment_def = mcl_enchanting.enchantments[enchantment] if enchantment_def.on_enchant then enchantment_def.on_enchant(itemstack, level) @@ -26,6 +33,11 @@ function mcl_enchanting.set_enchantments(itemstack, enchantments) tt.reload_itemstack_description(itemstack) end +function mcl_enchanting.set_enchantments(itemstack, enchantments) + itemstack:get_meta():set_string("mcl_enchanting:enchantments", minetest.serialize(enchantments)) + mcl_enchanting.load_enchantments(itemstack) +end + function mcl_enchanting.get_enchantment(itemstack, enchantment) return mcl_enchanting.get_enchantments(itemstack)[enchantment] or 0 end @@ -147,7 +159,7 @@ function mcl_enchanting.combine(itemstack, combine_with) local itemname = itemstack:get_name() local combine_name = combine_with:get_name() local enchanted_itemname = mcl_enchanting.get_enchanted_itemstring(itemname) - if enchanted_itemname ~= mcl_enchanting.get_enchanted_itemstring(combine_name) and not mcl_enchanting.is_book(combine_name) then + if not enchanted_itemname or enchanted_itemname ~= mcl_enchanting.get_enchanted_itemstring(combine_name) and not mcl_enchanting.is_book(combine_name) then return false end local enchantments = mcl_enchanting.get_enchantments(itemstack) @@ -325,7 +337,7 @@ function mcl_enchanting.get_randomly_enchanted_book(enchantment_level, treasure, return mcl_enchanting.enchant_randomly(ItemStack("mcl_books:book"), enchantment_level, treasure, no_reduced_bonus_chance, true) end -function mcl_enchanting.get_uniform_randomly_enchanted_book(except) +function mcl_enchanting.get_uniform_randomly_enchanted_book(except, pr) except = except or except local stack = ItemStack("mcl_enchanting:book_enchanted") local list = {} @@ -334,10 +346,19 @@ function mcl_enchanting.get_uniform_randomly_enchanted_book(except) table.insert(list, enchantment) end end - local index = math.random(#list) + local index, level + if pr then + index = pr:next(1,#list) + else + index = math.random(#list) + end local enchantment = list[index] local enchantment_def = mcl_enchanting.enchantments[enchantment] - local level = math.random(enchantment_def.max_level) + if pr then + level = pr:next(1, enchantment_def.max_level) + else + level = math.random(enchantment_def.max_level) + end mcl_enchanting.enchant(stack, enchantment, level) return stack end diff --git a/mods/ITEMS/mcl_enchanting/init.lua b/mods/ITEMS/mcl_enchanting/init.lua index a53350a70..4918e3776 100644 --- a/mods/ITEMS/mcl_enchanting/init.lua +++ b/mods/ITEMS/mcl_enchanting/init.lua @@ -191,7 +191,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 +308,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/locale/mcl_enchanting.ru.tr b/mods/ITEMS/mcl_enchanting/locale/mcl_enchanting.ru.tr new file mode 100644 index 000000000..6ea2038be --- /dev/null +++ b/mods/ITEMS/mcl_enchanting/locale/mcl_enchanting.ru.tr @@ -0,0 +1,100 @@ +# textdomain: mcl_enchanting +Aqua Affinity=Родство с водой +Increases underwater mining speed.=Увеличивает скорость добычи под водой. +Bane of Arthropods=Бич членистоногих +Increases damage and applies Slowness IV to arthropod mobs (spiders, cave spiders, silverfish and endermites).=Увеличивает урон и применяет Замедление IV к насекомым и членистоногим (паукам, пещерным паукам, чешуйницам и чешуйницам края). +Blast Protection=Взрывоустойчивость +Reduces explosion damage and knockback.=Уменьшает урон и отдачу от взрывов. +Channeling=Громовержец +Channels a bolt of lightning toward a target. Works only during thunderstorms and if target is unobstructed with opaque blocks.=Бьёт молнией в цель. Работает только во время грозы, когда цель не защищена плотными блоками. +Curse of Binding=Проклятие несъёмности +Item cannot be removed from armor slots except due to death, breaking or in Creative Mode.=Предмет не может быть изъят из слота доспехов, кроме как в результате смерти, разрушения или в креативном режиме. +Curse of Vanishing=Проклятье утраты +Item destroyed on death.=Предмет уничтожается при смерти. +Depth Strider=Покоритель глубин +Increases underwater movement speed.=Увеличивает скорость передвижения под водой. +Efficiency=Эффективность +Increases mining speed.=Увеличивает скорость добычи. +Feather Falling=Невесомость +Reduces fall damage.=Снижает урон от падения. +Fire Aspect=Заговор огня +Sets target on fire.=Поджигает цель. +Fire Protection=Защита от огня +Reduces fire damage.=Уменьшает урон от огня. +Flame=Пламя +Arrows set target on fire.=Стрелы поджигают цель. +Fortune=Удача +Increases certain block drops.=Увеличивает выпадение ресурсов из блоков. +Frost Walker=Ледоход +Turns water beneath the player into frosted ice and prevents the damage from magma blocks.=Превращает воду под игроком в замороженный лёд и предотвращает урон от магмовых блоков. +Impaling=Пронзатель +Trident deals additional damage to ocean mobs.=Трезубец наносит дополнительный урон океаническим мобам. +Infinity=Бесконечность +Shooting consumes no regular arrows.=При стрельбе не расходуются стрелы. +Knockback=Отскок +Increases knockback.=Увеличивает отдачу. +Looting=Добыча +Increases mob loot.=Увеличивает добычу от мобов. +Loyalty=Верность +Trident returns after being thrown. Higher levels reduce return time.=Возвращает трезубец после броска. Более высокие уровни сокращают время возврата. +Luck of the Sea=Везучий рыбак +Increases rate of good loot (enchanting books, etc.)=Увеличивает шанс поймать сокровище (зачарованные книги и т.п.) +Lure=Приманка +Decreases time until rod catches something.=Уменьшает время ожидания клёва. +Mending=Починка +Repair the item while gaining XP orbs.=Предмет чинится при сборе жемчужин опыта. +Multishot=Залп +Shoot 3 arrows at the cost of one.=Выстреливают три стрелы по стоимости одной. +Piercing=Бронебойность +Arrows passes through multiple objects.=Стрела пробивает насквозь несколько объектов. +Power=Сила +Increases arrow damage.=Увеличивает урон от стрел. +Projectile Protection=Защита от снарядов +Reduces projectile damage.=Уменьшает урон от снарядов. +Protection=Защита +Reduces most types of damage by 4% for each level.=Уменьшает большинство повреждений на 4% за каждый уровень. +Punch=Отбрасывание +Increases arrow knockback.=Увеличивает отбрасывание от стрелы. +Quick Charge=Быстрая перезарядка +Decreases crossbow charging time.=Уменьшает время заряда снаряда. +Respiration=Подводное дыхание +Extends underwater breathing time.=Увеличивает время дыхания под водой. +Riptide=Тягун +Trident launches player with itself when thrown. Works only in water or rain.=Трезубец тянет игрока за собой. Работает только в воде или под дождём. +Sharpness=Острота +Increases damage.=Увеличенный урон. +Silk Touch=Шёлковое касание +Mined blocks drop themselves.=Добываемый блок выпадает сам, даже если из него должно выпадать что-то другое. +Smite=Небесная кара +Increases damage to undead mobs.=Дополнительный урон мертвякам (зомби и т.п.). +Soul Speed=Скорость души +Increases walking speed on soul sand.=Увеличивает скорость ходьбы по песку душ. +Sweeping Edge=Разящий клинок +Increases sweeping attack damage.=Увеличивает урон по мобам, стоящих рядом с целью. +Thorns=Шипы +Reflects some of the damage taken when hit, at the cost of reducing durability with each proc.=Отражают некоторый урон, получаемый от ударов, за счёт снижения прочности с каждым разом. +Unbreaking=Нерушимость +Increases item durability.=Увеличивает прочность предмета. +Inventory=Инвентарь +@1 × Lapis Lazuli=@1 × Ляпис-лазурь +Enchantment levels: @1=Уровень зачаровывания: @1 +Level requirement: @1=Требуемый уровень: @1 +Enchant an item=Зачаровать предмет + []=<игрок> <зачарование> [<уровень>] +Usage: /enchant []=Использование: /enchant <игрок> <зачарование> [<уровень>] +Player '@1' cannot be found.=Не удалось найти игрока '@1'. +There is no such enchantment '@1'.=Нет такого зачаровывания: '@1'. +The target doesn't hold an item.=Цель не держит предмета. +The selected enchantment can't be added to the target item.=Выбранное зачарование не может быть добавлено к целевому предмету. +'@1' is not a valid number='@1' не является допустимым числом +The number you have entered (@1) is too big, it must be at most @2.=Число, которое вы задали (@1), слишком велико, оно может быть максимум @2. +The number you have entered (@1) is too small, it must be at least @2.=Число, которое вы задали (@1), слишком мало, оно может быть минимум @2. +@1 can't be combined with @2.=@1 нельзя сочетать с @2. +Enchanting succeded.=Зачарование выполнено. +Forcefully enchant an item=Принудительно зачаровать предмет +Usage: /forceenchant []=Использование: /forceenchant <игрок> <зачарование> [<уровень>] +The target item is not enchantable.=Указана незачаровываемая цель. +'@1' is not a valid number.='@1' не является допустимым числом. +Enchanted Book=Зачарованная книга +Enchanting Table=Стол зачаровывания +Enchant=Зачарование 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/depends.txt b/mods/ITEMS/mcl_end/depends.txt deleted file mode 100644 index 2adb4b59d..000000000 --- a/mods/ITEMS/mcl_end/depends.txt +++ /dev/null @@ -1,5 +0,0 @@ -mcl_sounds -mcl_util -doc_items -mcl_worlds -mcl_structures diff --git a/mods/ITEMS/mcl_end/end_crystal.lua b/mods/ITEMS/mcl_end/end_crystal.lua index c07ff7930..8686f1de0 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"), @@ -86,9 +86,14 @@ minetest.register_craftitem("mcl_end:crystal", { if pointed_thing.type == "node" then local pos = minetest.get_pointed_thing_position(pointed_thing) local node = minetest.get_node(pos).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 not minetest.is_creative_enabled(placer:get_player_name()) then itemstack:take_item() end spawn_crystal(pos) @@ -110,5 +115,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/mod.conf b/mods/ITEMS/mcl_end/mod.conf new file mode 100644 index 000000000..021417e86 --- /dev/null +++ b/mods/ITEMS/mcl_end/mod.conf @@ -0,0 +1,2 @@ +name = mcl_end +depends = screwdriver, mcl_sounds, mcl_util, doc_items, mcl_worlds, mcl_structures \ No newline at end of file diff --git a/mods/ITEMS/mcl_farming/shared_functions.lua b/mods/ITEMS/mcl_farming/shared_functions.lua index 90f7d3373..c4cb2fd71 100644 --- a/mods/ITEMS/mcl_farming/shared_functions.lua +++ b/mods/ITEMS/mcl_farming/shared_functions.lua @@ -1,4 +1,6 @@ +mcl_farming.plant_lists = {} local plant_lists = {} + local plant_nodename_to_id_list = {} local function get_intervals_counter(pos, interval, chance) @@ -51,11 +53,12 @@ local function get_avg_light_level(pos) end function mcl_farming:add_plant(identifier, full_grown, names, interval, chance) - plant_lists[identifier] = {} - plant_lists[identifier].full_grown = full_grown - plant_lists[identifier].names = names - plant_lists[identifier].interval = interval - plant_lists[identifier].chance = chance + mcl_farming.plant_lists[identifier] = {} + mcl_farming.plant_lists[identifier].full_grown = full_grown + mcl_farming.plant_lists[identifier].names = names + mcl_farming.plant_lists[identifier].interval = interval + mcl_farming.plant_lists[identifier].chance = chance + plant_lists = mcl_farming.plant_lists --provide local copy of plant lists (performances) minetest.register_abm({ label = string.format("Farming plant growth (%s)", identifier), nodenames = names, diff --git a/mods/ITEMS/mcl_fire/depends.txt b/mods/ITEMS/mcl_fire/depends.txt deleted file mode 100644 index 97699f211..000000000 --- a/mods/ITEMS/mcl_fire/depends.txt +++ /dev/null @@ -1,5 +0,0 @@ -mcl_core -mcl_worlds -mcl_sounds -mcl_particles -mcl_portals? diff --git a/mods/ITEMS/mcl_fire/fire_charge.lua b/mods/ITEMS/mcl_fire/fire_charge.lua index dcf4ddb00..f4d2da321 100644 --- a/mods/ITEMS/mcl_fire/fire_charge.lua +++ b/mods/ITEMS/mcl_fire/fire_charge.lua @@ -1,5 +1,8 @@ local S = minetest.get_translator("mcl_fire") +local get_node = minetest.get_node +local add_entity = minetest.add_entity + -- Fire Charge minetest.register_craftitem("mcl_fire:fire_charge", { description = S("Fire Charge"), @@ -11,7 +14,7 @@ minetest.register_craftitem("mcl_fire:fire_charge", { stack_max = 64, on_place = function(itemstack, user, pointed_thing) -- Use pointed node's on_rightclick function first, if present - local node = minetest.get_node(pointed_thing.under) + local node = get_node(pointed_thing.under) if user and not user: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, user, itemstack) or itemstack @@ -45,7 +48,7 @@ minetest.register_craftitem("mcl_fire:fire_charge", { _on_dispense = function(stack, pos, droppos, dropnode, dropdir) -- Throw fire charge local shootpos = vector.add(pos, vector.multiply(dropdir, 0.51)) - local fireball = minetest.add_entity(shootpos, "mobs_mc:blaze_fireball") + local fireball = add_entity(shootpos, "mobs_mc:blaze_fireball") local ent = fireball:get_luaentity() ent._shot_from_dispenser = true local v = ent.velocity or 1 diff --git a/mods/ITEMS/mcl_fire/flint_and_steel.lua b/mods/ITEMS/mcl_fire/flint_and_steel.lua index 54c2f1fac..b0e711e0a 100644 --- a/mods/ITEMS/mcl_fire/flint_and_steel.lua +++ b/mods/ITEMS/mcl_fire/flint_and_steel.lua @@ -1,4 +1,6 @@ local S = minetest.get_translator("mcl_fire") +local get_node = minetest.get_node +local add_node = minetest.add_node -- Flint and Steel minetest.register_tool("mcl_fire:flint_and_steel", { @@ -12,7 +14,7 @@ minetest.register_tool("mcl_fire:flint_and_steel", { groups = { tool = 1, }, on_place = function(itemstack, user, pointed_thing) -- Use pointed node's on_rightclick function first, if present - local node = minetest.get_node(pointed_thing.under) + local node = get_node(pointed_thing.under) if user and not user: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, user, itemstack) or itemstack @@ -33,7 +35,7 @@ minetest.register_tool("mcl_fire:flint_and_steel", { ) local used = false if pointed_thing.type == "node" then - local nodedef = minetest.registered_nodes[minetest.get_node(pointed_thing.under).name] + local nodedef = minetest.registered_nodes[get_node(pointed_thing.under).name] if nodedef and nodedef._on_ignite then local overwrite = nodedef._on_ignite(user, pointed_thing) if not overwrite then @@ -56,7 +58,7 @@ minetest.register_tool("mcl_fire:flint_and_steel", { _on_dispense = function(stack, pos, droppos, dropnode, dropdir) -- Ignite air if dropnode.name == "air" then - minetest.add_node(droppos, {name="mcl_fire:fire"}) + add_node(droppos, {name="mcl_fire:fire"}) if not minetest.is_creative_enabled("") then stack:add_wear(65535/65) -- 65 uses end diff --git a/mods/ITEMS/mcl_fire/init.lua b/mods/ITEMS/mcl_fire/init.lua index 50303e3b2..f11c683a6 100644 --- a/mods/ITEMS/mcl_fire/init.lua +++ b/mods/ITEMS/mcl_fire/init.lua @@ -1,10 +1,29 @@ -- Global namespace for functions mcl_fire = {} +local modpath = minetest.get_modpath(minetest.get_current_modname()) local S = minetest.get_translator("mcl_fire") local N = function(s) return s end +local has_mcl_portals = minetest.get_modpath("mcl_portals") + +local set_node = minetest.set_node +local get_node = minetest.get_node +local add_node = minetest.add_node +local remove_node = minetest.remove_node +local swap_node = minetest.swap_node +local get_node_or_nil = minetest.get_node_or_nil + +local find_nodes_in_area = minetest.find_nodes_in_area +local find_node_near = minetest.find_node_near +local get_item_group = minetest.get_item_group + +local get_connected_players = minetest.get_connected_players + +local vector = vector +local math = math + -- inverse pyramid pattern above lava source, floor 1 of 2: local lava_fire= { @@ -28,7 +47,72 @@ local alldirs= { x = 0, y = 0, z = 1} } +-- 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, +} +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 }) + + -- 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 + + smoke_pdef_cached[id] = table.copy(smoke_pdef_base) + + mcl_particles.add_node_particlespawner(pos, smoke_pdef_cached[id], "high") + + 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 + +--[[ Old smoke pdef + local spawn_smoke = function(pos) mcl_particles.add_node_particlespawner(pos, { amount = 0.1, time = 0, @@ -48,6 +132,8 @@ local spawn_smoke = function(pos) length = 2.1, }, }, "high") + -- ]] + end -- @@ -90,7 +176,7 @@ local fire_timer = function(pos) end local spawn_fire = function(pos, age) - minetest.set_node(pos, {name="mcl_fire:fire", param2 = age}) + set_node(pos, {name="mcl_fire:fire", param2 = age}) minetest.check_single_for_falling({x=pos.x, y=pos.y+1, z=pos.z}) end @@ -120,28 +206,28 @@ minetest.register_node("mcl_fire:fire", { groups = {fire = 1, dig_immediate = 3, not_in_creative_inventory = 1, dig_by_piston=1, destroys_items=1, set_on_fire=8}, floodable = true, on_flood = function(pos, oldnode, newnode) - if minetest.get_item_group(newnode.name, "water") ~= 0 then + if get_item_group(newnode.name, "water") ~= 0 then minetest.sound_play("fire_extinguish_flame", {pos = pos, gain = 0.25, max_hear_distance = 16}, true) end end, on_timer = function(pos) - local node = minetest.get_node(pos) + local node = get_node(pos) -- Age is a number from 0 to 15 and is increased every timer step. -- "old" fire is more likely to be extinguished local age = node.param2 - local flammables = minetest.find_nodes_in_area({x=pos.x-1, y=pos.y-1, z=pos.z-1}, {x=pos.x+1, y=pos.y+4, z=pos.z+1}, {"group:flammable"}) - local below = minetest.get_node({x=pos.x, y=pos.z-1, z=pos.z}) - local below_is_flammable = minetest.get_item_group(below.name, "flammable") > 0 + local flammables = find_nodes_in_area({x=pos.x-1, y=pos.y-1, z=pos.z-1}, {x=pos.x+1, y=pos.y+4, z=pos.z+1}, {"group:flammable"}) + local below = get_node({x=pos.x, y=pos.z-1, z=pos.z}) + local below_is_flammable = get_item_group(below.name, "flammable") > 0 -- Extinguish fire if (not fire_enabled) and (math.random(1,3) == 1) then - minetest.remove_node(pos) + remove_node(pos) return end if age == 15 and not below_is_flammable then - minetest.remove_node(pos) + remove_node(pos) return elseif age > 3 and #flammables == 0 and not below_is_flammable and math.random(1,4) == 1 then - minetest.remove_node(pos) + remove_node(pos) return end local age_add = 1 @@ -149,14 +235,14 @@ minetest.register_node("mcl_fire:fire", { if (not fire_enabled) then if age + age_add <= 15 then node.param2 = age + age_add - minetest.set_node(pos, node) + set_node(pos, node) end -- Restart timer fire_timer(pos) return end -- Spawn fire to nearby flammable nodes - local is_next_to_flammable = minetest.find_node_near(pos, 2, {"group:flammable"}) ~= nil + local is_next_to_flammable = find_node_near(pos, 2, {"group:flammable"}) ~= nil if is_next_to_flammable and math.random(1,2) == 1 then -- The fire we spawn copies the age of this fire. -- This prevents fire from spreading infinitely far as the fire fire dies off @@ -166,10 +252,10 @@ minetest.register_node("mcl_fire:fire", { local burntype = math.random(1,2) if burntype == 1 then -- Spawn fire in air - local nodes = minetest.find_nodes_in_area({x=pos.x-1, y=pos.y-1, z=pos.z-1}, {x=pos.x+1, y=pos.y+4, z=pos.z+1}, {"air"}) + local nodes = find_nodes_in_area({x=pos.x-1, y=pos.y-1, z=pos.z-1}, {x=pos.x+1, y=pos.y+4, z=pos.z+1}, {"air"}) while #nodes > 0 do local r = math.random(1, #nodes) - if minetest.find_node_near(nodes[r], 1, {"group:flammable"}) then + if find_node_near(nodes[r], 1, {"group:flammable"}) then spawn_fire(nodes[r], age_next) break else @@ -178,12 +264,12 @@ minetest.register_node("mcl_fire:fire", { end else -- Burn flammable block - local nodes = minetest.find_nodes_in_area({x=pos.x-1, y=pos.y-1, z=pos.z-1}, {x=pos.x+1, y=pos.y+4, z=pos.z+1}, {"group:flammable"}) + local nodes = find_nodes_in_area({x=pos.x-1, y=pos.y-1, z=pos.z-1}, {x=pos.x+1, y=pos.y+4, z=pos.z+1}, {"group:flammable"}) if #nodes > 0 then local r = math.random(1, #nodes) - local nn = minetest.get_node(nodes[r]).name + local nn = get_node(nodes[r]).name local ndef = minetest.registered_nodes[nn] - local fgroup = minetest.get_item_group(nn, "flammable") + local fgroup = get_item_group(nn, "flammable") if ndef and ndef._on_burn then ndef._on_burn(nodes[r]) elseif fgroup ~= -1 then @@ -195,7 +281,7 @@ minetest.register_node("mcl_fire:fire", { -- Regular age increase if age + age_add <= 15 then node.param2 = age + age_add - minetest.set_node(pos, node) + set_node(pos, node) end -- Restart timer fire_timer(pos) @@ -205,14 +291,14 @@ minetest.register_node("mcl_fire:fire", { -- Turn into eternal fire on special blocks, light Nether portal (if possible), start burning timer on_construct = function(pos) local bpos = {x=pos.x, y=pos.y-1, z=pos.z} - local under = minetest.get_node(bpos).name + local under = get_node(bpos).name local dim = mcl_worlds.pos_to_dimension(bpos) if under == "mcl_nether:magma" or under == "mcl_nether:netherrack" or (under == "mcl_core:bedrock" and dim == "end") then - minetest.swap_node(pos, {name = "mcl_fire:eternal_fire"}) + swap_node(pos, {name = "mcl_fire:eternal_fire"}) end - if minetest.get_modpath("mcl_portals") then + if has_mcl_portals then mcl_portals.light_nether_portal(pos) end @@ -251,17 +337,17 @@ minetest.register_node("mcl_fire:eternal_fire", { groups = {fire = 1, dig_immediate = 3, not_in_creative_inventory = 1, dig_by_piston = 1, destroys_items = 1, set_on_fire=8}, floodable = true, on_flood = function(pos, oldnode, newnode) - if minetest.get_item_group(newnode.name, "water") ~= 0 then + if get_item_group(newnode.name, "water") ~= 0 then minetest.sound_play("fire_extinguish_flame", {pos = pos, gain = 0.25, max_hear_distance = 16}, true) end end, on_timer = function(pos) if fire_enabled then - local airs = minetest.find_nodes_in_area({x=pos.x-1, y=pos.y-1, z=pos.z-1}, {x=pos.x+1, y=pos.y+4, z=pos.z+1}, {"air"}) + local airs = find_nodes_in_area({x=pos.x-1, y=pos.y-1, z=pos.z-1}, {x=pos.x+1, y=pos.y+4, z=pos.z+1}, {"air"}) while #airs > 0 do local r = math.random(1, #airs) - if minetest.find_node_near(airs[r], 1, {"group:flammable"}) then - local node = minetest.get_node(airs[r]) + if find_node_near(airs[r], 1, {"group:flammable"}) then + local node = get_node(airs[r]) local age = node.param2 local age_next = math.min(15, age + math.random(0, 1)) spawn_fire(airs[r], age_next) @@ -278,7 +364,7 @@ minetest.register_node("mcl_fire:eternal_fire", { on_construct = function(pos) fire_timer(pos) - if minetest.get_modpath("mcl_portals") then + if has_mcl_portals then --Calling directly minetest.get_modpath consumes 4x more compute time mcl_portals.light_nether_portal(pos) end spawn_smoke(pos) @@ -313,7 +399,7 @@ if flame_sound then local ppos = player:get_pos() local areamin = vector.subtract(ppos, radius) local areamax = vector.add(ppos, radius) - local fpos, num = minetest.find_nodes_in_area( + local fpos, num = find_nodes_in_area( areamin, areamax, {"mcl_fire:fire", "mcl_fire:eternal_fire"} @@ -384,7 +470,7 @@ if flame_sound then end timer = 0 - local players = minetest.get_connected_players() + local players = get_connected_players() for n = 1, #players do mcl_fire.update_player_sound(players[n]) end @@ -416,7 +502,7 @@ minetest.register_abm({ chance = 1, catch_up = false, action = function(pos, node, active_object_count, active_object_count_wider) - minetest.remove_node(pos) + remove_node(pos) minetest.sound_play("fire_extinguish_flame", {pos = pos, max_hear_distance = 16, gain = 0.15}, true) end, @@ -429,8 +515,8 @@ local function has_flammable(pos) local npos, node for n, v in ipairs(alldirs) do npos = vector.add(pos, v) - node = minetest.get_node_or_nil(npos) - if node and node.name and minetest.get_item_group(node.name, "flammable") ~= 0 then + node = get_node_or_nil(npos) + if node and node.name and get_item_group(node.name, "flammable") ~= 0 then return npos end end @@ -447,7 +533,7 @@ if not fire_enabled then interval = 10, chance = 10, catch_up = false, - action = minetest.remove_node, + action = remove_node, }) else -- Fire enabled @@ -465,12 +551,12 @@ else -- Fire enabled i = math.random(1,9) dir = lava_fire[i] target = {x=pos.x+dir.x, y=pos.y+dir.y, z=pos.z+dir.z} - node = minetest.get_node(target) + node = get_node(target) if not node or node.name ~= "air" then i = ((i + math.random(0,7)) % 9) + 1 dir = lava_fire[i] target = {x=pos.x+dir.x, y=pos.y+dir.y, z=pos.z+dir.z} - node = minetest.get_node(target) + node = get_node(target) if not node or node.name ~= "air" then return end @@ -480,7 +566,7 @@ else -- Fire enabled local dir2, target2, node2 dir2 = lava_fire[i2] target2 = {x=target.x+dir2.x, y=target.y+dir2.y, z=target.z+dir2.z} - node2 = minetest.get_node(target2) + node2 = get_node(target2) if node2 and node2.name == "air" then f = has_flammable(target2) if f then @@ -521,9 +607,9 @@ mcl_fire.set_fire = function(pointed_thing, player, allow_on_fire) else pname = player:get_player_name() end - local n = minetest.get_node(pointed_thing.above) - local nu = minetest.get_node(pointed_thing.under) - if allow_on_fire == false and minetest.get_item_group(nu.name, "fire") ~= 0 then + local n = get_node(pointed_thing.above) + local nu = get_node(pointed_thing.under) + if allow_on_fire == false and get_item_group(nu.name, "fire") ~= 0 then return end if minetest.is_protected(pointed_thing.above, pname) then @@ -531,7 +617,7 @@ mcl_fire.set_fire = function(pointed_thing, player, allow_on_fire) return end if n.name == "air" then - minetest.add_node(pointed_thing.above, {name="mcl_fire:fire"}) + add_node(pointed_thing.above, {name="mcl_fire:fire"}) end end @@ -549,5 +635,5 @@ minetest.register_alias("mcl_fire:basic_flame", "mcl_fire:fire") minetest.register_alias("fire:basic_flame", "mcl_fire:fire") minetest.register_alias("fire:permanent_flame", "mcl_fire:eternal_fire") -dofile(minetest.get_modpath(minetest.get_current_modname()).."/flint_and_steel.lua") -dofile(minetest.get_modpath(minetest.get_current_modname()).."/fire_charge.lua") +dofile(modpath.."/flint_and_steel.lua") +dofile(modpath.."/fire_charge.lua") diff --git a/mods/ITEMS/mcl_fire/mod.conf b/mods/ITEMS/mcl_fire/mod.conf index 23de4da69..da94d9278 100644 --- a/mods/ITEMS/mcl_fire/mod.conf +++ b/mods/ITEMS/mcl_fire/mod.conf @@ -1 +1,3 @@ name = mcl_fire +depends = mcl_core, mcl_worlds, mcl_sounds, mcl_particles +optional_depends = mcl_portals \ No newline at end of file diff --git a/mods/ITEMS/mcl_flowerpots/depends.txt b/mods/ITEMS/mcl_flowerpots/depends.txt deleted file mode 100644 index bc1609be2..000000000 --- a/mods/ITEMS/mcl_flowerpots/depends.txt +++ /dev/null @@ -1,5 +0,0 @@ -mcl_core -mcl_sounds -mcl_farming -mcl_flowers -doc? diff --git a/mods/ITEMS/mcl_flowerpots/init.lua b/mods/ITEMS/mcl_flowerpots/init.lua index 5a752c407..21d4c04e6 100644 --- a/mods/ITEMS/mcl_flowerpots/init.lua +++ b/mods/ITEMS/mcl_flowerpots/init.lua @@ -1,31 +1,8 @@ local S = minetest.get_translator("mcl_flowerpots") +local has_doc = minetest.get_modpath("doc") -local flowers = { - {"dandelion", "mcl_flowers:dandelion", S("Dandelion Flower Pot")}, - {"poppy", "mcl_flowers:poppy", S("Poppy Flower Pot")}, - {"blue_orchid", "mcl_flowers:blue_orchid", S("Blue Orchid Flower Pot")}, - {"allium", "mcl_flowers:allium", S("Allium Flower Pot")}, - {"azure_bluet", "mcl_flowers:azure_bluet", S("Azure Bluet Flower Pot")}, - {"tulip_red", "mcl_flowers:tulip_red", S("Red Tulip Flower Pot")}, - {"tulip_pink", "mcl_flowers:tulip_pink", S("Pink Tulip Flower Pot")}, - {"tulip_white", "mcl_flowers:tulip_white", S("White Tulip Flower Pot")}, - {"tulip_orange", "mcl_flowers:tulip_orange", S("Orange Tulip Flower Pot")}, - {"oxeye_daisy", "mcl_flowers:oxeye_daisy", S("Oxeye Daisy Flower Pot")}, - {"mushroom_brown", "mcl_mushrooms:mushroom_brown", S("Brown Mushroom Flower Pot")}, - {"mushroom_red", "mcl_mushrooms:mushroom_red", S("Red Mushroom Flower Pot")}, - {"sapling", "mcl_core:sapling", S("Oak Sapling Flower Pot")}, - {"acaciasapling", "mcl_core:acaciasapling", S("Acacia Sapling Flower Pot")}, - {"junglesapling", "mcl_core:junglesapling", S("Jungle Sapling Flower Pot")}, - {"darksapling", "mcl_core:darksapling", S("Dark Oak Sapling Flower Pot")}, - {"sprucesapling", "mcl_core:sprucesapling", S("Spruce Sapling Flower Pot")}, - {"birchsapling", "mcl_core:birchsapling", S("Birch Sapling Flower Pot")}, - {"deadbush", "mcl_core:deadbush", S("Dead Bush Flower Pot")}, - {"fern", "mcl_flowers:fern", S("Fern Flower Pot"), {"mcl_flowers_fern_inv.png"}}, -} - -local cubes = { - {"cactus", "mcl_core:cactus", S("Cactus Flower Pot")}, -} +mcl_flowerpots = {} +mcl_flowerpots.registered_pots = {} minetest.register_node("mcl_flowerpots:flower_pot", { description = S("Flower Pot"), @@ -62,24 +39,10 @@ minetest.register_node("mcl_flowerpots:flower_pot", { return end local item = clicker:get_wielded_item():get_name() - for _, row in ipairs(flowers) do - local flower = row[1] - local flower_node = row[2] - if item == flower_node then - minetest.swap_node(pos, {name="mcl_flowerpots:flower_pot_"..flower}) - if not minetest.is_creative_enabled(clicker:get_player_name()) then - itemstack:take_item() - end - end - end - for _, row in ipairs(cubes) do - local flower = row[1] - local flower_node = row[2] - if item == flower_node then - minetest.swap_node(pos, {name="mcl_flowerpots:flower_pot_"..flower}) - if not minetest.is_creative_enabled(clicker:get_player_name()) then - itemstack:take_item() - end + if mcl_flowerpots.registered_pots[item] then + minetest.swap_node(pos, {name="mcl_flowerpots:flower_pot_"..mcl_flowerpots.registered_pots[item]}) + if not minetest.is_creative_enabled(clicker:get_player_name()) then + itemstack:take_item() end end end, @@ -94,112 +57,160 @@ minetest.register_craft({ } }) -for _, row in ipairs(flowers) do -local flower = row[1] -local flower_node = row[2] -local desc = row[3] -local texture -if row[4] then - texture = row[4] -else - texture = minetest.registered_nodes[flower_node]["tiles"] -end -minetest.register_node("mcl_flowerpots:flower_pot_"..flower, { - description = desc, - _doc_items_create_entry = false, - drawtype = "mesh", - mesh = "flowerpot.obj", - tiles = { - "[combine:32x32:0,0=mcl_flowerpots_flowerpot.png:0,0="..texture[1], - }, - use_texture_alpha = minetest.features.use_texture_alpha_string_modes and "clip" or true, - visual_scale = 0.5, - wield_scale = {x=1.0, y=1.0, z=1.0}, - paramtype = "light", - sunlight_propagates = true, - selection_box = { - type = "fixed", - fixed = {-0.2, -0.5, -0.2, 0.2, -0.1, 0.2} - }, - collision_box = { - type = "fixed", - fixed = {-0.2, -0.5, -0.2, 0.2, -0.1, 0.2} - }, - is_ground_content = false, - groups = {dig_immediate=3, attached_node=1, dig_by_piston=1, not_in_creative_inventory=1, flower_pot=2}, - sounds = mcl_sounds.node_sound_stone_defaults(), - on_rightclick = function(pos, item, clicker) - local name = clicker:get_player_name() - if minetest.is_protected(pos, name) then - minetest.record_protection_violation(pos, name) - return - end - minetest.add_item({x=pos.x, y=pos.y+0.5, z=pos.z}, flower_node) - minetest.set_node(pos, {name="mcl_flowerpots:flower_pot"}) - end, - drop = { - items = { - { items = { "mcl_flowerpots:flower_pot", flower_node } } - } - }, -}) --- Add entry alias for the Help -if minetest.get_modpath("doc") then - doc.add_entry_alias("nodes", "mcl_flowerpots:flower_pot", "nodes", "mcl_flowerpots:flower_pot_"..flower) -end +function mcl_flowerpots.register_potted_flower(name, def) + mcl_flowerpots.registered_pots[name] = def.name + minetest.register_node(":mcl_flowerpots:flower_pot_"..def.name, { + description = def.desc.." "..S("Flower Pot"), + _doc_items_create_entry = false, + drawtype = "mesh", + mesh = "flowerpot.obj", + tiles = { + "[combine:32x32:0,0=mcl_flowerpots_flowerpot.png:0,0="..def.image, + }, + use_texture_alpha = minetest.features.use_texture_alpha_string_modes and "clip" or true, + visual_scale = 0.5, + wield_scale = {x=1.0, y=1.0, z=1.0}, + paramtype = "light", + sunlight_propagates = true, + selection_box = { + type = "fixed", + fixed = {-0.2, -0.5, -0.2, 0.2, -0.1, 0.2} + }, + collision_box = { + type = "fixed", + fixed = {-0.2, -0.5, -0.2, 0.2, -0.1, 0.2} + }, + is_ground_content = false, + groups = {dig_immediate=3, attached_node=1, dig_by_piston=1, not_in_creative_inventory=1, flower_pot=2}, + sounds = mcl_sounds.node_sound_stone_defaults(), + on_rightclick = function(pos, item, clicker) + local player_name = clicker:get_player_name() + if minetest.is_protected(pos, player_name) then + minetest.record_protection_violation(pos, player_name) + return + end + minetest.add_item({x=pos.x, y=pos.y+0.5, z=pos.z}, name) + minetest.set_node(pos, {name="mcl_flowerpots:flower_pot"}) + end, + drop = { + items = { + { items = { "mcl_flowerpots:flower_pot", name } } + } + }, + }) + -- Add entry alias for the Help + if has_doc then + doc.add_entry_alias("nodes", "mcl_flowerpots:flower_pot", "nodes", "mcl_flowerpots:flower_pot_"..name) + end end -for _, row in ipairs(cubes) do -local flower = row[1] -local flower_node = row[2] -local desc = row[3] -minetest.register_node("mcl_flowerpots:flower_pot_"..flower, { - description = desc, - _doc_items_create_entry = false, - drawtype = "mesh", - mesh = "flowerpot_with_long_cube.obj", - tiles = { - "mcl_flowerpots_"..flower..".png", - }, - use_texture_alpha = minetest.features.use_texture_alpha_string_modes and "clip" or true, - visual_scale = 0.5, - wield_scale = {x=1.0, y=1.0, z=1.0}, - paramtype = "light", - sunlight_propagates = true, - selection_box = { - type = "fixed", - fixed = {-0.2, -0.5, -0.2, 0.2, -0.1, 0.2} - }, - collision_box = { - type = "fixed", - fixed = {-0.2, -0.5, -0.2, 0.2, -0.1, 0.2} - }, - is_ground_content = false, - groups = {dig_immediate=3, attached_node=1, dig_by_piston=1, not_in_creative_inventory=1, flower_pot=2}, - sounds = mcl_sounds.node_sound_stone_defaults(), - on_rightclick = function(pos, item, clicker) - local name = "" - if clicker:is_player() then - name = clicker:get_player_name() - end - if minetest.is_protected(pos, name) then - minetest.record_protection_violation(pos, name) - return - end - minetest.add_item({x=pos.x, y=pos.y+0.5, z=pos.z}, flower_node) - minetest.set_node(pos, {name="mcl_flowerpots:flower_pot"}) - end, - drop = { - items = { - { items = { "mcl_flowerpots:flower_pot", flower_node } } - } - }, - +function mcl_flowerpots.register_potted_cube(name, def) + mcl_flowerpots.registered_pots[name] = def.name + minetest.register_node(":mcl_flowerpots:flower_pot_"..def.name, { + description = def.desc.." "..S("Flower Pot"), + _doc_items_create_entry = false, + drawtype = "mesh", + mesh = "flowerpot_with_long_cube.obj", + tiles = { + def.image, + }, + use_texture_alpha = minetest.features.use_texture_alpha_string_modes and "clip" or true, + visual_scale = 0.5, + wield_scale = {x=1.0, y=1.0, z=1.0}, + paramtype = "light", + sunlight_propagates = true, + selection_box = { + type = "fixed", + fixed = {-0.2, -0.5, -0.2, 0.2, -0.1, 0.2} + }, + collision_box = { + type = "fixed", + fixed = {-0.2, -0.5, -0.2, 0.2, -0.1, 0.2} + }, + is_ground_content = false, + groups = {dig_immediate=3, attached_node=1, dig_by_piston=1, not_in_creative_inventory=1, flower_pot=2}, + sounds = mcl_sounds.node_sound_stone_defaults(), + on_rightclick = function(pos, item, clicker) + local player_name = "" + if clicker:is_player() then + player_name = clicker:get_player_name() + end + if minetest.is_protected(pos, player_name) then + minetest.record_protection_violation(pos, player_name) + return + end + minetest.add_item({x=pos.x, y=pos.y+0.5, z=pos.z}, name) + minetest.set_node(pos, {name="mcl_flowerpots:flower_pot"}) + end, + drop = { + items = { + { items = { "mcl_flowerpots:flower_pot", name } } + } + }, + }) + -- Add entry alias for the Help + if has_doc then + doc.add_entry_alias("nodes", "mcl_flowerpots:flower_pot", "nodes", "mcl_flowerpots:flower_pot_"..def.name) + end +end +--forced because hard dependency to mcl_core +mcl_flowerpots.register_potted_cube("mcl_core:cactus", { + name = "cactus", + desc = S("Cactus"), + image = "mcl_flowerpots_cactus.png", }) --- Add entry alias for the Help -if minetest.get_modpath("doc") then - doc.add_entry_alias("nodes", "mcl_flowerpots:flower_pot", "nodes", "mcl_flowerpots:flower_pot_"..flower) -end -end +mcl_flowerpots.register_potted_flower("mcl_mushrooms:mushroom_brown", { + name = "mushroom_brown", + desc = S("Brown Mushroom"), + image = "farming_mushroom_brown.png", +}) + +mcl_flowerpots.register_potted_flower("mcl_mushrooms:mushroom_red", { + name = "mushroom_red", + desc = S("Red Mushroom"), + image = "farming_mushroom_red.png", +}) + +mcl_flowerpots.register_potted_flower("mcl_core:sapling", { + name = "sapling", + desc = S("Oak Sapling"), + image = "default_sapling.png", +}) + +mcl_flowerpots.register_potted_flower("mcl_core:acaciasapling", { + name = "acaciasapling", + desc = S("Acacia Sapling"), + image = "default_acacia_sapling.png", +}) + +mcl_flowerpots.register_potted_flower("mcl_core:junglesapling", { + name = "junglesapling", + desc = S("Jungle Sapling"), + image = "default_junglesapling.png", +}) + +mcl_flowerpots.register_potted_flower("mcl_core:darksapling", { + name = "darksapling", + desc = S("Dark Oak Sapling"), + image = "mcl_core_sapling_big_oak.png", +}) + +mcl_flowerpots.register_potted_flower("mcl_core:sprucesapling", { + name = "sprucesapling", + desc = S("Spruce Sapling"), + image = "mcl_core_sapling_spruce.png", +}) + +mcl_flowerpots.register_potted_flower("mcl_core:birchsapling", { + name = "birchsapling", + desc = S("Birch Sapling"), + image = "mcl_core_sapling_birch.png", +}) + +mcl_flowerpots.register_potted_flower("mcl_core:deadbush", { + name = "deadbush", + desc = S("Dead Bush"), + image = "default_dry_shrub.png", +}) diff --git a/mods/ITEMS/mcl_flowerpots/mod.conf b/mods/ITEMS/mcl_flowerpots/mod.conf new file mode 100644 index 000000000..e6a71c4da --- /dev/null +++ b/mods/ITEMS/mcl_flowerpots/mod.conf @@ -0,0 +1,3 @@ +name=mcl_flowerpots +depends=mcl_core, mcl_sounds, mcl_farming +optional_depends=doc \ No newline at end of file diff --git a/mods/ITEMS/mcl_flowers/API.md b/mods/ITEMS/mcl_flowers/API.md new file mode 100644 index 000000000..f3dc87725 --- /dev/null +++ b/mods/ITEMS/mcl_flowers/API.md @@ -0,0 +1,9 @@ +# API +Flower mod for mcl2 +# Functions +## mcl_flowers.register_simple_flower(name, desc, image, simple_selection_box) +Register a simple flower: +* name: legacity name eg: "my_super_flower" +* desc: description eg: "My Super Flower" +* image: texture +* simple_selection_box: nodebox of the flower \ No newline at end of file diff --git a/mods/ITEMS/mcl_flowers/depends.txt b/mods/ITEMS/mcl_flowers/depends.txt deleted file mode 100644 index a7a7b9cd1..000000000 --- a/mods/ITEMS/mcl_flowers/depends.txt +++ /dev/null @@ -1,5 +0,0 @@ -mcl_core -mcl_util -mcl_sounds -screwdriver? -doc? diff --git a/mods/ITEMS/mcl_flowers/init.lua b/mods/ITEMS/mcl_flowers/init.lua index 4e6c438de..a155ebd0b 100644 --- a/mods/ITEMS/mcl_flowers/init.lua +++ b/mods/ITEMS/mcl_flowers/init.lua @@ -1,7 +1,10 @@ local S = minetest.get_translator("mcl_flowers") - local mod_screwdriver = minetest.get_modpath("screwdriver") ~= nil +local has_mcl_flowerpots = minetest.get_modpath("mcl_flowerpots") +local modpath = minetest.get_modpath("mcl_flowers") +mcl_flowers = {} +mcl_flowers.registered_simple_flowers = {} -- Simple flower template local smallflowerlongdesc = S("This is a small flower. Small flowers are mainly used for dye production and can also be potted.") local plant_usage_help = S("It can only be placed on a block on which it would also survive.") @@ -51,43 +54,49 @@ local on_place_flower = mcl_util.generate_on_place_plant_function(function(pos, return ok, colorize end) -local function add_simple_flower(name, desc, image, simple_selection_box) - minetest.register_node("mcl_flowers:"..name, { - description = desc, +function mcl_flowers.register_simple_flower(name, def) + local newname = "mcl_flowers:"..name + if not def._mcl_silk_touch_drop then def._mcl_silk_touch_drop = nil end + if not def.drop then def.drop = newname end + mcl_flowers.registered_simple_flowers[newname] = { + name=name, + desc=def.desc, + image=def.image, + simple_selection_box=def.simple_selection_box, + } + minetest.register_node(newname, { + description = def.desc, _doc_items_longdesc = smallflowerlongdesc, _doc_items_usagehelp = plant_usage_help, drawtype = "plantlike", waving = 1, - tiles = { image..".png" }, - inventory_image = image..".png", - wield_image = image..".png", + tiles = { def.image }, + inventory_image = def.image, + wield_image = def.image, sunlight_propagates = true, paramtype = "light", walkable = false, stack_max = 64, + drop = def.drop, groups = {dig_immediate=3,flammable=2,fire_encouragement=60,fire_flammability=100,plant=1,flower=1,place_flowerlike=1,non_mycelium_plant=1,attached_node=1,dig_by_water=1,destroy_by_lava_flow=1,dig_by_piston=1,enderman_takable=1,deco_block=1}, sounds = mcl_sounds.node_sound_leaves_defaults(), node_placement_prediction = "", on_place = on_place_flower, selection_box = { type = "fixed", - fixed = simple_selection_box, + fixed = def.selection_box, }, + _mcl_silk_touch_drop = def._mcl_silk_touch_drop, }) + if def.potted and has_mcl_flowerpots then + mcl_flowerpots.register_potted_flower(newname, { + name = name, + desc = def.desc, + image = def.image, + }) + end end -add_simple_flower("poppy", S("Poppy"), "mcl_flowers_poppy", { -5/16, -0.5, -5/16, 5/16, 5/16, 5/16 }) -add_simple_flower("dandelion", S("Dandelion"), "flowers_dandelion_yellow", { -4/16, -0.5, -4/16, 4/16, 3/16, 4/16 }) -add_simple_flower("oxeye_daisy", S("Oxeye Daisy"), "mcl_flowers_oxeye_daisy", { -4/16, -0.5, -4/16, 4/16, 4/16, 4/16 }) -add_simple_flower("tulip_orange", S("Orange Tulip"), "flowers_tulip", { -3/16, -0.5, -3/16, 3/16, 5/16, 3/16 }) -add_simple_flower("tulip_pink", S("Pink Tulip"), "mcl_flowers_tulip_pink", { -3/16, -0.5, -3/16, 3/16, 5/16, 3/16 }) -add_simple_flower("tulip_red", S("Red Tulip"), "mcl_flowers_tulip_red", { -3/16, -0.5, -3/16, 3/16, 6/16, 3/16 }) -add_simple_flower("tulip_white", S("White Tulip"), "mcl_flowers_tulip_white", { -3/16, -0.5, -3/16, 3/16, 4/16, 3/16 }) -add_simple_flower("allium", S("Allium"), "mcl_flowers_allium", { -3/16, -0.5, -3/16, 3/16, 6/16, 3/16 }) -add_simple_flower("azure_bluet", S("Azure Bluet"), "mcl_flowers_azure_bluet", { -5/16, -0.5, -5/16, 5/16, 3/16, 5/16 }) -add_simple_flower("blue_orchid", S("Blue Orchid"), "mcl_flowers_blue_orchid", { -5/16, -0.5, -5/16, 5/16, 7/16, 5/16 }) - - local wheat_seed_drop = { max_items = 1, items = { @@ -159,6 +168,14 @@ def_fern.selection_box = { minetest.register_node("mcl_flowers:fern", def_fern) +if has_mcl_flowerpots then + mcl_flowerpots.register_potted_flower("mcl_flowers:fern", { + name = "fern", + desc = S("Fern"), + image = "mcl_flowers_fern_inv.png", + }) +end + local function add_large_plant(name, desc, longdesc, bottom_img, top_img, inv_img, selbox_radius, selbox_top_height, drop, shears_drop, is_flower, grass_color, fortune_drop) if not inv_img then inv_img = top_img @@ -480,3 +497,4 @@ local fix_doubleplants = minetest.settings:get_bool("fix_doubleplants", true) }) end +dofile(modpath.."/register.lua") diff --git a/mods/ITEMS/mcl_flowers/mod.conf b/mods/ITEMS/mcl_flowers/mod.conf new file mode 100644 index 000000000..b309ac22e --- /dev/null +++ b/mods/ITEMS/mcl_flowers/mod.conf @@ -0,0 +1,3 @@ +name=mcl_flowers +depends=mcl_core, mcl_util, mcl_sounds +optional_depends=screwdriver, doc, mcl_flowerpots \ No newline at end of file diff --git a/mods/ITEMS/mcl_flowers/register.lua b/mods/ITEMS/mcl_flowers/register.lua new file mode 100644 index 000000000..9b65caebf --- /dev/null +++ b/mods/ITEMS/mcl_flowers/register.lua @@ -0,0 +1,62 @@ +local S = minetest.get_translator("mcl_flowers") + +mcl_flowers.register_simple_flower("poppy", { + desc = S("Poppy"), + image = "mcl_flowers_poppy.png", + selection_box = { -5/16, -0.5, -5/16, 5/16, 5/16, 5/16 }, + potted = true, +}) +mcl_flowers.register_simple_flower("dandelion", { + desc = S("Dandelion"), + image = "flowers_dandelion_yellow.png", + selection_box = { -4/16, -0.5, -4/16, 4/16, 3/16, 4/16 }, + potted = true, +}) +mcl_flowers.register_simple_flower("oxeye_daisy", { + desc = S("Oxeye Daisy"), + image = "mcl_flowers_oxeye_daisy.png", + selection_box = { -4/16, -0.5, -4/16, 4/16, 4/16, 4/16 }, + potted = true, +}) +mcl_flowers.register_simple_flower("tulip_orange", { + desc = S("Orange Tulip"), + image = "flowers_tulip.png", + selection_box = { -3/16, -0.5, -3/16, 3/16, 5/16, 3/16 }, + potted = true, +}) +mcl_flowers.register_simple_flower("tulip_pink", { + desc = S("Pink Tulip"), + image = "mcl_flowers_tulip_pink.png", + selection_box = { -3/16, -0.5, -3/16, 3/16, 5/16, 3/16 }, + potted = true, +}) +mcl_flowers.register_simple_flower("tulip_red", { + desc = S("Red Tulip"), + image = "mcl_flowers_tulip_red.png", + selection_box = { -3/16, -0.5, -3/16, 3/16, 6/16, 3/16 }, + potted = true, +}) +mcl_flowers.register_simple_flower("tulip_white", { + desc = S("White Tulip"), + image = "mcl_flowers_tulip_white.png", + selection_box = { -3/16, -0.5, -3/16, 3/16, 4/16, 3/16 }, + potted = true, +}) +mcl_flowers.register_simple_flower("allium", { + desc = S("Allium"), + image = "mcl_flowers_allium.png", + selection_box = { -3/16, -0.5, -3/16, 3/16, 6/16, 3/16 }, + potted = true, +}) +mcl_flowers.register_simple_flower("azure_bluet", { + desc = S("Azure Bluet"), + image = "mcl_flowers_azure_bluet.png", + selection_box = { -5/16, -0.5, -5/16, 5/16, 3/16, 5/16 }, + potted = true, +}) +mcl_flowers.register_simple_flower("blue_orchid", { + desc = S("Blue Orchid"), + image = "mcl_flowers_blue_orchid.png", + selection_box = { -5/16, -0.5, -5/16, 5/16, 7/16, 5/16 }, + potted = true, +}) \ No newline at end of file diff --git a/mods/ITEMS/mcl_hoppers/init.lua b/mods/ITEMS/mcl_hoppers/init.lua index 52cb60874..3ff549e4f 100644 --- a/mods/ITEMS/mcl_hoppers/init.lua +++ b/mods/ITEMS/mcl_hoppers/init.lua @@ -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_jukebox/API.md b/mods/ITEMS/mcl_jukebox/API.md new file mode 100644 index 000000000..85900ede0 --- /dev/null +++ b/mods/ITEMS/mcl_jukebox/API.md @@ -0,0 +1,18 @@ +# mcl_jukebox + +## mcl_jukebox.register_record(title, author, identifier, image, sound) + +* title: title of the track +* author: author of the track +* identifier: short string used in the item registration +* image: the texture of the track +* sound: sound file of the track + +## mcl_jukebox.registered_records + +Table indexed by item name containing: +* title: title of the track +* author: author of the track +* identifier: short string used in the item registration +* image: the texture of the track +* sound: sound file of the track \ No newline at end of file diff --git a/mods/ITEMS/mcl_jukebox/depends.txt b/mods/ITEMS/mcl_jukebox/depends.txt deleted file mode 100644 index 97bf51069..000000000 --- a/mods/ITEMS/mcl_jukebox/depends.txt +++ /dev/null @@ -1,2 +0,0 @@ -mcl_core -mcl_sounds diff --git a/mods/ITEMS/mcl_jukebox/description.txt b/mods/ITEMS/mcl_jukebox/description.txt deleted file mode 100644 index 143812e1d..000000000 --- a/mods/ITEMS/mcl_jukebox/description.txt +++ /dev/null @@ -1 +0,0 @@ -Jukebox and music discs are used to play background music on a per-player basis. diff --git a/mods/ITEMS/mcl_jukebox/init.lua b/mods/ITEMS/mcl_jukebox/init.lua index db9f25312..c5bd3d268 100644 --- a/mods/ITEMS/mcl_jukebox/init.lua +++ b/mods/ITEMS/mcl_jukebox/init.lua @@ -1,5 +1,8 @@ local S = minetest.get_translator("mcl_jukebox") +mcl_jukebox = {} +mcl_jukebox.registered_records = {} + -- Player name-indexed table containing the currently heard track local active_tracks = {} @@ -10,47 +13,30 @@ local active_huds = {} -- Used to make sure that minetest.after only applies to the latest HUD change event local hud_sequence_numbers = {} --- List of music -local recorddata = { - -- { title, author, identifier } - { "The Evil Sister (Jordach's Mix)", "SoundHelix", "13" } , - { "The Energetic Rat (Jordach's Mix)", "SoundHelix", "wait" }, - { "Eastern Feeling", "Jordach", "blocks"}, - { "Minetest", "Jordach", "far" }, - { "Credit Roll (Jordach's HD Mix)", "Junichi Masuda", "chirp" }, - { "Winter Feeling", "Tom Peter", "strad" }, - { "Synthgroove (Jordach's Mix)", "HeroOfTheWinds", "mellohi" }, - { "The Clueless Frog (Jordach's Mix)", "SoundHelix", "mall" }, -} -local records = #recorddata - -for r=1, records do - local doc = false - local entryname, longdesc, usagehelp - if r == 1 then - doc = true - entryname = S("Music Disc") - longdesc = S("A music disc holds a single music track which can be used in a jukebox to play music.") - 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.") - end - minetest.register_craftitem("mcl_jukebox:record_"..r, { +function mcl_jukebox.register_record(title, author, identifier, image, sound) + mcl_jukebox.registered_records["mcl_jukebox:record_"..identifier] = {title, author, identifier, image, sound} + local entryname = S("Music Disc") + local longdesc = S("A music disc holds a single music track which can be used in a jukebox to play music.") + 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", recorddata[r][2], recorddata[r][1])), - _doc_items_create_entry = doc, + core.colorize("#989898", S("@1—@2", author, title)), + _doc_items_create_entry = true, _doc_items_entry_name = entryname, _doc_items_longdesc = longdesc, _doc_items_usagehelp = usagehelp, - inventory_image = "mcl_jukebox_record_"..recorddata[r][3]..".png", + --inventory_image = "mcl_jukebox_record_"..recorddata[r][3]..".png", + inventory_image = image, stack_max = 1, - groups = { music_record = r }, + groups = { music_record = 1 }, }) end -local function now_playing(player, track_id) +local function now_playing(player, name) local playername = player:get_player_name() local hud = active_huds[playername] - local text = S("Now playing: @1—@2", recorddata[track_id][2], recorddata[track_id][1]) + local text = S("Now playing: @1—@2", mcl_jukebox.registered_records[name][2], mcl_jukebox.registered_records[name][1]) if not hud_sequence_numbers[playername] then hud_sequence_numbers[playername] = 1 @@ -106,18 +92,18 @@ minetest.register_craft({ }) local play_record = function(pos, itemstack, player) - local record_id = minetest.get_item_group(itemstack:get_name(), "music_record") - if record_id ~= 0 then + local name = itemstack:get_name() + if mcl_jukebox.registered_records[name] then local cname = player:get_player_name() if active_tracks[cname] ~= nil then minetest.sound_stop(active_tracks[cname]) active_tracks[cname] = nil end - active_tracks[cname] = minetest.sound_play("mcl_jukebox_track_"..record_id, { + active_tracks[cname] = minetest.sound_play(mcl_jukebox.registered_records[name][5], { to_player = cname, gain = 1, }) - now_playing(player, record_id) + now_playing(player, name) return true end return false @@ -239,3 +225,22 @@ minetest.register_craft({ recipe = "mcl_jukebox:jukebox", burntime = 15, }) + +mcl_jukebox.register_record("The Evil Sister (Jordach's Mix)", "SoundHelix", "13", "mcl_jukebox_record_13.png", "mcl_jukebox_track_1") +mcl_jukebox.register_record("The Energetic Rat (Jordach's Mix)", "SoundHelix", "wait", "mcl_jukebox_record_wait.png", "mcl_jukebox_track_2") +mcl_jukebox.register_record("Eastern Feeling", "Jordach", "blocks", "mcl_jukebox_record_blocks.png", "mcl_jukebox_track_3") +mcl_jukebox.register_record("Minetest", "Jordach", "far", "mcl_jukebox_record_far.png", "mcl_jukebox_track_4") +mcl_jukebox.register_record("Credit Roll (Jordach's HD Mix)", "Junichi Masuda", "chirp", "mcl_jukebox_record_chirp.png", "mcl_jukebox_track_5") +mcl_jukebox.register_record("Winter Feeling", "Tom Peter", "strad", "mcl_jukebox_record_strad.png", "mcl_jukebox_track_6") +mcl_jukebox.register_record("Synthgroove (Jordach's Mix)", "HeroOfTheWinds", "mellohi", "mcl_jukebox_record_mellohi.png", "mcl_jukebox_track_7") +mcl_jukebox.register_record("The Clueless Frog (Jordach's Mix)", "SoundHelix", "mall", "mcl_jukebox_record_mall.png", "mcl_jukebox_track_8") + +--add backward compatibility +minetest.register_alias("mcl_jukebox:record_1", "mcl_jukebox:record_13") +minetest.register_alias("mcl_jukebox:record_2", "mcl_jukebox:record_wait") +minetest.register_alias("mcl_jukebox:record_3", "mcl_jukebox:record_blocks") +minetest.register_alias("mcl_jukebox:record_4", "mcl_jukebox:record_far") +minetest.register_alias("mcl_jukebox:record_5", "mcl_jukebox:record_chirp") +minetest.register_alias("mcl_jukebox:record_6", "mcl_jukebox:record_strad") +minetest.register_alias("mcl_jukebox:record_7", "mcl_jukebox:record_mellohi") +minetest.register_alias("mcl_jukebox:record_8", "mcl_jukebox:record_mall") \ No newline at end of file diff --git a/mods/ITEMS/mcl_jukebox/mod.conf b/mods/ITEMS/mcl_jukebox/mod.conf index ec39a7be9..ad1f8c06a 100644 --- a/mods/ITEMS/mcl_jukebox/mod.conf +++ b/mods/ITEMS/mcl_jukebox/mod.conf @@ -1 +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 diff --git a/mods/ITEMS/mcl_maps/init.lua b/mods/ITEMS/mcl_maps/init.lua index 893e70073..58a0a3a15 100644 --- a/mods/ITEMS/mcl_maps/init.lua +++ b/mods/ITEMS/mcl_maps/init.lua @@ -28,6 +28,8 @@ minetest.register_craftitem("mcl_maps:empty_map", { stack_max = 64, }) +mcl_wip.register_wip_item("mcl_maps:empty_map") + local function has_item_in_hotbar(player, item) -- Requirement: player carries the tool in the hotbar local inv = player:get_inventory() diff --git a/mods/ITEMS/mcl_maps/mod.conf b/mods/ITEMS/mcl_maps/mod.conf index 44c4becf0..5615dc2be 100644 --- a/mods/ITEMS/mcl_maps/mod.conf +++ b/mods/ITEMS/mcl_maps/mod.conf @@ -1 +1,2 @@ name = mcl_maps +depends = mcl_wip diff --git a/mods/ITEMS/mcl_mobspawners/init.lua b/mods/ITEMS/mcl_mobspawners/init.lua index a58c2ed02..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 @@ -313,7 +313,7 @@ minetest.register_node("mcl_mobspawners:spawner", { if obj then obj:remove() end - mcl_experience.throw_experience(math.random(15, 43)) + mcl_experience.throw_experience(pos, math.random(15, 43)) end, on_punch = function(pos) diff --git a/mods/ITEMS/mcl_nether/init.lua b/mods/ITEMS/mcl_nether/init.lua index 026428db2..7c8dd56a5 100644 --- a/mods/ITEMS/mcl_nether/init.lua +++ b/mods/ITEMS/mcl_nether/init.lua @@ -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 diff --git a/mods/ITEMS/mcl_nether/locale/mcl_nether.fr.tr b/mods/ITEMS/mcl_nether/locale/mcl_nether.fr.tr index 78b8a453e..11a046374 100644 --- a/mods/ITEMS/mcl_nether/locale/mcl_nether.fr.tr +++ b/mods/ITEMS/mcl_nether/locale/mcl_nether.fr.tr @@ -10,10 +10,10 @@ Magma blocks are hot solid blocks which hurt anyone standing on it, unless they @1 stood too long on a magma block.=@1 s'est tenu trop longtemps sur un bloc de magma. Soul Sand=Sable des âmes Soul sand is a block from the Nether. One can only slowly walk on soul sand. The slowing effect is amplified when the soul sand is on top of ice, packed ice or a slime block.=Le sable de l'âme est un bloc du Nether. On ne peut que marcher lentement sur le sable de l'âme. L'effet de ralentissement est amplifié lorsque le sable de l'âme est au-dessus de la glace, de la glace tassée ou d'un bloc de slime. -Nether Brick Block=Brique du Nether -Red Nether Brick Block=Brique Rouge du Nether +Nether Brick Block=Bloc de Briques du Nether +Red Nether Brick Block=Bloc de Briques Rouges du Nether Nether Wart Block=Bloc de Verrues du Nether -A nether wart block is a purely decorative block made from nether wart.=Un bloc de verrue du Nether est un bloc purement décoratif fabriqué à partir de verrue du Nether. +A nether wart block is a purely decorative block made from nether wart.=Un bloc de verrues du Nether est un bloc purement décoratif fabriqué à partir de verrue du Nether. Block of Quartz=Bloc de Quartz Chiseled Quartz Block=Bloc de Quartz sculpté Pillar Quartz Block=Bloc de Quartz rayé @@ -22,8 +22,8 @@ Glowstone Dust=Poudre Lumineuse Glowstone dust is the dust which comes out of broken glowstones. It is mainly used in crafting.=La poudre lumineuse est la poussière qui sort des pierres incandescentes brisées. Il est principalement utilisé dans l'artisanat. Nether Quartz=Quartz du Nether Nether quartz is a versatile crafting ingredient.=Le quartz du Nether est un ingrédient artisanal polyvalent. -Nether Brick=Bric du Nether -Nether bricks are the main crafting ingredient for crafting nether brick blocks and nether fences.=Les briques du Nether sont le principal ingrédient de fabrication pour la fabrication de blocs de briques et de clôtures du Nether. +Nether Brick=Brique du Nether +Nether bricks are the main crafting ingredient for crafting nether brick blocks and nether fences.=Les briques du Nether sont le principal ingrédient pour la fabrication de blocs de briques et de clôtures du Nether. Nether Lava Source=Source de Lave du Nether Flowing Nether Lava=Lave du Nether en Mouvement Premature Nether Wart (Stage 1)=Verrue du Néant prématurée (étape 1) 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 0a04fb709..ff9df2b4d 100644 --- a/mods/ITEMS/mcl_portals/portal_nether.lua +++ b/mods/ITEMS/mcl_portals/portal_nether.lua @@ -64,7 +64,7 @@ local function destroy_nether_portal(pos) local meta = minetest.get_meta(pos) local node = minetest.get_node(pos) local nn, orientation = node.name, node.param2 - local obsidian = nn == "mcl_core:obsidian" + local obsidian = nn == "mcl_core:obsidian" local has_meta = minetest.string_to_pos(meta:get_string("portal_frame1")) if has_meta then @@ -138,8 +138,6 @@ minetest.register_node("mcl_portals:portal", { sunlight_propagates = true, use_texture_alpha = minetest.features.use_texture_alpha_string_modes and "blend" or true, walkable = false, - diggable = false, - pointable = false, buildable_to = false, is_ground_content = false, drop = "", @@ -152,7 +150,8 @@ minetest.register_node("mcl_portals:portal", { {-0.5, -0.5, -0.1, 0.5, 0.5, 0.1}, }, }, - groups = {portal=1, not_in_creative_inventory = 1}, + groups = { creative_breakable = 1, portal = 1, not_in_creative_inventory = 1 }, + sounds = mcl_sounds.node_sound_glass_defaults(), on_destruct = destroy_nether_portal, _mcl_hardness = -1, @@ -583,7 +582,7 @@ local function check_and_light_shape(pos, orientation) meta:set_string("portal_time", tostring(0)) meta:set_string("portal_target", "") end - return true + return true end -- Attempts to light a Nether portal at pos @@ -595,7 +594,7 @@ function mcl_portals.light_nether_portal(pos) -- Only allow to make portals in Overworld and Nether local dim = mcl_worlds.pos_to_dimension(pos) if dim ~= "overworld" and dim ~= "nether" then - return 0 + return false end local orientation = math.random(0, 1) for orientation_iteration = 1, 2 do @@ -799,7 +798,7 @@ minetest.register_abm({ end end distance = vector.subtract(pos, distance) - 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 minetest.add_particlespawner({ amount = node_particles_allowed_level + 1, @@ -819,7 +818,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) @@ -842,7 +841,7 @@ minetest.override_item("mcl_core:obsidian", { _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: - local portals_placed = + local portals_placed = mcl_portals.light_nether_portal({x = x - 1, y = y, z = z}) or mcl_portals.light_nether_portal({x = x + 1, y = y, 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 + 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}) @@ -863,4 +862,3 @@ minetest.override_item("mcl_core:obsidian", { end end, }) - diff --git a/mods/ITEMS/mcl_potions/functions.lua b/mods/ITEMS/mcl_potions/functions.lua index f1384ab30..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 @@ -590,23 +590,36 @@ function mcl_potions.make_invisible(player, toggle) local is_player = player:is_player() local entity = player:get_luaentity() + local playername = player:get_player_name() + local skin_file = "" if toggle then -- hide player - if player:is_player() then - EF.invisible[player].old_size = player:get_properties().visual_size - elseif entity then + skin_file = "mobs_mc_empty.png" + + if entity then EF.invisible[player].old_size = entity.visual_size - else -- if not a player or entity, do nothing + elseif not player:is_player() then -- if not a player or entity, do nothing return end - player:set_properties({visual_size = {x = 0, y = 0}}) + if minetest.get_modpath("mcl_armor") and player:is_player() then + armor.textures[playername].skin = skin_file + armor:update_player_visuals(player) + elseif not player:is_player() and minetest.get_modpath("mcl_armor") or not player:is_player() and not minetest.get_modpath("mcl_armor") then + player:set_properties({visual_size = {x = 0, y = 0}}) + end player:set_nametag_attributes({color = {a = 0}}) elseif EF.invisible[player] then -- show player - player:set_properties({visual_size = EF.invisible[player].old_size}) + if minetest.get_modpath("mcl_armor") and player:is_player() then + skin_file = mcl_skins.skins[playername] .. ".png" + armor.textures[playername].skin = skin_file + armor:update_player_visuals(player) + elseif not player:is_player() and minetest.get_modpath("mcl_armor") or not player:is_player() and not minetest.get_modpath("mcl_armor") then + player:set_properties({visual_size = EF.invisible[player].old_size}) + end player:set_nametag_attributes({color = {r = 255, g = 255, b = 255, a = 255}}) end @@ -999,4 +1012,3 @@ function mcl_potions._extinguish_nearby_fire(pos, radius) end return exting end - diff --git a/mods/ITEMS/mcl_potions/init.lua b/mods/ITEMS/mcl_potions/init.lua index b7f814c24..65bb0d4de 100644 --- a/mods/ITEMS/mcl_potions/init.lua +++ b/mods/ITEMS/mcl_potions/init.lua @@ -455,3 +455,12 @@ function mcl_potions.get_alchemy(ingr, pot) return false end + +mcl_wip.register_wip_item("mcl_potions:night_vision") +mcl_wip.register_wip_item("mcl_potions:night_vision_plus") +mcl_wip.register_wip_item("mcl_potions:night_vision_splash") +mcl_wip.register_wip_item("mcl_potions:night_vision_plus_splash") +mcl_wip.register_wip_item("mcl_potions:night_vision_lingering") +mcl_wip.register_wip_item("mcl_potions:night_vision_plus_lingering") +mcl_wip.register_wip_item("mcl_potions:night_vision_arrow") +mcl_wip.register_wip_item("mcl_potions:night_vision_plus_arrow") \ No newline at end of file diff --git a/mods/ITEMS/mcl_potions/lingering.lua b/mods/ITEMS/mcl_potions/lingering.lua index cea045233..f4f0e249d 100644 --- a/mods/ITEMS/mcl_potions/lingering.lua +++ b/mods/ITEMS/mcl_potions/lingering.lua @@ -142,7 +142,7 @@ minetest.register_entity(id.."_flying",{ local pos = self.object:get_pos() local node = minetest.get_node(pos) local n = node.name - local g = minetest.get_node_group(n, "liquid") + local g = minetest.get_item_group(n, "liquid") local d = 4 if n ~= "air" and n ~= "mcl_portals:portal" and n ~= "mcl_portals:portal_end" and g == 0 or mcl_potions.is_obj_hit(self, pos) then minetest.sound_play("mcl_potions_breaking_glass", {pos = pos, max_hear_distance = 16, gain = 1}) diff --git a/mods/ITEMS/mcl_potions/mod.conf b/mods/ITEMS/mcl_potions/mod.conf index 3d6fd0011..bcb6d8ad3 100644 --- a/mods/ITEMS/mcl_potions/mod.conf +++ b/mods/ITEMS/mcl_potions/mod.conf @@ -1,2 +1,2 @@ name = mcl_potions -depends = mcl_core, mcl_farming, mcl_mobitems, mcl_fishing, mcl_bows, mcl_end, mcl_weather, playerphysics +depends = mcl_core, mcl_farming, mcl_mobitems, mcl_fishing, mcl_bows, mcl_end, mcl_weather, playerphysics, mcl_wip diff --git a/mods/ITEMS/mcl_potions/splash.lua b/mods/ITEMS/mcl_potions/splash.lua index d5cf30782..bea07b8cf 100644 --- a/mods/ITEMS/mcl_potions/splash.lua +++ b/mods/ITEMS/mcl_potions/splash.lua @@ -64,7 +64,7 @@ function mcl_potions.register_splash(name, descr, color, def) local pos = self.object:get_pos() local node = minetest.get_node(pos) local n = node.name - local g = minetest.get_node_group(n, "liquid") + local g = minetest.get_item_group(n, "liquid") local d = 0.1 local redux_map = {7/8,0.5,0.25} if n ~= "air" and n ~= "mcl_portals:portal" and n ~= "mcl_portals:portal_end" and g == 0 or mcl_potions.is_obj_hit(self, pos) then diff --git a/mods/ITEMS/mcl_potions/tipped_arrow.lua b/mods/ITEMS/mcl_potions/tipped_arrow.lua index 2853487c9..860019e8a 100644 --- a/mods/ITEMS/mcl_potions/tipped_arrow.lua +++ b/mods/ITEMS/mcl_potions/tipped_arrow.lua @@ -100,9 +100,10 @@ function mcl_potions.register_arrow(name, desc, color, def) local ARROW_ENTITY={ physical = true, - visual = "wielditem", - visual_size = {x=0.4, y=0.4}, - textures = {"mcl_potions:"..name.."_arrow_box"}, + visual = "mesh", + mesh = "mcl_bows_arrow.obj", + visual_size = {x=1, y=1}, + textures = arrow_image(color, 100), collisionbox = {-0.19, -0.125, -0.19, 0.19, 0.125, 0.19}, collide_with_objects = false, @@ -177,6 +178,26 @@ function mcl_potions.register_arrow(name, desc, color, def) -- Check for object "collision". Done every tick (hopefully this is not too stressing) else + + if self._damage == 10 or self._damage == 9 then + minetest.add_particlespawner({ + amount = 1, + time = .001, + minpos = pos, + maxpos = pos, + minvel = vector.new(-0.1,-0.1,-0.1), + maxvel = vector.new(0.1,0.1,0.1), + minexptime = 0.5, + maxexptime = 0.5, + minsize = 2, + maxsize = 2, + collisiondetection = false, + vertical = false, + texture = "mobs_mc_arrow_particle.png", + glow = 1, + }) + end + -- We just check for any hurtable objects nearby. -- The radius of 3 is fairly liberal, but anything lower than than will cause -- arrow to hilariously go through mobs often. diff --git a/mods/ITEMS/mcl_tnt/init.lua b/mods/ITEMS/mcl_tnt/init.lua index ef4fb33c2..8001e5cf0 100644 --- a/mods/ITEMS/mcl_tnt/init.lua +++ b/mods/ITEMS/mcl_tnt/init.lua @@ -180,7 +180,7 @@ function TNT:on_step(dtime) self.blinkstatus = not self.blinkstatus end if self.timer > tnt.BOOMTIMER then - mcl_explosions.explode(self.object:get_pos(), 4, { drop_chance = 1.0 }, self.object) + mcl_explosions.explode(self.object:get_pos(), 4, {}, self.object) self.object:remove() end end diff --git a/mods/ITEMS/mcl_tools/init.lua b/mods/ITEMS/mcl_tools/init.lua index b022bacd8..d40b8e01b 100644 --- a/mods/ITEMS/mcl_tools/init.lua +++ b/mods/ITEMS/mcl_tools/init.lua @@ -49,7 +49,7 @@ minetest.register_item(":", { _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".. S("In Creative Mode, the hand is able to break all blocks instantly."), - wield_image = "wieldhand.png", + wield_image = "blank.png", wield_scale = {x=1.0,y=1.0,z=2.0}, -- According to Minecraft Wiki, the exact range is 3.975. -- Minetest seems to only support whole numbers, so we use 4. diff --git a/mods/ITEMS/mcl_tools/textures/wieldhand.png b/mods/ITEMS/mcl_tools/textures/wieldhand.png deleted file mode 100644 index 47d21f690..000000000 Binary files a/mods/ITEMS/mcl_tools/textures/wieldhand.png and /dev/null differ diff --git a/mods/ITEMS/mclx_core/depends.txt b/mods/ITEMS/mclx_core/depends.txt deleted file mode 100644 index 870d9cb09..000000000 --- a/mods/ITEMS/mclx_core/depends.txt +++ /dev/null @@ -1,2 +0,0 @@ -mcl_core -doc? diff --git a/mods/ITEMS/mclx_core/description.txt b/mods/ITEMS/mclx_core/description.txt deleted file mode 100644 index 422e6da57..000000000 --- a/mods/ITEMS/mclx_core/description.txt +++ /dev/null @@ -1 +0,0 @@ -Core items not found in Minecraft diff --git a/mods/ITEMS/mclx_core/mod.conf b/mods/ITEMS/mclx_core/mod.conf index 235cf6d3f..62e8d5fb3 100644 --- a/mods/ITEMS/mclx_core/mod.conf +++ b/mods/ITEMS/mclx_core/mod.conf @@ -1 +1,4 @@ name = mclx_core +description = Core items not found in Minecraft +depends = mcl_core +optional_depends = doc diff --git a/mods/ITEMS/screwdriver/init.lua b/mods/ITEMS/screwdriver/init.lua index ec4f1a2ad..e6aedf19c 100644 --- a/mods/ITEMS/screwdriver/init.lua +++ b/mods/ITEMS/screwdriver/init.lua @@ -187,6 +187,7 @@ minetest.register_tool("screwdriver:screwdriver", { end, }) +mcl_wip.register_wip_item("screwdriver:screwdriver") minetest.register_craft({ output = "screwdriver:screwdriver", diff --git a/mods/ITEMS/screwdriver/mod.conf b/mods/ITEMS/screwdriver/mod.conf new file mode 100644 index 000000000..a18279839 --- /dev/null +++ b/mods/ITEMS/screwdriver/mod.conf @@ -0,0 +1,2 @@ +name = screwdriver +depends = mcl_wip \ No newline at end of file diff --git a/mods/MAPGEN/mcl_biomes/depends.txt b/mods/MAPGEN/mcl_biomes/depends.txt deleted file mode 100644 index dd21ef64f..000000000 --- a/mods/MAPGEN/mcl_biomes/depends.txt +++ /dev/null @@ -1,7 +0,0 @@ -mcl_init -mcl_core -mcl_worlds -mcl_farming -mcl_flowers -mcl_end -mcl_ocean diff --git a/mods/MAPGEN/mcl_biomes/description.txt b/mods/MAPGEN/mcl_biomes/description.txt deleted file mode 100644 index 496ffb217..000000000 --- a/mods/MAPGEN/mcl_biomes/description.txt +++ /dev/null @@ -1 +0,0 @@ -Adds the various biomes and biome-related things for non-v6 map generators. diff --git a/mods/MAPGEN/mcl_biomes/init.lua b/mods/MAPGEN/mcl_biomes/init.lua index dc4905dda..ffb6ae628 100644 --- a/mods/MAPGEN/mcl_biomes/init.lua +++ b/mods/MAPGEN/mcl_biomes/init.lua @@ -2043,26 +2043,28 @@ local function register_dimension_ores() }) -- Nether quartz - minetest.register_ore({ - ore_type = "scatter", - ore = "mcl_nether:quartz_ore", - wherein = {"mcl_nether:netherrack", "mcl_core:stone"}, - clust_scarcity = 850, - clust_num_ores = 4, -- MC cluster amount: 4-10 - clust_size = 3, - y_min = mcl_vars.mg_nether_min, - y_max = mcl_vars.mg_nether_max, - }) - minetest.register_ore({ - ore_type = "scatter", - ore = "mcl_nether:quartz_ore", - wherein = {"mcl_nether:netherrack", "mcl_core:stone"}, - clust_scarcity = 1650, - clust_num_ores = 8, -- MC cluster amount: 4-10 - clust_size = 4, - y_min = mcl_vars.mg_nether_min, - y_max = mcl_vars.mg_nether_max, - }) + if minetest.settings:get("mcl_generate_ores") == "true" then + minetest.register_ore({ + ore_type = "scatter", + ore = "mcl_nether:quartz_ore", + wherein = {"mcl_nether:netherrack", "mcl_core:stone"}, + clust_scarcity = 850, + clust_num_ores = 4, -- MC cluster amount: 4-10 + clust_size = 3, + y_min = mcl_vars.mg_nether_min, + y_max = mcl_vars.mg_nether_max, + }) + minetest.register_ore({ + ore_type = "scatter", + ore = "mcl_nether:quartz_ore", + wherein = {"mcl_nether:netherrack", "mcl_core:stone"}, + clust_scarcity = 1650, + clust_num_ores = 8, -- MC cluster amount: 4-10 + clust_size = 4, + y_min = mcl_vars.mg_nether_min, + y_max = mcl_vars.mg_nether_max, + }) + end -- Lava springs in the Nether minetest.register_ore({ @@ -3967,7 +3969,7 @@ if mg_name ~= "singlenode" then -- Overworld decorations for v6 are handled in mcl_mapgen_core if deco_id_chorus_plant then - minetest.register_on_generated(function(minp, maxp, blockseed) + mcl_mapgen_core.register_generator("chorus_grow", nil, function(minp, maxp, blockseed) local gennotify = minetest.get_mapgen_object("gennotify") local poslist = {} for _, pos in ipairs(gennotify["decoration#"..deco_id_chorus_plant] or {}) do diff --git a/mods/MAPGEN/mcl_biomes/mod.conf b/mods/MAPGEN/mcl_biomes/mod.conf new file mode 100644 index 000000000..0c6095f3d --- /dev/null +++ b/mods/MAPGEN/mcl_biomes/mod.conf @@ -0,0 +1,4 @@ +name = mcl_biomes +author = maikerumine +description = Adds the various biomes and biome-related things for non-v6 map generators. +depends = mcl_init, mcl_mapgen_core, mcl_core, mcl_worlds, mcl_farming, mcl_flowers, mcl_end, mcl_ocean diff --git a/mods/MAPGEN/mcl_dungeons/depends.txt b/mods/MAPGEN/mcl_dungeons/depends.txt deleted file mode 100644 index 4c803c72d..000000000 --- a/mods/MAPGEN/mcl_dungeons/depends.txt +++ /dev/null @@ -1,7 +0,0 @@ -mcl_init -mcl_core -mcl_chests -mcl_mobs -mcl_mobspawners -mcl_mapgen_core -mobs_mc diff --git a/mods/MAPGEN/mcl_dungeons/description.txt b/mods/MAPGEN/mcl_dungeons/description.txt deleted file mode 100644 index 343cb7bdb..000000000 --- a/mods/MAPGEN/mcl_dungeons/description.txt +++ /dev/null @@ -1 +0,0 @@ -Generates random dungeons in the world diff --git a/mods/MAPGEN/mcl_dungeons/init.lua b/mods/MAPGEN/mcl_dungeons/init.lua index 1ce1556b2..05d82c3e9 100644 --- a/mods/MAPGEN/mcl_dungeons/init.lua +++ b/mods/MAPGEN/mcl_dungeons/init.lua @@ -1,400 +1,395 @@ -- FIXME: Chests may appear at openings +mcl_dungeons = {} + local mg_name = minetest.get_mapgen_setting("mg_name") -local pr = PseudoRandom(os.time()) -- Are dungeons disabled? -if mcl_vars.mg_dungeons == false then +if mcl_vars.mg_dungeons == false or mg_name == "singlenode" then return end -if mg_name ~= "singlenode" then --- Get loot for dungeon chests -local get_loot = function() - local loottable = { - { - stacks_min = 1, - stacks_max = 3, - items = { - { itemstring = "mcl_mobs:nametag", weight = 20 }, - { itemstring = "mcl_mobitems:saddle", weight = 20 }, - { itemstring = "mcl_jukebox:record_1", weight = 15 }, - { itemstring = "mcl_jukebox:record_4", weight = 15 }, - { itemstring = "mobs_mc:iron_horse_armor", weight = 15 }, - { itemstring = "mcl_core:apple_gold", weight = 15 }, - { itemstack = mcl_enchanting.get_uniform_randomly_enchanted_book({"soul_speed"}), weight = 10 }, - { itemstring = "mobs_mc:gold_horse_armor", weight = 10 }, - { itemstring = "mobs_mc:diamond_horse_armor", weight = 5 }, - { itemstring = "mcl_core:apple_gold_enchanted", weight = 2 }, - } - }, - { - stacks_min = 1, - stacks_max = 4, - items = { - { itemstring = "mcl_farming:wheat_item", weight = 20, amount_min = 1, amount_max = 4 }, - { itemstring = "mcl_farming:bread", weight = 20 }, - { itemstring = "mcl_core:coal_lump", weight = 15, amount_min = 1, amount_max = 4 }, - { itemstring = "mesecons:redstone", weight = 15, amount_min = 1, amount_max = 4 }, - { itemstring = "mcl_farming:beetroot_seeds", weight = 10, amount_min = 2, amount_max = 4 }, - { itemstring = "mcl_farming:melon_seeds", weight = 10, amount_min = 2, amount_max = 4 }, - { itemstring = "mcl_farming:pumpkin_seeds", weight = 10, amount_min = 2, amount_max = 4 }, - { itemstring = "mcl_core:iron_ingot", weight = 10, amount_min = 1, amount_max = 4 }, - { itemstring = "mcl_buckets:bucket_empty", weight = 10 }, - { itemstring = "mcl_core:gold_ingot", weight = 5, amount_min = 1, amount_max = 4 }, - }, - }, - { - stacks_min = 3, - stacks_max = 3, - items = { - { itemstring = "mcl_mobitems:bone", weight = 10, amount_min = 1, amount_max = 8 }, - { itemstring = "mcl_mobitems:gunpowder", weight = 10, amount_min = 1, amount_max = 8 }, - { itemstring = "mcl_mobitems:rotten_flesh", weight = 10, amount_min = 1, amount_max = 8 }, - { itemstring = "mcl_mobitems:string", weight = 10, amount_min = 1, amount_max = 8 }, - }, - } - } +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 - -- Bonus loot for v6 mapgen: Otherwise unobtainable saplings. - if mg_name == "v6" then - table.insert(loottable, { - stacks_min = 1, - stacks_max = 3, - items = { - { itemstring = "mcl_core:birchsapling", weight = 1, amount_min = 1, amount_max = 2 }, - { itemstring = "mcl_core:acaciasapling", weight = 1, amount_min = 1, amount_max = 2 }, - { itemstring = "", weight = 6 }, - }, - }) +-- Calculate the number of dungeon spawn attempts +-- In Minecraft, there 8 dungeon spawn attempts Minecraft chunk (16*256*16 = 65536 blocks). +-- Minetest chunks don't have this size, so scale the number accordingly. +local attempts = math.ceil(((mcl_vars.chunksize * mcl_vars.MAP_BLOCKSIZE) ^ 3) / 8192) -- 63 = 80*80*80/8192 + +local dungeonsizes = { + { x=5, y=4, z=5}, + { x=5, y=4, z=7}, + { x=7, y=4, z=5}, + { x=7, y=4, z=7}, +} + +local dirs = { + { x= 1, y=0, z= 0 }, + { x= 0, y=0, z= 1 }, + { x=-1, y=0, z= 0 }, + { x= 0, y=0, z=-1 }, +} + +local surround_vectors = { + { x=-1, y=0, z=0 }, + { x=1, y=0, z=0 }, + { x=0, y=0, z=-1 }, + { x=0, y=0, z=1 }, +} + +local function ecb_spawn_dungeon(blockpos, action, calls_remaining, param) + if calls_remaining >= 1 then return end + + local p1, p2, dim, pr = param.p1, param.p2, param.dim, param.pr + local x, y, z = p1.x, p1.y, p1.z + local check = not (param.dontcheck or false) + + -- Check floor and ceiling: Must be *completely* solid + 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 + end end end + + -- Check for air openings (2 stacked air at ground level) in wall positions + local openings_counter = 0 + -- Store positions of openings; walls will not be generated here + local openings = {} + -- Corners are stored because a corner-only opening needs to be increased, + -- so entities can get through. + local corners = {} + + 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 + 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 - local items = mcl_loot.get_multi_loot(loottable, pr) - - return items -end - - --- Buffer for LuaVoxelManip -local lvm_buffer = {} - --- Below the bedrock, generate air/void -minetest.register_on_generated(function(minp, maxp) - if maxp.y < mcl_vars.mg_overworld_min or minp.y > mcl_vars.mg_overworld_max then - return + 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 + 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 + 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 + openings_counter = openings_counter + 1 + if not openings[x2] then openings[x2]={} end + openings[x2][z2] = true + table.insert(corners, {x=x2, z=z2}) end - local vm, emin, emax = minetest.get_mapgen_object("voxelmanip") - local data = vm:get_data(lvm_buffer) - local area = VoxelArea:new({MinEdge=emin, MaxEdge=emax}) - local lvm_used = false + 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 + 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 + openings_counter = openings_counter + 1 + if check and openings_counter > 5 then return end + if not openings[wx] then openings[wx]={} end + openings[wx][z2] = true + 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 + 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 + openings_counter = openings_counter + 1 + if check and openings_counter > 5 then return end + if not openings[x2] then openings[x2]={} end + openings[x2][wz] = true + end + end - local c_air = minetest.get_content_id("air") - local c_cobble = minetest.get_content_id("mcl_core:cobble") - local c_mossycobble = minetest.get_content_id("mcl_core:mossycobble") + -- If all openings are only at corners, the dungeon can't be accessed yet. + -- This code extends the openings of corners so they can be entered. + if openings_counter >= 1 and openings_counter == #corners then + for c=1, #corners do + -- Prevent creating too many openings because this would lead to dungeon rejection + if openings_counter >= 5 then + break + end + -- A corner is widened by adding openings to both neighbors + local cx, cz = corners[c].x, corners[c].z + local cxn, czn = cx, cz + if x == cx then + cxn = cxn + 1 + else + cxn = cxn - 1 + end + if z == cz then + czn = czn + 1 + else + czn = czn - 1 + end + openings[cx][czn] = true + openings_counter = openings_counter + 1 + if openings_counter < 5 then + if not openings[cxn] then openings[cxn]={} end + openings[cxn][cz] = true + openings_counter = openings_counter + 1 + end + end + end + + -- Check conditions. If okay, start generating + if check and (openings_counter < 1 or openings_counter > 5) then return end + + minetest.log("action","[mcl_dungeons] Placing new dungeon at "..minetest.pos_to_string({x=x,y=y,z=z})) + -- Okay! Spawning starts! -- Remember spawner chest positions to set metadata later - local chest_posses = {} + local chests = {} local spawner_posses = {} - -- Calculate the number of dungeon spawn attempts - local sizevector = vector.subtract(maxp, minp) - sizevector = vector.add(sizevector, 1) - local chunksize = sizevector.x * sizevector.y * sizevector.z + -- First prepare random chest positions. + -- Chests spawn at wall - -- In Minecraft, there 8 dungeon spawn attempts Minecraft chunk (16*256*16 = 65536 blocks). - -- Minetest chunks don't have this size, so scale the number accordingly. - local attempts = math.ceil(chunksize / 65536 * 8) - - for a=1, attempts do - local x, y, z - local b = 7 -- buffer - x = math.random(minp.x+b, maxp.x-b) - - local ymin = math.min(mcl_vars.mg_overworld_max, math.max(minp.y, mcl_vars.mg_bedrock_overworld_max) + 7) - local ymax = math.min(mcl_vars.mg_overworld_max, math.max(maxp.y, mcl_vars.mg_bedrock_overworld_max) - 4) - - y = math.random(ymin, ymax) - z = math.random(minp.z+b, maxp.z-b) - - local dungeonsizes = { - { x=5, y=4, z=5}, - { x=5, y=4, z=7}, - { x=7, y=4, z=5}, - { x=7, y=4, z=7}, - } - local dim = dungeonsizes[math.random(1, #dungeonsizes)] - - -- Check floor and ceiling: Must be *completely* solid - local ceilingfloor_ok = true - for tx = x, x+dim.x do - for tz = z, z+dim.z do - local floor = minetest.get_name_from_content_id(data[area:index(tx, y, tz)]) - local ceiling = minetest.get_name_from_content_id(data[area:index(tx, y+dim.y+1, tz)]) - if (not minetest.registered_nodes[floor].walkable) or (not minetest.registered_nodes[ceiling].walkable) then - ceilingfloor_ok = false - break - end - end - if not ceilingfloor_ok then break end + -- We assign each position at the wall a number and each chest gets one of these numbers randomly + local totalChests = 2 -- this code strongly relies on this number being 2 + local totalChestSlots = (dim.x + dim.z - 2) * 2 + local chestSlots = {} + -- There is a small chance that both chests have the same slot. + -- In that case, we give a 2nd chance for the 2nd chest to get spawned. + -- If it failed again, tough luck! We stick with only 1 chest spawned. + local lastRandom + local secondChance = true -- second chance is still available + for i=1, totalChests do + local r = pr:next(1, totalChestSlots) + if r == lastRandom and secondChance then + -- Oops! Same slot selected. Try again. + r = pr:next(1, totalChestSlots) + secondChance = false end + lastRandom = r + table.insert(chestSlots, r) + end + table.sort(chestSlots) + local currentChest = 1 - -- Check for air openings (2 stacked air at ground level) in wall positions - local openings_counter = 0 - -- Store positions of openings; walls will not be generated here - local openings = {} - -- Corners are stored because a corner-only opening needs to be increased, - -- so entities can get through. - local corners = {} - if ceilingfloor_ok then - - local walls = { - -- walls along x axis (contain corners) - { x, x+dim.x+1, "x", "z", z }, - { x, x+dim.x+1, "x", "z", z+dim.z+1 }, - -- walls along z axis (exclude corners) - { z+1, z+dim.z, "z", "x", x }, - { z+1, z+dim.z, "z", "x", x+dim.x+1 }, - } - - for w=1, #walls do - local wall = walls[w] - for iter = wall[1], wall[2] do - local pos = {} - pos[wall[3]] = iter - pos[wall[4]] = wall[5] - pos.y = y+1 - - if openings[pos.x] == nil then openings[pos.x] = {} end - - local door1 = area:index(pos.x, pos.y, pos.z) - pos.y = y+2 - local door2 = area:index(pos.x, pos.y, pos.z) - local doorname1 = minetest.get_name_from_content_id(data[door1]) - local doorname2 = minetest.get_name_from_content_id(data[door2]) - if doorname1 == "air" and doorname2 == "air" then - openings_counter = openings_counter + 1 - openings[pos.x][pos.z] = true - - -- Record corners - if wall[3] == "x" and (iter == wall[1] or iter == wall[2]) then - table.insert(corners, {x=pos.x, z=pos.z}) - end - end - end - end - - end - - -- If all openings are only at corners, the dungeon can't be accessed yet. - -- This code extends the openings of corners so they can be entered. - if openings_counter >= 1 and openings_counter == #corners then - for c=1, #corners do - -- Prevent creating too many openings because this would lead to dungeon rejection - if openings_counter >= 5 then - break - end - -- A corner is widened by adding openings to both neighbors - local cx, cz = corners[c].x, corners[c].z - local cxn, czn = cx, cz - if x == cx then - cxn = cxn + 1 - else - cxn = cxn - 1 - end - if z == cz then - czn = czn + 1 - else - czn = czn - 1 - end - openings[cx][czn] = true - openings_counter = openings_counter + 1 - if openings_counter < 5 then - openings[cxn][cz] = true - openings_counter = openings_counter + 1 - end - end - end - - -- Check conditions. If okay, start generating - if ceilingfloor_ok and openings_counter >= 1 and openings_counter <= 5 then - -- Okay! Spawning starts! - - -- First prepare random chest positions. - -- Chests spawn at wall - - -- We assign each position at the wall a number and each chest gets one of these numbers randomly - local totalChests = 2 -- this code strongly relies on this number being 2 - local totalChestSlots = (dim.x-1) * (dim.z-1) - local chestSlots = {} - -- There is a small chance that both chests have the same slot. - -- In that case, we give a 2nd chance for the 2nd chest to get spawned. - -- If it failed again, tough luck! We stick with only 1 chest spawned. - local lastRandom - local secondChance = true -- second chance is still available - for i=1, totalChests do - local r = math.random(1, totalChestSlots) - if r == lastRandom and secondChance then - -- Oops! Same slot selected. Try again. - r = math.random(1, totalChestSlots) - secondChance = false - end - lastRandom = r - table.insert(chestSlots, r) - end - table.sort(chestSlots) - local currentChest = 1 - - -- Calculate the mob spawner position, to be re-used for later - local spawner_pos = {x = x + math.ceil(dim.x/2), y = y+1, z = z + math.ceil(dim.z/2)} - table.insert(spawner_posses, spawner_pos) - - -- Generate walls and floor - local maxx, maxy, maxz = x+dim.x+1, y+dim.y, z+dim.z+1 - local chestSlotCounter = 1 - for tx = x, maxx do - for tz = z, maxz do - for ty = y, maxy do - local p_pos = area:index(tx, ty, tz) - - -- 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 = minetest.get_name_from_content_id(data[p_pos]) - if name == "mcl_core:cobble" or name == "mcl_core:mossycobble" or minetest.registered_nodes[name].is_ground_content then - -- Floor - if ty == y then - if math.random(1,4) == 1 then - data[p_pos] = c_cobble - else - data[p_pos] = c_mossycobble - end - - -- Generate walls - --[[ Note: No additional cobblestone ceiling is generated. This is intentional. - The solid blocks above the dungeon are considered as the “ceiling”. - It is possible (but rare) for a dungeon to generate below sand or gravel. ]] - - elseif ty > y and (tx == x or tx == maxx or (tz == z or tz == maxz)) then - -- Check if it's an opening first - if (not openings[tx][tz]) or ty == maxy then - -- Place wall or ceiling - data[p_pos] = c_cobble - elseif ty < maxy - 1 then - -- Normally the openings are already clear, but not if it is a corner - -- widening. Make sure to clear at least the bottom 2 nodes of an opening. - data[p_pos] = c_air - elseif ty == maxy - 1 and data[p_pos] ~= c_air then - -- This allows for variation between 2-node and 3-node high openings. - data[p_pos] = c_cobble - end - -- If it was an opening, the lower 3 blocks are not touched at all - - -- Room interiour - else - local forChest = ty==y+1 and (tx==x+1 or tx==maxx-1 or tz==z+1 or tz==maxz-1) - - -- Place next chest at the wall (if it was its chosen wall slot) - if forChest and (currentChest < totalChests + 1) and (chestSlots[currentChest] == chestSlotCounter) then - table.insert(chest_posses, {x=tx, y=ty, z=tz}) - currentChest = currentChest + 1 - else - data[p_pos] = c_air - end - if forChest then - chestSlotCounter = chestSlotCounter + 1 - end - end - end - - end - end - end - end - - lvm_used = true + -- 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] + if rn and rn.is_ground_content then + table.insert(spawner_posses, sp) end - if lvm_used then - local chest_param2 = {} - -- Determine correct chest rotation (must pointi outwards) - for c=1, #chest_posses do - local cpos = chest_posses[c] + -- Generate walls and floor + local maxx, maxy, maxz = x+dim.x+1, y+dim.y, z+dim.z+1 + local chestSlotCounter = 1 + for tx = x, maxx do + for tz = z, maxz do + for ty = y, maxy do + local p = {x = tx, y=ty, z=tz} - -- Check surroundings of chest to determine correct rotation - local surround_vectors = { - { x=-1, y=0, z=0 }, - { x=1, y=0, z=0 }, - { x=0, y=0, z=-1 }, - { x=0, y=0, z=1 }, - } - local surroundings = {} - - for s=1, #surround_vectors do - -- Detect the 4 horizontal neighbors - local spos = vector.add(cpos, surround_vectors[s]) - local wpos = vector.subtract(cpos, surround_vectors[s]) - local p_pos = area:index(spos.x, spos.y, spos.z) - local p_pos2 = area:index(wpos.x, wpos.y, wpos.z) - - local nodename = minetest.get_name_from_content_id(data[p_pos]) - local nodename2 = minetest.get_name_from_content_id(data[p_pos2]) - 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 - if nodedef and nodedef.walkable == false and nodedef2 and nodedef2.walkable == true and nodename2 ~= "mcl_chests:chest" then - table.insert(surroundings, spos) + -- 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 + if minetest.registered_nodes[name].is_ground_content or name == "mcl_core:cobble" or name == "mcl_core:mossycobble" then + -- Floor + if ty == y then + if pr:next(1,4) == 1 then + minetest.swap_node(p, {name = "mcl_core:cobble"}) + else + minetest.swap_node(p, {name = "mcl_core:mossycobble"}) end - end - -- Set param2 (=facedir) of this chest - local facedir - if #surroundings <= 0 then - -- Fallback if chest ended up in the middle of a room for some reason - facedir = math.random(0, 0) + + -- Generate walls + --[[ Note: No additional cobblestone ceiling is generated. This is intentional. + The solid blocks above the dungeon are considered as the “ceiling”. + It is possible (but rare) for a dungeon to generate below sand or gravel. ]] + + elseif tx == x or tz == z or tx == maxx or tz == maxz then + -- Check if it's an opening first + if (ty == maxy) or (not (openings[tx] and openings[tx][tz])) then + -- Place wall or ceiling + minetest.swap_node(p, {name = "mcl_core:cobble"}) + elseif ty < maxy - 1 then + -- Normally the openings are already clear, but not if it is a corner + -- widening. Make sure to clear at least the bottom 2 nodes of an opening. + if name ~= "air" then minetest.swap_node(p, {name = "air"}) end + elseif name ~= "air" then + -- This allows for variation between 2-node and 3-node high openings. + minetest.swap_node(p, {name = "mcl_core:cobble"}) + end + -- If it was an opening, the lower 3 blocks are not touched at all + + -- Room interiour else - -- 1 or multiple possible open directions: Choose random facedir - local face_to = surroundings[math.random(1, #surroundings)] - facedir = minetest.dir_to_facedir(vector.subtract(cpos, face_to)) + if (ty==y+1) and (tx==x+1 or tx==maxx-1 or tz==z+1 or tz==maxz-1) and (currentChest < totalChests + 1) and (chestSlots[currentChest] == chestSlotCounter) then + currentChest = currentChest + 1 + table.insert(chests, {x=tx, y=ty, z=tz}) + else + minetest.swap_node(p, {name = "air"}) + end + + local forChest = ty==y+1 and (tx==x+1 or tx==maxx-1 or tz==z+1 or tz==maxz-1) + + -- Place next chest at the wall (if it was its chosen wall slot) + if forChest and (currentChest < totalChests + 1) and (chestSlots[currentChest] == chestSlotCounter) then + currentChest = currentChest + 1 + table.insert(chests, {x=tx, y=ty, z=tz}) + else + --minetest.swap_node(p, {name = "air"}) + end + if forChest then + chestSlotCounter = chestSlotCounter + 1 + end end - chest_param2[c] = facedir + end + end end end + + for c=#chests, 1, -1 do + local pos = chests[c] + + local surroundings = {} + for s=1, #surround_vectors do + -- Detect the 4 horizontal neighbors + local spos = vector.add(pos, surround_vectors[s]) + local wpos = vector.subtract(pos, surround_vectors[s]) + local nodename = minetest.get_node(spos).name + local nodename2 = minetest.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 + if nodedef and nodedef.walkable == false and nodedef2 and nodedef2.walkable == true and nodename2 ~= "mcl_chests:chest" then + table.insert(surroundings, spos) + end + end + -- Set param2 (=facedir) of this chest + local facedir + if #surroundings <= 0 then + -- Fallback if chest ended up in the middle of a room for some reason + facedir = pr:next(0, 0) + else + -- 1 or multiple possible open directions: Choose random facedir + local face_to = surroundings[pr:next(1, #surroundings)] + facedir = minetest.dir_to_facedir(vector.subtract(pos, face_to)) end - -- Finally generate the dungeons all at once (except the chests and the spawners) - vm:set_data(data) - vm:calc_lighting() - vm:update_liquids() - vm:write_to_map() + minetest.set_node(pos, {name="mcl_chests:chest", param2=facedir}) + local meta = minetest.get_meta(pos) - -- Chests are placed seperately - for c=1, #chest_posses do - local cpos = chest_posses[c] - minetest.set_node(cpos, {name="mcl_chests:chest", param2=chest_param2[c]}) - local meta = minetest.get_meta(cpos) - local inv = meta:get_inventory() - local items = get_loot() - mcl_loot.fill_inventory(inv, "main", items) - end - - -- Mob spawners are placed seperately, too - -- We don't want to destroy non-ground nodes - for s=1, #spawner_posses do - local sp = spawner_posses[s] - local n = minetest.get_name_from_content_id(data[area:index(sp.x,sp.y,sp.z)]) - if minetest.registered_nodes[n].is_ground_content then - - -- ... and place it and select a random mob - minetest.set_node(sp, {name = "mcl_mobspawners:spawner"}) - local mobs = { - "mobs_mc:zombie", - "mobs_mc:zombie", - "mobs_mc:spider", - "mobs_mc:skeleton", + local loottable = + { + { + stacks_min = 1, + stacks_max = 3, + items = { + { itemstring = "mcl_mobs:nametag", weight = 20 }, + { itemstring = "mcl_mobitems:saddle", weight = 20 }, + { itemstring = "mcl_jukebox:record_1", weight = 15 }, + { itemstring = "mcl_jukebox:record_4", weight = 15 }, + { itemstring = "mobs_mc:iron_horse_armor", weight = 15 }, + { itemstring = "mcl_core:apple_gold", weight = 15 }, + { itemstack = mcl_enchanting.get_uniform_randomly_enchanted_book({"soul_speed"}, pr), weight = 10 }, + { itemstring = "mobs_mc:gold_horse_armor", weight = 10 }, + { itemstring = "mobs_mc:diamond_horse_armor", weight = 5 }, + { itemstring = "mcl_core:apple_gold_enchanted", weight = 2 }, } - local spawner_mob = mobs[math.random(1, #mobs)] + }, + { + stacks_min = 1, + stacks_max = 4, + items = { + { itemstring = "mcl_farming:wheat_item", weight = 20, amount_min = 1, amount_max = 4 }, + { itemstring = "mcl_farming:bread", weight = 20 }, + { itemstring = "mcl_core:coal_lump", weight = 15, amount_min = 1, amount_max = 4 }, + { itemstring = "mesecons:redstone", weight = 15, amount_min = 1, amount_max = 4 }, + { itemstring = "mcl_farming:beetroot_seeds", weight = 10, amount_min = 2, amount_max = 4 }, + { itemstring = "mcl_farming:melon_seeds", weight = 10, amount_min = 2, amount_max = 4 }, + { itemstring = "mcl_farming:pumpkin_seeds", weight = 10, amount_min = 2, amount_max = 4 }, + { itemstring = "mcl_core:iron_ingot", weight = 10, amount_min = 1, amount_max = 4 }, + { itemstring = "mcl_buckets:bucket_empty", weight = 10 }, + { itemstring = "mcl_core:gold_ingot", weight = 5, amount_min = 1, amount_max = 4 }, + }, + }, + { + stacks_min = 3, + stacks_max = 3, + items = { + { itemstring = "mcl_mobitems:bone", weight = 10, amount_min = 1, amount_max = 8 }, + { itemstring = "mcl_mobitems:gunpowder", weight = 10, amount_min = 1, amount_max = 8 }, + { itemstring = "mcl_mobitems:rotten_flesh", weight = 10, amount_min = 1, amount_max = 8 }, + { itemstring = "mcl_mobitems:string", weight = 10, amount_min = 1, amount_max = 8 }, + }, + } + } - mcl_mobspawners.setup_spawner(sp, spawner_mob, 0, 7) - end + -- Bonus loot for v6 mapgen: Otherwise unobtainable saplings. + if mg_name == "v6" then + table.insert(loottable, { + stacks_min = 1, + stacks_max = 3, + items = { + { itemstring = "mcl_core:birchsapling", weight = 1, amount_min = 1, amount_max = 2 }, + { itemstring = "mcl_core:acaciasapling", weight = 1, amount_min = 1, amount_max = 2 }, + { itemstring = "", weight = 6 }, + }, + }) end + mcl_loot.fill_inventory(meta:get_inventory(), "main", mcl_loot.get_multi_loot(loottable, pr), pr) end -end) + -- Mob spawners are placed seperately, too + -- We don't want to destroy non-ground nodes + for s=#spawner_posses, 1, -1 do + local sp = spawner_posses[s] + -- ... and place it and select a random mob + minetest.set_node(sp, {name = "mcl_mobspawners:spawner"}) + local mobs = { + "mobs_mc:zombie", + "mobs_mc:zombie", + "mobs_mc:spider", + "mobs_mc:skeleton", + } + local spawner_mob = mobs[pr:next(1, #mobs)] + + mcl_mobspawners.setup_spawner(sp, spawner_mob, 0, 7) + end end + +local function dungeons_nodes(minp, maxp, blockseed) + local ymin, ymax = math.max(min_y, minp.y), math.min(max_y, maxp.y) + if ymax < ymin then return false end + local pr = PseudoRandom(blockseed) + for a=1, attempts do + local dim = dungeonsizes[pr:next(1, #dungeonsizes)] + local x = pr:next(minp.x, maxp.x-dim.x-1) + local y = pr:next(ymin , ymax -dim.y-1) + local z = pr:next(minp.z, maxp.z-dim.z-1) + local p1 = {x=x,y=y,z=z} + local p2 = {x = x+dim.x+1, y = y+dim.y+1, z = z+dim.z+1} + minetest.log("verbose","[mcl_dungeons] size=" ..minetest.pos_to_string(dim) .. ", emerge from "..minetest.pos_to_string(p1) .. " to " .. minetest.pos_to_string(p2)) + local param = {p1=p1, p2=p2, dim=dim, pr=pr} + minetest.emerge_area(p1, p2, ecb_spawn_dungeon, param) + end +end + +function mcl_dungeons.spawn_dungeon(p1, _, pr) + if not p1 or not pr or not p1.x or not p1.y or not p1.z then return end + local dim = dungeonsizes[pr:next(1, #dungeonsizes)] + local p2 = {x = p1.x+dim.x+1, y = p1.y+dim.y+1, z = p1.z+dim.z+1} + minetest.log("verbose","[mcl_dungeons] size=" ..minetest.pos_to_string(dim) .. ", emerge from "..minetest.pos_to_string(p1) .. " to " .. minetest.pos_to_string(p2)) + local param = {p1=p1, p2=p2, dim=dim, pr=pr, dontcheck=true} + minetest.emerge_area(p1, p2, ecb_spawn_dungeon, param) +end + +mcl_mapgen_core.register_generator("dungeons", nil, dungeons_nodes, 999999) diff --git a/mods/MAPGEN/mcl_dungeons/mod.conf b/mods/MAPGEN/mcl_dungeons/mod.conf index d6af72a27..fe02286fa 100644 --- a/mods/MAPGEN/mcl_dungeons/mod.conf +++ b/mods/MAPGEN/mcl_dungeons/mod.conf @@ -1 +1,4 @@ name = mcl_dungeons +author = Wuzzy +description = Generates random dungeons in the world +depends = mcl_init, mcl_core, mcl_chests, mcl_mobs, mcl_mobspawners, mcl_mapgen_core, mobs_mc diff --git a/mods/MAPGEN/mcl_mapgen_core/depends.txt b/mods/MAPGEN/mcl_mapgen_core/depends.txt deleted file mode 100644 index 4aa96f053..000000000 --- a/mods/MAPGEN/mcl_mapgen_core/depends.txt +++ /dev/null @@ -1,11 +0,0 @@ -mcl_init -mcl_core -biomeinfo -mclx_core? -mcl_worlds -mcl_cocoas -mcl_sponges -mcl_ocean -mcl_stairs -mcl_monster_eggs -mcl_structures diff --git a/mods/MAPGEN/mcl_mapgen_core/init.lua b/mods/MAPGEN/mcl_mapgen_core/init.lua index 8e75de910..2986664f6 100644 --- a/mods/MAPGEN/mcl_mapgen_core/init.lua +++ b/mods/MAPGEN/mcl_mapgen_core/init.lua @@ -1,3 +1,46 @@ +mcl_mapgen_core = {} +mcl_mapgen_core.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 + -- -- Aliases for map generator outputs -- @@ -180,415 +223,417 @@ minetest.register_ore({ } }) --- --- Coal --- - --- Common spawn -minetest.register_ore({ - ore_type = "scatter", - ore = "mcl_core:stone_with_coal", - wherein = stonelike, - clust_scarcity = 525*3, - clust_num_ores = 5, - clust_size = 3, - y_min = mcl_vars.mg_overworld_min, - y_max = mcl_worlds.layer_to_y(50), -}) -minetest.register_ore({ - ore_type = "scatter", - ore = "mcl_core:stone_with_coal", - wherein = stonelike, - clust_scarcity = 510*3, - clust_num_ores = 8, - clust_size = 3, - y_min = mcl_vars.mg_overworld_min, - y_max = mcl_worlds.layer_to_y(50), -}) -minetest.register_ore({ - ore_type = "scatter", - ore = "mcl_core:stone_with_coal", - wherein = stonelike, - clust_scarcity = 500*3, - clust_num_ores = 12, - clust_size = 3, - y_min = mcl_vars.mg_overworld_min, - y_max = mcl_worlds.layer_to_y(50), -}) - --- Medium-rare spawn -minetest.register_ore({ - ore_type = "scatter", - ore = "mcl_core:stone_with_coal", - wherein = stonelike, - clust_scarcity = 550*3, - clust_num_ores = 4, - clust_size = 2, - y_min = mcl_worlds.layer_to_y(51), - y_max = mcl_worlds.layer_to_y(80), -}) -minetest.register_ore({ - ore_type = "scatter", - ore = "mcl_core:stone_with_coal", - wherein = stonelike, - clust_scarcity = 525*3, - clust_num_ores = 6, - clust_size = 3, - y_min = mcl_worlds.layer_to_y(51), - y_max = mcl_worlds.layer_to_y(80), -}) -minetest.register_ore({ - ore_type = "scatter", - ore = "mcl_core:stone_with_coal", - wherein = stonelike, - clust_scarcity = 500*3, - clust_num_ores = 8, - clust_size = 3, - y_min = mcl_worlds.layer_to_y(51), - y_max = mcl_worlds.layer_to_y(80), -}) - --- Rare spawn -minetest.register_ore({ - ore_type = "scatter", - ore = "mcl_core:stone_with_coal", - wherein = stonelike, - clust_scarcity = 600*3, - clust_num_ores = 3, - clust_size = 2, - y_min = mcl_worlds.layer_to_y(81), - y_max = mcl_worlds.layer_to_y(128), -}) -minetest.register_ore({ - ore_type = "scatter", - ore = "mcl_core:stone_with_coal", - wherein = stonelike, - clust_scarcity = 550*3, - clust_num_ores = 4, - clust_size = 3, - y_min = mcl_worlds.layer_to_y(81), - y_max = mcl_worlds.layer_to_y(128), -}) -minetest.register_ore({ - ore_type = "scatter", - ore = "mcl_core:stone_with_coal", - wherein = stonelike, - clust_scarcity = 500*3, - clust_num_ores = 5, - clust_size = 3, - y_min = mcl_worlds.layer_to_y(81), - y_max = mcl_worlds.layer_to_y(128), -}) - --- --- Iron --- -minetest.register_ore({ - ore_type = "scatter", - ore = "mcl_core:stone_with_iron", - wherein = stonelike, - clust_scarcity = 830, - clust_num_ores = 5, - clust_size = 3, - y_min = mcl_vars.mg_overworld_min, - y_max = mcl_worlds.layer_to_y(39), -}) -minetest.register_ore({ - ore_type = "scatter", - ore = "mcl_core:stone_with_iron", - wherein = stonelike, - clust_scarcity = 1660, - clust_num_ores = 4, - clust_size = 2, - y_min = mcl_worlds.layer_to_y(40), - y_max = mcl_worlds.layer_to_y(63), -}) - --- --- Gold --- - --- Common spawn -minetest.register_ore({ - ore_type = "scatter", - ore = "mcl_core:stone_with_gold", - wherein = stonelike, - clust_scarcity = 4775, - clust_num_ores = 5, - clust_size = 3, - y_min = mcl_vars.mg_overworld_min, - y_max = mcl_worlds.layer_to_y(30), -}) -minetest.register_ore({ - ore_type = "scatter", - ore = "mcl_core:stone_with_gold", - wherein = stonelike, - clust_scarcity = 6560, - clust_num_ores = 7, - clust_size = 3, - y_min = mcl_vars.mg_overworld_min, - y_max = mcl_worlds.layer_to_y(30), -}) - --- Rare spawn -minetest.register_ore({ - ore_type = "scatter", - ore = "mcl_core:stone_with_gold", - wherein = stonelike, - clust_scarcity = 13000, - clust_num_ores = 4, - clust_size = 2, - y_min = mcl_worlds.layer_to_y(31), - y_max = mcl_worlds.layer_to_y(33), -}) - --- --- Diamond --- - --- Common spawn -minetest.register_ore({ - ore_type = "scatter", - ore = "mcl_core:stone_with_diamond", - wherein = stonelike, - clust_scarcity = 10000, - clust_num_ores = 4, - clust_size = 3, - y_min = mcl_vars.mg_overworld_min, - y_max = mcl_worlds.layer_to_y(12), -}) -minetest.register_ore({ - ore_type = "scatter", - ore = "mcl_core:stone_with_diamond", - wherein = stonelike, - clust_scarcity = 5000, - clust_num_ores = 2, - clust_size = 2, - y_min = mcl_vars.mg_overworld_min, - y_max = mcl_worlds.layer_to_y(12), -}) -minetest.register_ore({ - ore_type = "scatter", - ore = "mcl_core:stone_with_diamond", - wherein = stonelike, - clust_scarcity = 10000, - clust_num_ores = 8, - clust_size = 3, - y_min = mcl_vars.mg_overworld_min, - y_max = mcl_worlds.layer_to_y(12), -}) - --- Rare spawn -minetest.register_ore({ - ore_type = "scatter", - ore = "mcl_core:stone_with_diamond", - wherein = stonelike, - clust_scarcity = 20000, - clust_num_ores = 1, - clust_size = 1, - y_min = mcl_worlds.layer_to_y(13), - y_max = mcl_worlds.layer_to_y(15), -}) -minetest.register_ore({ - ore_type = "scatter", - ore = "mcl_core:stone_with_diamond", - wherein = stonelike, - clust_scarcity = 20000, - clust_num_ores = 2, - clust_size = 2, - y_min = mcl_worlds.layer_to_y(13), - y_max = mcl_worlds.layer_to_y(15), -}) - --- --- Redstone --- - --- Common spawn -minetest.register_ore({ - ore_type = "scatter", - ore = "mcl_core:stone_with_redstone", - wherein = stonelike, - clust_scarcity = 500, - clust_num_ores = 4, - clust_size = 3, - y_min = mcl_vars.mg_overworld_min, - y_max = mcl_worlds.layer_to_y(13), -}) -minetest.register_ore({ - ore_type = "scatter", - ore = "mcl_core:stone_with_redstone", - wherein = stonelike, - clust_scarcity = 800, - clust_num_ores = 7, - clust_size = 4, - y_min = mcl_vars.mg_overworld_min, - y_max = mcl_worlds.layer_to_y(13), -}) - --- Rare spawn -minetest.register_ore({ - ore_type = "scatter", - ore = "mcl_core:stone_with_redstone", - wherein = stonelike, - clust_scarcity = 1000, - clust_num_ores = 4, - clust_size = 3, - y_min = mcl_worlds.layer_to_y(13), - y_max = mcl_worlds.layer_to_y(15), -}) -minetest.register_ore({ - ore_type = "scatter", - ore = "mcl_core:stone_with_redstone", - wherein = stonelike, - clust_scarcity = 1600, - clust_num_ores = 7, - clust_size = 4, - y_min = mcl_worlds.layer_to_y(13), - y_max = mcl_worlds.layer_to_y(15), -}) - --- --- Emerald --- - -if mg_name == "v6" then - -- Generate everywhere in v6, but rarely. +if minetest.settings:get_bool("mcl_generate_ores", true) then + -- + -- Coal + -- -- Common spawn minetest.register_ore({ ore_type = "scatter", - ore = "mcl_core:stone_with_emerald", + ore = "mcl_core:stone_with_coal", wherein = stonelike, - clust_scarcity = 14340, - clust_num_ores = 1, - clust_size = 1, + clust_scarcity = 525*3, + clust_num_ores = 5, + clust_size = 3, y_min = mcl_vars.mg_overworld_min, - y_max = mcl_worlds.layer_to_y(29), + y_max = mcl_worlds.layer_to_y(50), }) + minetest.register_ore({ + ore_type = "scatter", + ore = "mcl_core:stone_with_coal", + wherein = stonelike, + clust_scarcity = 510*3, + clust_num_ores = 8, + clust_size = 3, + y_min = mcl_vars.mg_overworld_min, + y_max = mcl_worlds.layer_to_y(50), + }) + minetest.register_ore({ + ore_type = "scatter", + ore = "mcl_core:stone_with_coal", + wherein = stonelike, + clust_scarcity = 500*3, + clust_num_ores = 12, + clust_size = 3, + y_min = mcl_vars.mg_overworld_min, + y_max = mcl_worlds.layer_to_y(50), + }) + + -- Medium-rare spawn + minetest.register_ore({ + ore_type = "scatter", + ore = "mcl_core:stone_with_coal", + wherein = stonelike, + clust_scarcity = 550*3, + clust_num_ores = 4, + clust_size = 2, + y_min = mcl_worlds.layer_to_y(51), + y_max = mcl_worlds.layer_to_y(80), + }) + minetest.register_ore({ + ore_type = "scatter", + ore = "mcl_core:stone_with_coal", + wherein = stonelike, + clust_scarcity = 525*3, + clust_num_ores = 6, + clust_size = 3, + y_min = mcl_worlds.layer_to_y(51), + y_max = mcl_worlds.layer_to_y(80), + }) + minetest.register_ore({ + ore_type = "scatter", + ore = "mcl_core:stone_with_coal", + wherein = stonelike, + clust_scarcity = 500*3, + clust_num_ores = 8, + clust_size = 3, + y_min = mcl_worlds.layer_to_y(51), + y_max = mcl_worlds.layer_to_y(80), + }) + -- Rare spawn minetest.register_ore({ ore_type = "scatter", - ore = "mcl_core:stone_with_emerald", - wherein = stonelike, - clust_scarcity = 21510, + ore = "mcl_core:stone_with_coal", + wherein = stonelike, + clust_scarcity = 600*3, + clust_num_ores = 3, + clust_size = 2, + y_min = mcl_worlds.layer_to_y(81), + y_max = mcl_worlds.layer_to_y(128), + }) + minetest.register_ore({ + ore_type = "scatter", + ore = "mcl_core:stone_with_coal", + wherein = stonelike, + clust_scarcity = 550*3, + clust_num_ores = 4, + clust_size = 3, + y_min = mcl_worlds.layer_to_y(81), + y_max = mcl_worlds.layer_to_y(128), + }) + minetest.register_ore({ + ore_type = "scatter", + ore = "mcl_core:stone_with_coal", + wherein = stonelike, + clust_scarcity = 500*3, + clust_num_ores = 5, + clust_size = 3, + y_min = mcl_worlds.layer_to_y(81), + y_max = mcl_worlds.layer_to_y(128), + }) + + -- + -- Iron + -- + minetest.register_ore({ + ore_type = "scatter", + ore = "mcl_core:stone_with_iron", + wherein = stonelike, + clust_scarcity = 830, + clust_num_ores = 5, + clust_size = 3, + y_min = mcl_vars.mg_overworld_min, + y_max = mcl_worlds.layer_to_y(39), + }) + minetest.register_ore({ + ore_type = "scatter", + ore = "mcl_core:stone_with_iron", + wherein = stonelike, + clust_scarcity = 1660, + clust_num_ores = 4, + clust_size = 2, + y_min = mcl_worlds.layer_to_y(40), + y_max = mcl_worlds.layer_to_y(63), + }) + + -- + -- Gold + -- + + -- Common spawn + minetest.register_ore({ + ore_type = "scatter", + ore = "mcl_core:stone_with_gold", + wherein = stonelike, + clust_scarcity = 4775, + clust_num_ores = 5, + clust_size = 3, + y_min = mcl_vars.mg_overworld_min, + y_max = mcl_worlds.layer_to_y(30), + }) + minetest.register_ore({ + ore_type = "scatter", + ore = "mcl_core:stone_with_gold", + wherein = stonelike, + clust_scarcity = 6560, + clust_num_ores = 7, + clust_size = 3, + y_min = mcl_vars.mg_overworld_min, + y_max = mcl_worlds.layer_to_y(30), + }) + + -- Rare spawn + minetest.register_ore({ + ore_type = "scatter", + ore = "mcl_core:stone_with_gold", + wherein = stonelike, + clust_scarcity = 13000, + clust_num_ores = 4, + clust_size = 2, + y_min = mcl_worlds.layer_to_y(31), + y_max = mcl_worlds.layer_to_y(33), + }) + + -- + -- Diamond + -- + + -- Common spawn + minetest.register_ore({ + ore_type = "scatter", + ore = "mcl_core:stone_with_diamond", + wherein = stonelike, + clust_scarcity = 10000, + clust_num_ores = 4, + clust_size = 3, + y_min = mcl_vars.mg_overworld_min, + y_max = mcl_worlds.layer_to_y(12), + }) + minetest.register_ore({ + ore_type = "scatter", + ore = "mcl_core:stone_with_diamond", + wherein = stonelike, + clust_scarcity = 5000, + clust_num_ores = 2, + clust_size = 2, + y_min = mcl_vars.mg_overworld_min, + y_max = mcl_worlds.layer_to_y(12), + }) + minetest.register_ore({ + ore_type = "scatter", + ore = "mcl_core:stone_with_diamond", + wherein = stonelike, + clust_scarcity = 10000, + clust_num_ores = 8, + clust_size = 3, + y_min = mcl_vars.mg_overworld_min, + y_max = mcl_worlds.layer_to_y(12), + }) + + -- Rare spawn + minetest.register_ore({ + ore_type = "scatter", + ore = "mcl_core:stone_with_diamond", + wherein = stonelike, + clust_scarcity = 20000, clust_num_ores = 1, clust_size = 1, - y_min = mcl_worlds.layer_to_y(30), + y_min = mcl_worlds.layer_to_y(13), + y_max = mcl_worlds.layer_to_y(15), + }) + minetest.register_ore({ + ore_type = "scatter", + ore = "mcl_core:stone_with_diamond", + wherein = stonelike, + clust_scarcity = 20000, + clust_num_ores = 2, + clust_size = 2, + y_min = mcl_worlds.layer_to_y(13), + y_max = mcl_worlds.layer_to_y(15), + }) + + -- + -- Redstone + -- + + -- Common spawn + minetest.register_ore({ + ore_type = "scatter", + ore = "mcl_core:stone_with_redstone", + wherein = stonelike, + clust_scarcity = 500, + clust_num_ores = 4, + clust_size = 3, + y_min = mcl_vars.mg_overworld_min, + y_max = mcl_worlds.layer_to_y(13), + }) + minetest.register_ore({ + ore_type = "scatter", + ore = "mcl_core:stone_with_redstone", + wherein = stonelike, + clust_scarcity = 800, + clust_num_ores = 7, + clust_size = 4, + y_min = mcl_vars.mg_overworld_min, + y_max = mcl_worlds.layer_to_y(13), + }) + + -- Rare spawn + minetest.register_ore({ + ore_type = "scatter", + ore = "mcl_core:stone_with_redstone", + wherein = stonelike, + clust_scarcity = 1000, + clust_num_ores = 4, + clust_size = 3, + y_min = mcl_worlds.layer_to_y(13), + y_max = mcl_worlds.layer_to_y(15), + }) + minetest.register_ore({ + ore_type = "scatter", + ore = "mcl_core:stone_with_redstone", + wherein = stonelike, + clust_scarcity = 1600, + clust_num_ores = 7, + clust_size = 4, + y_min = mcl_worlds.layer_to_y(13), + y_max = mcl_worlds.layer_to_y(15), + }) + + -- + -- Emerald + -- + + if mg_name == "v6" then + -- Generate everywhere in v6, but rarely. + + -- Common spawn + minetest.register_ore({ + ore_type = "scatter", + ore = "mcl_core:stone_with_emerald", + wherein = stonelike, + clust_scarcity = 14340, + clust_num_ores = 1, + clust_size = 1, + y_min = mcl_vars.mg_overworld_min, + y_max = mcl_worlds.layer_to_y(29), + }) + -- Rare spawn + minetest.register_ore({ + ore_type = "scatter", + ore = "mcl_core:stone_with_emerald", + wherein = stonelike, + clust_scarcity = 21510, + clust_num_ores = 1, + clust_size = 1, + y_min = mcl_worlds.layer_to_y(30), + y_max = mcl_worlds.layer_to_y(32), + }) + end + + -- + -- Lapis Lazuli + -- + + -- Common spawn (in the center) + minetest.register_ore({ + ore_type = "scatter", + ore = "mcl_core:stone_with_lapis", + wherein = stonelike, + clust_scarcity = 10000, + clust_num_ores = 7, + clust_size = 4, + y_min = mcl_worlds.layer_to_y(14), + y_max = mcl_worlds.layer_to_y(16), + }) + + -- Rare spawn (below center) + minetest.register_ore({ + ore_type = "scatter", + ore = "mcl_core:stone_with_lapis", + wherein = stonelike, + clust_scarcity = 12000, + clust_num_ores = 6, + clust_size = 3, + y_min = mcl_worlds.layer_to_y(10), + y_max = mcl_worlds.layer_to_y(13), + }) + minetest.register_ore({ + ore_type = "scatter", + ore = "mcl_core:stone_with_lapis", + wherein = stonelike, + clust_scarcity = 14000, + clust_num_ores = 5, + clust_size = 3, + y_min = mcl_worlds.layer_to_y(6), + y_max = mcl_worlds.layer_to_y(9), + }) + minetest.register_ore({ + ore_type = "scatter", + ore = "mcl_core:stone_with_lapis", + wherein = stonelike, + clust_scarcity = 16000, + clust_num_ores = 4, + clust_size = 3, + y_min = mcl_worlds.layer_to_y(2), + y_max = mcl_worlds.layer_to_y(5), + }) + minetest.register_ore({ + ore_type = "scatter", + ore = "mcl_core:stone_with_lapis", + wherein = stonelike, + clust_scarcity = 18000, + clust_num_ores = 3, + clust_size = 2, + y_min = mcl_worlds.layer_to_y(0), + y_max = mcl_worlds.layer_to_y(2), + }) + + -- Rare spawn (above center) + minetest.register_ore({ + ore_type = "scatter", + ore = "mcl_core:stone_with_lapis", + wherein = stonelike, + clust_scarcity = 12000, + clust_num_ores = 6, + clust_size = 3, + y_min = mcl_worlds.layer_to_y(17), + y_max = mcl_worlds.layer_to_y(20), + }) + minetest.register_ore({ + ore_type = "scatter", + ore = "mcl_core:stone_with_lapis", + wherein = stonelike, + clust_scarcity = 14000, + clust_num_ores = 5, + clust_size = 3, + y_min = mcl_worlds.layer_to_y(21), + y_max = mcl_worlds.layer_to_y(24), + }) + minetest.register_ore({ + ore_type = "scatter", + ore = "mcl_core:stone_with_lapis", + wherein = stonelike, + clust_scarcity = 16000, + clust_num_ores = 4, + clust_size = 3, + y_min = mcl_worlds.layer_to_y(25), + y_max = mcl_worlds.layer_to_y(28), + }) + minetest.register_ore({ + ore_type = "scatter", + ore = "mcl_core:stone_with_lapis", + wherein = stonelike, + clust_scarcity = 18000, + clust_num_ores = 3, + clust_size = 2, + y_min = mcl_worlds.layer_to_y(29), + y_max = mcl_worlds.layer_to_y(32), + }) + minetest.register_ore({ + ore_type = "scatter", + ore = "mcl_core:stone_with_lapis", + wherein = stonelike, + clust_scarcity = 32000, + clust_num_ores = 1, + clust_size = 1, + y_min = mcl_worlds.layer_to_y(31), y_max = mcl_worlds.layer_to_y(32), }) end --- --- Lapis Lazuli --- - --- Common spawn (in the center) -minetest.register_ore({ - ore_type = "scatter", - ore = "mcl_core:stone_with_lapis", - wherein = stonelike, - clust_scarcity = 10000, - clust_num_ores = 7, - clust_size = 4, - y_min = mcl_worlds.layer_to_y(14), - y_max = mcl_worlds.layer_to_y(16), -}) - --- Rare spawn (below center) -minetest.register_ore({ - ore_type = "scatter", - ore = "mcl_core:stone_with_lapis", - wherein = stonelike, - clust_scarcity = 12000, - clust_num_ores = 6, - clust_size = 3, - y_min = mcl_worlds.layer_to_y(10), - y_max = mcl_worlds.layer_to_y(13), -}) -minetest.register_ore({ - ore_type = "scatter", - ore = "mcl_core:stone_with_lapis", - wherein = stonelike, - clust_scarcity = 14000, - clust_num_ores = 5, - clust_size = 3, - y_min = mcl_worlds.layer_to_y(6), - y_max = mcl_worlds.layer_to_y(9), -}) -minetest.register_ore({ - ore_type = "scatter", - ore = "mcl_core:stone_with_lapis", - wherein = stonelike, - clust_scarcity = 16000, - clust_num_ores = 4, - clust_size = 3, - y_min = mcl_worlds.layer_to_y(2), - y_max = mcl_worlds.layer_to_y(5), -}) -minetest.register_ore({ - ore_type = "scatter", - ore = "mcl_core:stone_with_lapis", - wherein = stonelike, - clust_scarcity = 18000, - clust_num_ores = 3, - clust_size = 2, - y_min = mcl_worlds.layer_to_y(0), - y_max = mcl_worlds.layer_to_y(2), -}) - --- Rare spawn (above center) -minetest.register_ore({ - ore_type = "scatter", - ore = "mcl_core:stone_with_lapis", - wherein = stonelike, - clust_scarcity = 12000, - clust_num_ores = 6, - clust_size = 3, - y_min = mcl_worlds.layer_to_y(17), - y_max = mcl_worlds.layer_to_y(20), -}) -minetest.register_ore({ - ore_type = "scatter", - ore = "mcl_core:stone_with_lapis", - wherein = stonelike, - clust_scarcity = 14000, - clust_num_ores = 5, - clust_size = 3, - y_min = mcl_worlds.layer_to_y(21), - y_max = mcl_worlds.layer_to_y(24), -}) -minetest.register_ore({ - ore_type = "scatter", - ore = "mcl_core:stone_with_lapis", - wherein = stonelike, - clust_scarcity = 16000, - clust_num_ores = 4, - clust_size = 3, - y_min = mcl_worlds.layer_to_y(25), - y_max = mcl_worlds.layer_to_y(28), -}) -minetest.register_ore({ - ore_type = "scatter", - ore = "mcl_core:stone_with_lapis", - wherein = stonelike, - clust_scarcity = 18000, - clust_num_ores = 3, - clust_size = 2, - y_min = mcl_worlds.layer_to_y(29), - y_max = mcl_worlds.layer_to_y(32), -}) -minetest.register_ore({ - ore_type = "scatter", - ore = "mcl_core:stone_with_lapis", - wherein = stonelike, - clust_scarcity = 32000, - clust_num_ores = 1, - clust_size = 1, - y_min = mcl_worlds.layer_to_y(31), - y_max = mcl_worlds.layer_to_y(32), -}) - if not superflat then -- Water and lava springs (single blocks of lava/water source) -- Water appears at nearly every height, but not near the bottom @@ -1190,12 +1235,14 @@ local perlin_structures local perlin_vines, perlin_vines_fine, perlin_vines_upwards, perlin_vines_length, perlin_vines_density local perlin_clay -local function generate_clay(minp, maxp, seed, voxelmanip_data, voxelmanip_area, lvm_used) +local function generate_clay(minp, maxp, blockseed, voxelmanip_data, voxelmanip_area, lvm_used) -- TODO: Make clay generation reproducible for same seed. if maxp.y < -5 or minp.y > 0 then return lvm_used end + local pr = PseudoRandom(blockseed) + perlin_clay = perlin_clay or minetest.get_perlin({ offset = 0.5, scale = 0.2, @@ -1212,18 +1259,18 @@ local function generate_clay(minp, maxp, seed, voxelmanip_data, voxelmanip_area, for divx=0+1,divs-2 do for divz=0+1,divs-2 do -- Get position and shift it a bit randomly so the clay do not obviously appear in a grid - local cx = minp.x + math.floor((divx+0.5)*divlen) + math.random(-1,1) - local cz = minp.z + math.floor((divz+0.5)*divlen) + math.random(-1,1) + local cx = minp.x + math.floor((divx+0.5)*divlen) + pr:next(-1,1) + local cz = minp.z + math.floor((divz+0.5)*divlen) + pr:next(-1,1) local water_pos = voxelmanip_area:index(cx, y+1, cz) local waternode = voxelmanip_data[water_pos] local surface_pos = voxelmanip_area:index(cx, y, cz) local surfacenode = voxelmanip_data[surface_pos] - local genrnd = math.random(1, 20) + local genrnd = pr:next(1, 20) if genrnd == 1 and perlin_clay:get_3d({x=cx,y=y,z=cz}) > 0 and waternode == c_water and (surfacenode == c_dirt or minetest.get_item_group(minetest.get_name_from_content_id(surfacenode), "sand") == 1) then - local diamondsize = math.random(1, 3) + local diamondsize = pr:next(1, 3) for x1 = -diamondsize, diamondsize do for z1 = -(diamondsize - math.abs(x1)), diamondsize - math.abs(x1) do local ccpos = voxelmanip_area:index(cx+x1, y, cz+z1) @@ -1242,37 +1289,34 @@ local function generate_clay(minp, maxp, seed, voxelmanip_data, voxelmanip_area, end -- TODO: Try to use more efficient structure generating code -local function generate_structures(minp, maxp, seed, biomemap) +local function generate_structures(minp, maxp, blockseed, biomemap) local chunk_has_desert_well = false local chunk_has_desert_temple = false local chunk_has_igloo = false - local struct_min, struct_max = -3, 64 + local struct_min, struct_max = -3, 111 --64 + if maxp.y >= struct_min and minp.y <= struct_max then -- Generate structures - + local pr = PcgRandom(blockseed) perlin_structures = perlin_structures or minetest.get_perlin(329, 3, 0.6, 100) -- Assume X and Z lengths are equal local divlen = 5 - local divs = (maxp.x-minp.x)/divlen+1; - for divx=0,divs-1 do - for divz=0,divs-1 do - local x0 = minp.x + math.floor((divx+0)*divlen) - local z0 = minp.z + math.floor((divz+0)*divlen) - local x1 = minp.x + math.floor((divx+1)*divlen) - local z1 = minp.z + math.floor((divz+1)*divlen) + for x0 = minp.x, maxp.x, divlen do for z0 = minp.z, maxp.z, divlen do -- Determine amount from perlin noise local amount = math.floor(perlin_structures:get_2d({x=x0, y=z0}) * 9) -- Find random positions based on this random - local pr = PseudoRandom(seed+1) + local p, ground_y for i=0, amount do - local x = pr:next(x0, x1) - local z = pr:next(z0, z1) + p = {x = pr:next(x0, x0+divlen-1), y = 0, z = pr:next(z0, z0+divlen-1)} -- Find ground level - local ground_y = nil + ground_y = nil + local nn for y = struct_max, struct_min, -1 do - local checknode = minetest.get_node_or_nil({x=x,y=y,z=z}) + p.y = y + local checknode = minetest.get_node(p) if checknode then - local def = minetest.registered_nodes[checknode.name] + nn = checknode.name + local def = minetest.registered_nodes[nn] if def and def.walkable then ground_y = y break @@ -1281,21 +1325,17 @@ local function generate_structures(minp, maxp, seed, biomemap) end if ground_y then - local p = {x=x,y=ground_y+1,z=z} - local nn = minetest.get_node(p).name + p.y = ground_y+1 + local nn0 = minetest.get_node(p).name -- Check if the node can be replaced - if minetest.registered_nodes[nn] and - minetest.registered_nodes[nn].buildable_to then - nn = minetest.get_node({x=x,y=ground_y,z=z}).name - local struct = false - + if minetest.registered_nodes[nn0] and minetest.registered_nodes[nn0].buildable_to then -- Desert temples and desert wells if nn == "mcl_core:sand" or (nn == "mcl_core:sandstone") then if not chunk_has_desert_temple and not chunk_has_desert_well and ground_y > 3 then -- Spawn desert temple -- TODO: Check surface - if math.random(1,12000) == 1 then - mcl_structures.call_struct(p, "desert_temple") + if pr:next(1,12000) == 1 then + mcl_structures.call_struct(p, "desert_temple", nil, pr) chunk_has_desert_temple = true end end @@ -1303,11 +1343,11 @@ local function generate_structures(minp, maxp, seed, biomemap) local desert_well_prob = minecraft_chunk_probability(1000, minp, maxp) -- Spawn desert well - if math.random(1, desert_well_prob) == 1 then + if pr:next(1, desert_well_prob) == 1 then -- Check surface local surface = minetest.find_nodes_in_area({x=p.x,y=p.y-1,z=p.z}, {x=p.x+5, y=p.y-1, z=p.z+5}, "mcl_core:sand") if #surface >= 25 then - mcl_structures.call_struct(p, "desert_well") + mcl_structures.call_struct(p, "desert_well", nil, pr) chunk_has_desert_well = true end end @@ -1315,13 +1355,13 @@ local function generate_structures(minp, maxp, seed, biomemap) -- Igloos elseif not chunk_has_igloo and (nn == "mcl_core:snowblock" or nn == "mcl_core:snow" or (minetest.get_item_group(nn, "grass_block_snow") == 1)) then - if math.random(1, 4400) == 1 then + if pr:next(1, 4400) == 1 then -- Check surface local floor = {x=p.x+9, y=p.y-1, z=p.z+9} local surface = minetest.find_nodes_in_area({x=p.x,y=p.y-1,z=p.z}, floor, "mcl_core:snowblock") local surface2 = minetest.find_nodes_in_area({x=p.x,y=p.y-1,z=p.z}, floor, "mcl_core:dirt_with_grass_snow") if #surface + #surface2 >= 63 then - mcl_structures.call_struct(p, "igloo") + mcl_structures.call_struct(p, "igloo", nil, pr) chunk_has_igloo = true end end @@ -1331,16 +1371,16 @@ local function generate_structures(minp, maxp, seed, biomemap) if nn == "mcl_core:sandstone" or nn == "mcl_core:sand" and not chunk_has_desert_temple and ground_y > 3 then local fossil_prob = minecraft_chunk_probability(64, minp, maxp) - if math.random(1, fossil_prob) == 1 then + if pr:next(1, fossil_prob) == 1 then -- Spawn fossil below desert surface between layers 40 and 49 - local p1 = {x=p.x, y=math.random(mcl_worlds.layer_to_y(40), mcl_worlds.layer_to_y(49)), z=p.z} + local p1 = {x=p.x, y=pr:next(mcl_worlds.layer_to_y(40), mcl_worlds.layer_to_y(49)), z=p.z} -- Very rough check of the environment (we expect to have enough stonelike nodes). -- Fossils may still appear partially exposed in caves, but this is O.K. local p2 = vector.add(p1, 4) local nodes = minetest.find_nodes_in_area(p1, p2, {"mcl_core:sandstone", "mcl_core:stone", "mcl_core:diorite", "mcl_core:andesite", "mcl_core:granite", "mcl_core:stone_with_coal", "mcl_core:dirt", "mcl_core:gravel"}) if #nodes >= 100 then -- >= 80% - mcl_structures.call_struct(p1, "fossil") + mcl_structures.call_struct(p1, "fossil", nil, pr) end end end @@ -1348,7 +1388,7 @@ local function generate_structures(minp, maxp, seed, biomemap) -- Witch hut if ground_y <= 0 and nn == "mcl_core:dirt" then local prob = minecraft_chunk_probability(48, minp, maxp) - if math.random(1, prob) == 1 then + if pr:next(1, prob) == 1 then local swampland = minetest.get_biome_id("Swampland") local swampland_shore = minetest.get_biome_id("Swampland_shore") @@ -1370,7 +1410,7 @@ local function generate_structures(minp, maxp, seed, biomemap) end if here_be_witches then - local r = tostring(math.random(0, 3) * 90) -- "0", "90", "180" or 270" + local r = tostring(pr:next(0, 3) * 90) -- "0", "90", "180" or 270" local p1 = {x=p.x-1, y=WITCH_HUT_HEIGHT+2, z=p.z-1} local size if r == "0" or r == "180" then @@ -1389,7 +1429,7 @@ local function generate_structures(minp, maxp, seed, biomemap) -- FIXME: For some mysterious reason (black magic?) this -- function does sometimes NOT spawn the witch hut. One can only see the -- oak wood nodes in the water, but no hut. :-/ - mcl_structures.call_struct(place, "witch_hut", r) + mcl_structures.call_struct(place, "witch_hut", r, pr) -- TODO: Spawn witch in or around hut when the mob sucks less. @@ -1451,7 +1491,7 @@ local function generate_structures(minp, maxp, seed, biomemap) -- Ice spikes in v6 -- In other mapgens, ice spikes are generated as decorations. if mg_name == "v6" and not chunk_has_igloo and nn == "mcl_core:snowblock" then - local spike = math.random(1, 58000) + local spike = pr:next(1,58000) if spike < 3 then -- Check surface local floor = {x=p.x+4, y=p.y-1, z=p.z+4} @@ -1460,7 +1500,7 @@ local function generate_structures(minp, maxp, seed, biomemap) local spruce_collisions = minetest.find_nodes_in_area({x=p.x+1,y=p.y+2,z=p.z+1}, {x=p.x+4, y=p.y+6, z=p.z+4}, {"mcl_core:sprucetree", "mcl_core:spruceleaves"}) if #surface >= 9 and #spruce_collisions == 0 then - mcl_structures.call_struct(p, "ice_spike_large") + mcl_structures.call_struct(p, "ice_spike_large", nil, pr) end elseif spike < 100 then -- Check surface @@ -1471,7 +1511,7 @@ local function generate_structures(minp, maxp, seed, biomemap) local spruce_collisions = minetest.find_nodes_in_area({x=p.x+1,y=p.y+1,z=p.z+1}, {x=p.x+6, y=p.y+6, z=p.z+6}, {"mcl_core:sprucetree", "mcl_core:spruceleaves"}) if #surface >= 25 and #spruce_collisions == 0 then - mcl_structures.call_struct(p, "ice_spike_small") + mcl_structures.call_struct(p, "ice_spike_small", nil, pr) end end end @@ -1479,36 +1519,31 @@ local function generate_structures(minp, maxp, seed, biomemap) end end - end - end + end end -- End exit portal - elseif minp.y <= END_EXIT_PORTAL_POS.y and maxp.y >= END_EXIT_PORTAL_POS.y and - minp.x <= END_EXIT_PORTAL_POS.x and maxp.x >= END_EXIT_PORTAL_POS.x and - minp.z <= END_EXIT_PORTAL_POS.z and maxp.z >= END_EXIT_PORTAL_POS.z then - local built = false + elseif minp.y <= END_EXIT_PORTAL_POS.y and maxp.y >= END_EXIT_PORTAL_POS.y and + minp.x <= END_EXIT_PORTAL_POS.x and maxp.x >= END_EXIT_PORTAL_POS.x and + minp.z <= END_EXIT_PORTAL_POS.z and maxp.z >= END_EXIT_PORTAL_POS.z then for y=maxp.y, minp.y, -1 do local p = {x=END_EXIT_PORTAL_POS.x, y=y, z=END_EXIT_PORTAL_POS.z} if minetest.get_node(p).name == "mcl_end:end_stone" then mcl_structures.call_struct(p, "end_exit_portal") - built = true - break + return end end - if not built then - mcl_structures.call_struct(END_EXIT_PORTAL_POS, "end_exit_portal") - end + mcl_structures.call_struct(END_EXIT_PORTAL_POS, "end_exit_portal") end end -- Buffers for LuaVoxelManip -local lvm_buffer = {} -local lvm_buffer_param2 = {} +-- local lvm_buffer = {} +-- local lvm_buffer_param2 = {} -- Generate tree decorations in the bounding box. This adds: -- * Cocoa at jungle trees -- * Jungle tree vines -- * Oak vines in swamplands -local function generate_tree_decorations(minp, maxp, seed, data, param2_data, area, biomemap, lvm_used) +local function generate_tree_decorations(minp, maxp, seed, data, param2_data, area, biomemap, lvm_used, pr) if maxp.y < 0 then return lvm_used end @@ -1576,7 +1611,7 @@ local function generate_tree_decorations(minp, maxp, seed, data, param2_data, ar if minetest.find_node_near(pos, 1, {"mcl_core:jungleleaves"}) then - dir = math.random(1, cocoachance) + dir = pr:next(1, cocoachance) if dir == 1 then pos.z = pos.z + 1 @@ -1594,7 +1629,7 @@ local function generate_tree_decorations(minp, maxp, seed, data, param2_data, ar if dir < 5 and data[p_pos] == c_air and l ~= nil and l > 12 then - local c = math.random(1, 3) + local c = pr:next(1, 3) if c == 1 then data[p_pos] = c_cocoa_1 elseif c == 2 then @@ -1712,10 +1747,10 @@ local function generate_tree_decorations(minp, maxp, seed, data, param2_data, ar return lvm_used end -local pr_shroom = PseudoRandom(os.time()-24359) -- Generate mushrooms in caves manually. -- Minetest's API does not support decorations in caves yet. :-( local generate_underground_mushrooms = function(minp, maxp, seed) + local pr_shroom = PseudoRandom(seed-24359) -- Generate rare underground mushrooms -- TODO: Make them appear in groups, use Perlin noise local min, max = mcl_vars.mg_lava_overworld_max + 4, 0 @@ -1740,7 +1775,6 @@ local generate_underground_mushrooms = function(minp, maxp, seed) end end -local pr_nether = PseudoRandom(os.time()+667) local nether_wart_chance if mg_name == "v6" then nether_wart_chance = 85 @@ -1750,6 +1784,8 @@ end -- Generate Nether decorations manually: Eternal fire, mushrooms, nether wart -- Minetest's API does not support decorations in caves yet. :-( local generate_nether_decorations = function(minp, maxp, seed) + local pr_nether = PseudoRandom(seed+667) + if minp.y > mcl_vars.mg_nether_max or maxp.y < mcl_vars.mg_nether_min then return end @@ -1810,125 +1846,218 @@ local generate_nether_decorations = function(minp, maxp, seed) end --- Below the bedrock, generate air/void -minetest.register_on_generated(function(minp, maxp, seed) - local vm, emin, emax = minetest.get_mapgen_object("voxelmanip") - local data = vm:get_data(lvm_buffer) - local param2_data = vm:get_param2_data(lvm_buffer_param2) - local area = VoxelArea:new({MinEdge=emin, MaxEdge=emax}) - local aream = VoxelArea:new({MinEdge={x=minp.x, y=0, z=minp.z}, MaxEdge={x=maxp.x, y=0, z=maxp.z}}) - local lvm_used = false - local biomemap +minetest.register_on_generated(function(minp, maxp, blockseed) + add_chunk(minp) + local p1, p2 = {x=minp.x, y=minp.y, z=minp.z}, {x=maxp.x, y=maxp.y, z=maxp.z} + if lvm > 0 then + 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) + if param2 > 0 then + data2 = vm:get_param2_data(lb2) + end + local area = VoxelArea:new({MinEdge=e1, MaxEdge=e2}) - local ymin, ymax + for _, rec in pairs(mcl_mapgen_core.registered_generators) do + if rec.vf then + local lvm_used0, shadow0 = rec.vf(vm, data, data2, p1, p2, area, p1, p2, blockseed) + if lvm_used0 then + lvm_used = true + end + if shadow0 then + shadow = true + end + end + end - -- Generate basic layer-based nodes: void, bedrock, realm barrier, lava seas, etc. - -- Also perform some basic node replacements. + if lvm_used then + -- Write stuff + vm:set_data(data) + if param2 > 0 then + vm:set_param2_data(data2) + end + vm:calc_lighting(p1, p2, shadow) + vm:write_to_map() + vm:update_liquids() + end + end - -- Helper function to set all nodes in the layers between min and max. - -- content_id: Node to set - -- check: optional. - -- If content_id, node will be set only if it is equal to check. - -- If function(pos_to_check, content_id_at_this_pos), will set node only if returns true. - -- min, max: Minimum and maximum Y levels of the layers to set - -- minp, maxp: minp, maxp of the on_generated - -- lvm_used: Set to true if any node in this on_generated has been set before. - -- - -- returns true if any node was set and lvm_used otherwise - local function set_layers(content_id, check, min, max, minp, maxp, lvm_used) - if (maxp.y >= min and minp.y <= max) then - for y = math.max(min, minp.y), math.min(max, maxp.y) do - for x = minp.x, maxp.x do - for z = minp.z, maxp.z do - local p_pos = area:index(x, y, z) - if check then - if type(check) == "function" and check({x=x,y=y,z=z}, data[p_pos]) then - data[p_pos] = content_id - lvm_used = true - elseif check == data[p_pos] then - data[p_pos] = content_id - lvm_used = true - end - else + if nodes > 0 then + for _, rec in pairs(mcl_mapgen_core.registered_generators) do + if rec.nf then + rec.nf(p1, p2, blockseed) + end + end + end + +-- 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) +end + +function mcl_mapgen_core.register_generator(id, lvm_function, node_function, priority, needs_param2) + if not id then return end + + local priority = priority or 5000 + + if lvm_function then lvm = lvm + 1 end + if lvm_function then nodes = nodes + 1 end + if needs_param2 then param2 = param2 + 1 end + + local new_record = { + i = priority, + vf = lvm_function, + nf = node_function, + needs_param2 = needs_param2, + } + + mcl_mapgen_core.registered_generators[id] = new_record + table.sort( + mcl_mapgen_core.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 rec.vf then lvm = lvm - 1 end + if rev.nf then nodes = nodes - 1 end + if rec.needs_param2 then param2 = param2 - 1 end + if rec.needs_level0 then level0 = level0 - 1 end +end + +-- Generate basic layer-based nodes: void, bedrock, realm barrier, lava seas, etc. +-- Also perform some basic node replacements. + +local bedrock_check +if mcl_vars.mg_bedrock_is_rough then + bedrock_check = function(pos, _, pr) + local y = pos.y + -- Bedrock layers with increasing levels of roughness, until a perfecly flat bedrock later at the bottom layer + -- This code assumes a bedrock height of 5 layers. + + local diff = mcl_vars.mg_bedrock_overworld_max - y -- Overworld bedrock + local ndiff1 = mcl_vars.mg_bedrock_nether_bottom_max - y -- Nether bedrock, bottom + local ndiff2 = mcl_vars.mg_bedrock_nether_top_max - y -- Nether bedrock, ceiling + + local top + if diff == 0 or ndiff1 == 0 or ndiff2 == 4 then + -- 50% bedrock chance + top = 2 + elseif diff == 1 or ndiff1 == 1 or ndiff2 == 3 then + -- 66.666...% + top = 3 + elseif diff == 2 or ndiff1 == 2 or ndiff2 == 2 then + -- 75% + top = 4 + elseif diff == 3 or ndiff1 == 3 or ndiff2 == 1 then + -- 90% + top = 10 + elseif diff == 4 or ndiff1 == 4 or ndiff2 == 0 then + -- 100% + return true + else + -- Not in bedrock layer + return false + end + + return pr:next(1, top) <= top-1 + end +end + + +-- Helper function to set all nodes in the layers between min and max. +-- content_id: Node to set +-- check: optional. +-- If content_id, node will be set only if it is equal to check. +-- If function(pos_to_check, content_id_at_this_pos), will set node only if returns true. +-- min, max: Minimum and maximum Y levels of the layers to set +-- minp, maxp: minp, maxp of the on_generated +-- lvm_used: Set to true if any node in this on_generated has been set before. +-- +-- returns true if any node was set and lvm_used otherwise +local function set_layers(data, area, content_id, check, min, max, minp, maxp, lvm_used, pr) + if (maxp.y >= min and minp.y <= max) then + for y = math.max(min, minp.y), math.min(max, maxp.y) do + for x = minp.x, maxp.x do + for z = minp.z, maxp.z do + local p_pos = area:index(x, y, z) + if check then + if type(check) == "function" and check({x=x,y=y,z=z}, data[p_pos], pr) then + data[p_pos] = content_id + lvm_used = true + elseif check == data[p_pos] then data[p_pos] = content_id lvm_used = true end + else + data[p_pos] = content_id + lvm_used = true end end end end - return lvm_used end + return lvm_used +end - -- The Void - lvm_used = set_layers(c_void, nil, -31000, mcl_vars.mg_nether_min-1, minp, maxp, lvm_used) - lvm_used = set_layers(c_void, nil, mcl_vars.mg_nether_max+1, mcl_vars.mg_end_min-1, minp, maxp, lvm_used) - lvm_used = set_layers(c_void, nil, mcl_vars.mg_end_max+1, mcl_vars.mg_realm_barrier_overworld_end_min-1, minp, maxp, lvm_used) - lvm_used = set_layers(c_void, nil, mcl_vars.mg_realm_barrier_overworld_end_max+1, mcl_vars.mg_overworld_min-1, minp, maxp, lvm_used) +-- Below the bedrock, generate air/void +local function basic(vm, data, data2, emin, emax, area, minp, maxp, blockseed) + local biomemap, ymin, ymax + local lvm_used = false + local pr = PseudoRandom(blockseed) + -- The Void below the Nether: + lvm_used = set_layers(data, area, c_void , nil, mcl_vars.mapgen_edge_min , mcl_vars.mg_nether_min -1, minp, maxp, lvm_used, pr) + + -- [[ THE NETHER: mcl_vars.mg_nether_min mcl_vars.mg_nether_max ]] + + -- The Air on the Nether roof, https://git.minetest.land/MineClone2/MineClone2/issues/1186 + lvm_used = set_layers(data, area, c_air , nil, mcl_vars.mg_nether_max +1, mcl_vars.mg_nether_max + 128 , minp, maxp, lvm_used, pr) + -- The Void above the Nether below the End: + lvm_used = set_layers(data, area, c_void , nil, mcl_vars.mg_nether_max + 128 +1, mcl_vars.mg_end_min -1, minp, maxp, lvm_used, pr) + + -- [[ THE END: mcl_vars.mg_end_min mcl_vars.mg_end_max ]] + + -- The Void above the End below the Realm barrier: + lvm_used = set_layers(data, area, c_void , nil, mcl_vars.mg_end_max +1, mcl_vars.mg_realm_barrier_overworld_end_min-1, minp, maxp, lvm_used, pr) -- Realm barrier between the Overworld void and the End - lvm_used = set_layers(c_realm_barrier, nil, mcl_vars.mg_realm_barrier_overworld_end_min, mcl_vars.mg_realm_barrier_overworld_end_max, minp, maxp, lvm_used) + lvm_used = set_layers(data, area, c_realm_barrier, nil, mcl_vars.mg_realm_barrier_overworld_end_min , mcl_vars.mg_realm_barrier_overworld_end_max , minp, maxp, lvm_used, pr) + -- The Void above Realm barrier below the Overworld: + lvm_used = set_layers(data, area, c_void , nil, mcl_vars.mg_realm_barrier_overworld_end_max+1, mcl_vars.mg_overworld_min -1, minp, maxp, lvm_used, pr) + if mg_name ~= "singlenode" then -- Bedrock - local bedrock_check - if mcl_vars.mg_bedrock_is_rough then - bedrock_check = function(pos) - local y = pos.y - -- Bedrock layers with increasing levels of roughness, until a perfecly flat bedrock later at the bottom layer - -- This code assumes a bedrock height of 5 layers. - - local diff = mcl_vars.mg_bedrock_overworld_max - y -- Overworld bedrock - local ndiff1 = mcl_vars.mg_bedrock_nether_bottom_max - y -- Nether bedrock, bottom - local ndiff2 = mcl_vars.mg_bedrock_nether_top_max - y -- Nether bedrock, ceiling - - local top - if diff == 0 or ndiff1 == 0 or ndiff2 == 4 then - -- 50% bedrock chance - top = 2 - elseif diff == 1 or ndiff1 == 1 or ndiff2 == 3 then - -- 66.666...% - top = 3 - elseif diff == 2 or ndiff1 == 2 or ndiff2 == 2 then - -- 75% - top = 4 - elseif diff == 3 or ndiff1 == 3 or ndiff2 == 1 then - -- 90% - top = 10 - elseif diff == 4 or ndiff1 == 4 or ndiff2 == 0 then - -- 100% - return true - else - -- Not in bedrock layer - return false - end - - return math.random(1, top) <= top-1 - end - else - bedrock_check = nil - end - - lvm_used = set_layers(c_bedrock, bedrock_check, mcl_vars.mg_bedrock_overworld_min, mcl_vars.mg_bedrock_overworld_max, minp, maxp, lvm_used) - lvm_used = set_layers(c_bedrock, bedrock_check, mcl_vars.mg_bedrock_nether_bottom_min, mcl_vars.mg_bedrock_nether_bottom_max, minp, maxp, lvm_used) - lvm_used = set_layers(c_bedrock, bedrock_check, mcl_vars.mg_bedrock_nether_top_min, mcl_vars.mg_bedrock_nether_top_max, minp, maxp, lvm_used) + lvm_used = set_layers(data, area, c_bedrock, bedrock_check, mcl_vars.mg_bedrock_overworld_min, mcl_vars.mg_bedrock_overworld_max, minp, maxp, lvm_used, pr) + lvm_used = set_layers(data, area, c_bedrock, bedrock_check, mcl_vars.mg_bedrock_nether_bottom_min, mcl_vars.mg_bedrock_nether_bottom_max, minp, maxp, lvm_used, pr) + lvm_used = set_layers(data, area, c_bedrock, bedrock_check, mcl_vars.mg_bedrock_nether_top_min, mcl_vars.mg_bedrock_nether_top_max, minp, maxp, lvm_used, pr) -- Flat Nether if mg_name == "flat" then - lvm_used = set_layers(c_air, nil, mcl_vars.mg_flat_nether_floor, mcl_vars.mg_flat_nether_ceiling, minp, maxp, lvm_used) + lvm_used = set_layers(data, area, c_air, nil, mcl_vars.mg_flat_nether_floor, mcl_vars.mg_flat_nether_ceiling, minp, maxp, lvm_used, pr) end -- Big lava seas by replacing air below a certain height if mcl_vars.mg_lava then - lvm_used = set_layers(c_lava, c_air, mcl_vars.mg_overworld_min, mcl_vars.mg_lava_overworld_max, emin, emax, lvm_used) - lvm_used = set_layers(c_nether_lava, c_air, mcl_vars.mg_nether_min, mcl_vars.mg_lava_nether_max, emin, emax, lvm_used) + lvm_used = set_layers(data, area, c_lava, c_air, mcl_vars.mg_overworld_min, mcl_vars.mg_lava_overworld_max, minp, maxp, lvm_used, pr) + lvm_used = set_layers(data, area, c_nether_lava, c_air, mcl_vars.mg_nether_min, mcl_vars.mg_lava_nether_max, minp, maxp, lvm_used, pr) end -- Clay, vines, cocoas - lvm_used = generate_clay(minp, maxp, seed, data, area, lvm_used) + lvm_used = generate_clay(minp, maxp, blockseed, data, area, lvm_used) biomemap = minetest.get_mapgen_object("biomemap") - lvm_used = generate_tree_decorations(minp, maxp, seed, data, param2_data, area, biomemap, lvm_used) + lvm_used = generate_tree_decorations(minp, maxp, blockseed, data, data2, area, biomemap, lvm_used, pr) ----- Interactive block fixing section ----- ----- The section to perform basic block overrides of the core mapgen generated world. ----- @@ -1936,7 +2065,7 @@ minetest.register_on_generated(function(minp, maxp, seed) -- Snow and sand fixes. This code implements snow consistency -- and fixes floating sand and cut plants. -- A snowy grass block must be below a top snow or snow block at all times. - if emin.y <= mcl_vars.mg_overworld_max and emax.y >= mcl_vars.mg_overworld_min then + if minp.y <= mcl_vars.mg_overworld_max and maxp.y >= mcl_vars.mg_overworld_min then -- v6 mapgen: if mg_name == "v6" then @@ -1950,7 +2079,7 @@ minetest.register_on_generated(function(minp, maxp, seed) altogether if ANY of their nodes could not be placed. 2) Cavegen: Removes the bottom part, the upper part floats 3) Mudflow: Same as 2) ]] - local plants = minetest.find_nodes_in_area(emin, emax, "group:double_plant") + local plants = minetest.find_nodes_in_area(minp, maxp, "group:double_plant") for n = 1, #plants do local node = vm:get_node_at(plants[n]) local is_top = minetest.get_item_group(node.name, "double_plant") == 2 @@ -1974,19 +2103,21 @@ minetest.register_on_generated(function(minp, maxp, seed) -- Set param2 (=color) of grass blocks. -- Clear snowy grass blocks without snow above to ensure consistency. local nodes = minetest.find_nodes_in_area(minp, maxp, {"mcl_core:dirt_with_grass", "mcl_core:dirt_with_grass_snow"}) + + -- Flat area at y=0 to read biome 3 times faster than 5.3.0.get_biome_data(pos).biome: 43us vs 125us per iteration: + local aream = VoxelArea:new({MinEdge={x=minp.x, y=0, z=minp.z}, MaxEdge={x=maxp.x, y=0, z=maxp.z}}) for n=1, #nodes do - local p_pos = area:index(nodes[n].x, nodes[n].y, nodes[n].z) - local p_pos_above = area:index(nodes[n].x, nodes[n].y+1, nodes[n].z) - local p_pos_below = area:index(nodes[n].x, nodes[n].y-1, nodes[n].z) - local b_pos = aream:index(nodes[n].x, 0, nodes[n].z) + local n = nodes[n] + local p_pos = area:index(n.x, n.y, n.z) + local p_pos_above = area:index(n.x, n.y+1, n.z) + local p_pos_below = area:index(n.x, n.y-1, n.z) + local b_pos = aream:index(n.x, 0, n.z) local bn = minetest.get_biome_name(biomemap[b_pos]) if bn then local biome = minetest.registered_biomes[bn] - if biome then - if biome._mcl_biome_type then - param2_data[p_pos] = biome._mcl_palette_index - lvm_used = true - end + if biome and biome._mcl_biome_type then + data2[p_pos] = biome._mcl_palette_index + lvm_used = true end end if data[p_pos] == c_dirt_with_grass_snow and p_pos_above and data[p_pos_above] ~= c_top_snow and data[p_pos_above] ~= c_snow_block then @@ -1994,17 +2125,18 @@ minetest.register_on_generated(function(minp, maxp, seed) lvm_used = true end end + end -- Nether block fixes: -- * Replace water with Nether lava. -- * Replace stone, sand dirt in v6 so the Nether works in v6. - elseif emin.y <= mcl_vars.mg_nether_max and emax.y >= mcl_vars.mg_nether_min then + elseif minp.y <= mcl_vars.mg_nether_max and maxp.y >= mcl_vars.mg_nether_min then local nodes if mg_name == "v6" then - nodes = minetest.find_nodes_in_area(emin, emax, {"mcl_core:water_source", "mcl_core:stone", "mcl_core:sand", "mcl_core:dirt"}) + nodes = minetest.find_nodes_in_area(minp, maxp, {"mcl_core:water_source", "mcl_core:stone", "mcl_core:sand", "mcl_core:dirt"}) else - nodes = minetest.find_nodes_in_area(emin, emax, {"mcl_core:water_source"}) + 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) @@ -2024,28 +2156,29 @@ minetest.register_on_generated(function(minp, maxp, seed) -- * Replace water with end stone or air (depending on height). -- * Remove stone, sand, dirt in v6 so our End map generator works in v6. -- * Generate spawn platform (End portal destination) - elseif emin.y <= mcl_vars.mg_end_max and emax.y >= mcl_vars.mg_end_min then - local nodes + elseif minp.y <= mcl_vars.mg_end_max and maxp.y >= mcl_vars.mg_end_min then + local nodes, node if mg_name == "v6" then - nodes = minetest.find_nodes_in_area(emin, emax, {"mcl_core:water_source", "mcl_core:stone", "mcl_core:sand", "mcl_core:dirt"}) + nodes = minetest.find_nodes_in_area(minp, maxp, {"mcl_core:water_source", "mcl_core:stone", "mcl_core:sand", "mcl_core:dirt"}) else - nodes = minetest.find_nodes_in_area(emin, emax, {"mcl_core:water_source"}) + nodes = minetest.find_nodes_in_area(minp, maxp, {"mcl_core:water_source"}) end - for n=1, #nodes do - local y = nodes[n].y - local p_pos = area:index(nodes[n].x, y, nodes[n].z) - - if data[p_pos] == c_water or data[p_pos] == c_stone or data[p_pos] == c_dirt or data[p_pos] == c_sand then - data[p_pos] = c_air - lvm_used = true + 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 end - end -- Obsidian spawn platform if minp.y <= mcl_vars.mg_end_platform_pos.y and maxp.y >= mcl_vars.mg_end_platform_pos.y and - minp.x <= mcl_vars.mg_end_platform_pos.x and maxp.x >= mcl_vars.mg_end_platform_pos.z and - minp.z <= mcl_vars.mg_end_platform_pos.z and maxp.z >= mcl_vars.mg_end_platform_pos.z then + minp.x <= mcl_vars.mg_end_platform_pos.x and maxp.x >= mcl_vars.mg_end_platform_pos.z and + minp.z <= mcl_vars.mg_end_platform_pos.z and maxp.z >= mcl_vars.mg_end_platform_pos.z then + + local pos1 = {x = math.max(minp.x, mcl_vars.mg_end_platform_pos.x-2), y = math.max(minp.y, mcl_vars.mg_end_platform_pos.y), z = math.max(minp.z, mcl_vars.mg_end_platform_pos.z-2)} + local pos2 = {x = math.min(maxp.x, mcl_vars.mg_end_platform_pos.x+2), y = math.min(maxp.y, mcl_vars.mg_end_platform_pos.y+2), z = math.min(maxp.z, mcl_vars.mg_end_platform_pos.z+2)} + for x=math.max(minp.x, mcl_vars.mg_end_platform_pos.x-2), math.min(maxp.x, mcl_vars.mg_end_platform_pos.x+2) do for z=math.max(minp.z, mcl_vars.mg_end_platform_pos.z-2), math.min(maxp.z, mcl_vars.mg_end_platform_pos.z+2) do for y=math.max(minp.y, mcl_vars.mg_end_platform_pos.y), math.min(maxp.y, mcl_vars.mg_end_platform_pos.y+2) do @@ -2065,7 +2198,7 @@ minetest.register_on_generated(function(minp, maxp, seed) -- Final hackery: Set sun light level in the End. -- -26912 is at a mapchunk border. - local shadow + local shadow = true if minp.y >= -26912 and maxp.y <= mcl_vars.mg_end_max then vm:set_lighting({day=15, night=15}) lvm_used = true @@ -2075,21 +2208,60 @@ minetest.register_on_generated(function(minp, maxp, seed) lvm_used = true end - -- Write stuff - if lvm_used then - vm:set_data(data) - vm:set_param2_data(param2_data) - vm:calc_lighting(nil, nil, shadow) - vm:write_to_map() - vm:update_liquids() - end - if mg_name ~= "singlenode" then -- Generate special decorations - generate_underground_mushrooms(minp, maxp, seed) - generate_nether_decorations(minp, maxp, seed) - generate_structures(minp, maxp, seed, biomemap) + generate_underground_mushrooms(minp, maxp, blockseed) + generate_nether_decorations(minp, maxp, blockseed) + generate_structures(minp, maxp, blockseed, biomemap) end -end) + return lvm_used, shadow +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_mapgen_core/mod.conf b/mods/MAPGEN/mcl_mapgen_core/mod.conf index 5b5419c32..9f7d9ebaa 100644 --- a/mods/MAPGEN/mcl_mapgen_core/mod.conf +++ b/mods/MAPGEN/mcl_mapgen_core/mod.conf @@ -1 +1,5 @@ name = mcl_mapgen_core +author = Wuzzy +description = The core of the MCL2 mapgen +depends = mcl_init, mcl_core, biomeinfo, mcl_worlds, mcl_cocoas, mcl_sponges, mcl_ocean, mcl_stairs, mcl_monster_eggs, mcl_structures +optional_depends = mclx_core diff --git a/mods/MAPGEN/mcl_strongholds/depends.txt b/mods/MAPGEN/mcl_strongholds/depends.txt deleted file mode 100644 index 76570fa33..000000000 --- a/mods/MAPGEN/mcl_strongholds/depends.txt +++ /dev/null @@ -1,3 +0,0 @@ -mcl_init -mcl_structures -mcl_mapgen_core diff --git a/mods/MAPGEN/mcl_strongholds/description.txt b/mods/MAPGEN/mcl_strongholds/description.txt deleted file mode 100644 index 2f761edbe..000000000 --- a/mods/MAPGEN/mcl_strongholds/description.txt +++ /dev/null @@ -1 +0,0 @@ -Generates strongholds with end portals in the Overworld diff --git a/mods/MAPGEN/mcl_strongholds/init.lua b/mods/MAPGEN/mcl_strongholds/init.lua index 92313bee7..e465b2e40 100644 --- a/mods/MAPGEN/mcl_strongholds/init.lua +++ b/mods/MAPGEN/mcl_strongholds/init.lua @@ -67,7 +67,8 @@ local init_strongholds = function() end -- Stronghold generation for register_on_generated. -local generate_strongholds = function(minp, maxp) +local generate_strongholds = function(minp, maxp, blockseed) + local pr = PseudoRandom(blockseed) for s=1, #strongholds do if not strongholds[s].generated then local pos = strongholds[s].pos @@ -80,6 +81,12 @@ local generate_strongholds = function(minp, maxp) if pos.x + 6 > maxp.x then pos.x = maxp.x - 7 end + if pos.y - 4 < minp.y then + pos.y = minp.y + 5 + end + if pos.y + 4 > maxp.y then + pos.y = maxp.y - 5 + end if pos.z - 6 < minp.z then pos.z = minp.z + 7 end @@ -87,7 +94,7 @@ local generate_strongholds = function(minp, maxp) pos.z = maxp.z - 7 end - mcl_structures.call_struct(pos, "end_portal_shrine") + mcl_structures.call_struct(pos, "end_portal_shrine", nil, pr) strongholds[s].generated = true end end @@ -96,9 +103,4 @@ end init_strongholds() ---[[ Note this mod depends on mcl_mapgen_core to make sure the core mapgen runs FIRST. -This is important because we need this to make sure the stronghold isn't instantly -overwritten by the core mapgen (since it uses LuaVoxelManip). ]] -minetest.register_on_generated(function(minp, maxp, blockseed) - generate_strongholds(minp, maxp) -end) +mcl_mapgen_core.register_generator("strongholds", nil, generate_strongholds, 999999) diff --git a/mods/MAPGEN/mcl_strongholds/mod.conf b/mods/MAPGEN/mcl_strongholds/mod.conf index 22c99de4f..8edec9a51 100644 --- a/mods/MAPGEN/mcl_strongholds/mod.conf +++ b/mods/MAPGEN/mcl_strongholds/mod.conf @@ -1 +1,4 @@ name = mcl_strongholds +author = Wuzzy +description = Generates strongholds with end portals in the Overworld +depends = mcl_init, mcl_structures, mcl_mapgen_core diff --git a/mods/MAPGEN/mcl_structures/depends.txt b/mods/MAPGEN/mcl_structures/depends.txt deleted file mode 100644 index dc513fc7b..000000000 --- a/mods/MAPGEN/mcl_structures/depends.txt +++ /dev/null @@ -1 +0,0 @@ -mcl_loot diff --git a/mods/MAPGEN/mcl_structures/init.lua b/mods/MAPGEN/mcl_structures/init.lua index bc3b1b1a7..96c620c99 100644 --- a/mods/MAPGEN/mcl_structures/init.lua +++ b/mods/MAPGEN/mcl_structures/init.lua @@ -1,24 +1,56 @@ local S = minetest.get_translator("mcl_structures") mcl_structures ={} +local rotations = { + "0", + "90", + "180", + "270" +} + +local function ecb_place(blockpos, action, calls_remaining, param) + if calls_remaining >= 1 then return end + minetest.place_schematic(param.pos, param.schematic, param.rotation, param.replacements, param.force_placement, param.flags) + if param.after_placement_callback and param.p1 and param.p2 then + param.after_placement_callback(param.p1, param.p2, param.size, param.rotation, param.pr) + end +end +mcl_structures.place_schematic = function(pos, schematic, rotation, replacements, force_placement, flags, after_placement_callback, pr) + local s = loadstring(minetest.serialize_schematic(schematic, "lua", {lua_use_comments = false, lua_num_indent_spaces = 0}) .. " return(schematic)")() + if s and s.size then + local x, z = s.size.x, s.size.z + if rotation then + if rotation == "random" and pr then + rotation = rotations[pr:next(1,#rotations)] + end + if rotation == "random" then + x = math.max(x, z) + z = x + elseif rotation == "90" or rotation == "270" then + x, z = z, x + end + end + local p1 = {x=pos.x , y=pos.y , z=pos.z } + local p2 = {x=pos.x+x-1, y=pos.y+s.size.y-1, z=pos.z+z-1} + minetest.log("verbose","[mcl_structures] size=" ..minetest.pos_to_string(s.size) .. ", rotation=" .. tostring(rotation) .. ", emerge from "..minetest.pos_to_string(p1) .. " to " .. minetest.pos_to_string(p2)) + local param = {pos=vector.new(pos), schematic=s, rotation=rotation, replacements=replacements, force_placement=force_placement, flags=flags, p1=p1, p2=p2, after_placement_callback = after_placement_callback, size=vector.new(s.size), pr=pr} + minetest.emerge_area(p1, p2, ecb_place, param) + end +end mcl_structures.get_struct = function(file) local localfile = minetest.get_modpath("mcl_structures").."/schematics/"..file local file, errorload = io.open(localfile, "rb") if errorload ~= nil then - minetest.log("error", '[mcl_structures] Could not open this struct: ' .. localfile) - return nil + minetest.log("error", '[mcl_structures] Could not open this struct: ' .. localfile) + return nil end - local allnode = file:read("*a") - file:close() + local allnode = file:read("*a") + file:close() - return allnode + return allnode end -local mapseed = tonumber(minetest.get_mapgen_setting("seed")) --- Random number generator for all generated structures -local pr = PseudoRandom(mapseed) - -- Call on_construct on pos. -- Useful to init chests from formspec. local init_node_construct = function(pos) @@ -32,16 +64,17 @@ local init_node_construct = function(pos) end -- The call of Struct -mcl_structures.call_struct = function(pos, struct_style, rotation) +mcl_structures.call_struct = function(pos, struct_style, rotation, pr) + minetest.log("action","[mcl_structures] call_struct " .. struct_style.." at "..minetest.pos_to_string(pos)) if not rotation then rotation = "random" end if struct_style == "desert_temple" then - return mcl_structures.generate_desert_temple(pos, rotation) + return mcl_structures.generate_desert_temple(pos, rotation, pr) elseif struct_style == "desert_well" then return mcl_structures.generate_desert_well(pos, rotation) elseif struct_style == "igloo" then - return mcl_structures.generate_igloo(pos, rotation) + return mcl_structures.generate_igloo(pos, rotation, pr) elseif struct_style == "witch_hut" then return mcl_structures.generate_witch_hut(pos, rotation) elseif struct_style == "ice_spike_small" then @@ -49,28 +82,28 @@ mcl_structures.call_struct = function(pos, struct_style, rotation) elseif struct_style == "ice_spike_large" then return mcl_structures.generate_ice_spike_large(pos, rotation) elseif struct_style == "boulder" then - return mcl_structures.generate_boulder(pos, rotation) + return mcl_structures.generate_boulder(pos, rotation, pr) elseif struct_style == "fossil" then - return mcl_structures.generate_fossil(pos, rotation) + return mcl_structures.generate_fossil(pos, rotation, pr) elseif struct_style == "end_exit_portal" then return mcl_structures.generate_end_exit_portal(pos, rotation) elseif struct_style == "end_portal_shrine" then - return mcl_structures.generate_end_portal_shrine(pos, rotation) + return mcl_structures.generate_end_portal_shrine(pos, rotation, pr) end end -mcl_structures.generate_desert_well = function(pos) +mcl_structures.generate_desert_well = function(pos, rot) local newpos = {x=pos.x,y=pos.y-2,z=pos.z} local path = minetest.get_modpath("mcl_structures").."/schematics/mcl_structures_desert_well.mts" - return minetest.place_schematic(newpos, path, "0", nil, true) + return mcl_structures.place_schematic(newpos, path, rot or "0", nil, true) end -mcl_structures.generate_igloo = function(pos) +mcl_structures.generate_igloo = function(pos, rotation, pr) -- Place igloo - local success, rotation = mcl_structures.generate_igloo_top(pos) + local success, rotation = mcl_structures.generate_igloo_top(pos, pr) -- Place igloo basement with 50% chance - local r = math.random(1,2) - if success and r == 1 then + local r = pr:next(1,2) + if r == 1 then -- Select basement depth local dim = mcl_worlds.pos_to_dimension(pos) local buffer = pos.y - (mcl_vars.mg_lava_overworld_max + 10) @@ -86,7 +119,7 @@ mcl_structures.generate_igloo = function(pos) if buffer <= 19 then return success end - local depth = math.random(19, buffer) + local depth = pr:next(19, buffer) local bpos = {x=pos.x, y=pos.y-depth, z=pos.z} -- trapdoor position local tpos @@ -111,8 +144,8 @@ mcl_structures.generate_igloo = function(pos) return success end local set_brick = function(pos) - local c = math.random(1, 3) -- cracked chance - local m = math.random(1, 10) -- chance for monster egg + local c = pr:next(1, 3) -- cracked chance + local m = pr:next(1, 10) -- chance for monster egg local brick if m == 1 then if c == 1 then @@ -155,75 +188,74 @@ mcl_structures.generate_igloo = function(pos) minetest.set_node({x=tpos.x,y=tpos.y-y,z=tpos.z}, {name="mcl_core:ladder", param2=ladder_param2}) end -- Place basement - mcl_structures.generate_igloo_basement(bpos, rotation) + mcl_structures.generate_igloo_basement(bpos, rotation, pr) end return success end -mcl_structures.generate_igloo_top = function(pos) +mcl_structures.generate_igloo_top = function(pos, pr) -- FIXME: This spawns bookshelf instead of furnace. Fix this! -- Furnace does ot work atm because apparently meta is not set. :-( local newpos = {x=pos.x,y=pos.y-1,z=pos.z} local path = minetest.get_modpath("mcl_structures").."/schematics/mcl_structures_igloo_top.mts" - local rotation = tostring(math.random(0,3)*90) - return minetest.place_schematic(newpos, path, rotation, nil, true), rotation + local rotation = tostring(pr:next(0,3)*90) + return mcl_structures.place_schematic(newpos, path, rotation, nil, true), rotation end -mcl_structures.generate_igloo_basement = function(pos, orientation) +local function igloo_placement_callback(p1, p2, size, orientation, pr) + local chest_offset + if orientation == "0" then + chest_offset = {x=5, y=1, z=5} + elseif orientation == "90" then + chest_offset = {x=5, y=1, z=3} + elseif orientation == "180" then + chest_offset = {x=3, y=1, z=1} + elseif orientation == "270" then + chest_offset = {x=1, y=1, z=5} + else + return + end + local size = {x=9,y=5,z=7} + local lootitems = mcl_loot.get_multi_loot({ + { + stacks_min = 1, + stacks_max = 1, + items = { + { itemstring = "mcl_core:apple_gold", weight = 1 }, + } + }, + { + stacks_min = 2, + stacks_max = 8, + items = { + { itemstring = "mcl_core:coal_lump", weight = 15, amount_min = 1, amount_max = 4 }, + { itemstring = "mcl_core:apple", weight = 15, amount_min = 1, amount_max = 3 }, + { itemstring = "mcl_farming:wheat_item", weight = 10, amount_min = 2, amount_max = 3 }, + { itemstring = "mcl_core:gold_nugget", weight = 10, amount_min = 1, amount_max = 3 }, + { itemstring = "mcl_mobitems:rotten_flesh", weight = 10 }, + { itemstring = "mcl_tools:axe_stone", weight = 2 }, + { itemstring = "mcl_core:emerald", weight = 1 }, + } + }}, pr) + + local chest_pos = vector.add(p1, chest_offset) + init_node_construct(chest_pos) + local meta = minetest.get_meta(chest_pos) + local inv = meta:get_inventory() + mcl_loot.fill_inventory(inv, "main", lootitems, pr) +end + +mcl_structures.generate_igloo_basement = function(pos, orientation, pr) -- TODO: Add brewing stand -- TODO: Add monster eggs -- TODO: Spawn villager and zombie villager local path = minetest.get_modpath("mcl_structures").."/schematics/mcl_structures_igloo_basement.mts" - - local success = minetest.place_schematic(pos, path, orientation, nil, true) - if success then - local chest_offset - if orientation == "0" then - chest_offset = {x=5, y=1, z=5} - elseif orientation == "90" then - chest_offset = {x=5, y=1, z=3} - elseif orientation == "180" then - chest_offset = {x=3, y=1, z=1} - elseif orientation == "270" then - chest_offset = {x=1, y=1, z=5} - else - return success - end - local size = {x=9,y=5,z=7} - local lootitems = mcl_loot.get_multi_loot({ - { - stacks_min = 1, - stacks_max = 1, - items = { - { itemstring = "mcl_core:apple_gold", weight = 1 }, - } - }, - { - stacks_min = 2, - stacks_max = 8, - items = { - { itemstring = "mcl_core:coal_lump", weight = 15, amount_min = 1, amount_max = 4 }, - { itemstring = "mcl_core:apple", weight = 15, amount_min = 1, amount_max = 3 }, - { itemstring = "mcl_farming:wheat_item", weight = 10, amount_min = 2, amount_max = 3 }, - { itemstring = "mcl_core:gold_nugget", weight = 10, amount_min = 1, amount_max = 3 }, - { itemstring = "mcl_mobitems:rotten_flesh", weight = 10 }, - { itemstring = "mcl_tools:axe_stone", weight = 2 }, - { itemstring = "mcl_core:emerald", weight = 1 }, - } - }}, pr) - - local chest_pos = vector.add(pos, chest_offset) - init_node_construct(chest_pos) - local meta = minetest.get_meta(chest_pos) - local inv = meta:get_inventory() - mcl_loot.fill_inventory(inv, "main", lootitems) - end - return success + mcl_structures.place_schematic(pos, path, orientation, nil, true, nil, igloo_placement_callback, pr) end -mcl_structures.generate_boulder = function(pos) +mcl_structures.generate_boulder = function(pos, rotation, pr) -- Choose between 2 boulder sizes (2×2×2 or 3×3×3) - local r = math.random(1, 10) + local r = pr:next(1, 10) local path if r <= 3 then path = minetest.get_modpath("mcl_structures").."/schematics/mcl_structures_boulder_small.mts" @@ -232,25 +264,37 @@ mcl_structures.generate_boulder = function(pos) end local newpos = {x=pos.x,y=pos.y-1,z=pos.z} - return minetest.place_schematic(newpos, path) + + return minetest.place_schematic(newpos, path, rotation) -- don't serialize schematics for registered biome decorations, for MT 5.4.0, https://github.com/minetest/minetest/issues/10995 end -mcl_structures.generate_witch_hut = function(pos, rotation) +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 + legs[i].y = legs[i].y - 1 + minetest.swap_node(legs[i], {name = "mcl_core:tree", param2 = 2}) + end + end +end + +mcl_structures.generate_witch_hut = function(pos, rotation, pr) local path = minetest.get_modpath("mcl_structures").."/schematics/mcl_structures_witch_hut.mts" - return minetest.place_schematic(pos, path, rotation, nil, true) + mcl_structures.place_schematic(pos, path, rotation, nil, true, nil, hut_placement_callback, pr) end -mcl_structures.generate_ice_spike_small = function(pos) +mcl_structures.generate_ice_spike_small = function(pos, rotation) local path = minetest.get_modpath("mcl_structures").."/schematics/mcl_structures_ice_spike_small.mts" - return minetest.place_schematic(pos, path, "random", nil, false) + return minetest.place_schematic(pos, path, rotation or "random", nil, false) -- don't serialize schematics for registered biome decorations, for MT 5.4.0 end -mcl_structures.generate_ice_spike_large = function(pos) +mcl_structures.generate_ice_spike_large = function(pos, rotation) local path = minetest.get_modpath("mcl_structures").."/schematics/mcl_structures_ice_spike_large.mts" - return minetest.place_schematic(pos, path, "random", nil, false) + return minetest.place_schematic(pos, path, rotation or "random", nil, false) -- don't serialize schematics for registered biome decorations, for MT 5.4.0 end -mcl_structures.generate_fossil = function(pos) +mcl_structures.generate_fossil = function(pos, rotation, pr) -- Generates one out of 8 possible fossil pieces local newpos = {x=pos.x,y=pos.y-1,z=pos.z} local fossils = { @@ -263,34 +307,26 @@ mcl_structures.generate_fossil = function(pos) "mcl_structures_fossil_spine_3.mts", -- 7×4×13 "mcl_structures_fossil_spine_4.mts", -- 8×5×13 } - local r = math.random(1, #fossils) + local r = pr:next(1, #fossils) local path = minetest.get_modpath("mcl_structures").."/schematics/"..fossils[r] - return minetest.place_schematic(newpos, path, "random", nil, true) + return mcl_structures.place_schematic(newpos, path, rotation or "random", nil, true) end -mcl_structures.generate_end_exit_portal = function(pos) +mcl_structures.generate_end_exit_portal = function(pos, rot) local path = minetest.get_modpath("mcl_structures").."/schematics/mcl_structures_end_exit_portal.mts" - return minetest.place_schematic(pos, path, "0", nil, true) + return mcl_structures.place_schematic(pos, path, rot or "0", nil, true) end -local generate_end_portal_shrine_no_delay = function(newpos) - local path = minetest.get_modpath("mcl_structures").."/schematics/mcl_structures_end_portal_room_simple.mts" - local size = {x=13, y=8, z=13} - local ret = minetest.place_schematic(newpos, path, "0", nil, true) - if ret == nil then - return ret - end - - local area_start, area_end = newpos, vector.add(newpos, size) +local function shrine_placement_callback(p1, p2, size, rotation, pr) -- Find and setup spawner with silverfish - local spawners = minetest.find_nodes_in_area(area_start, area_end, "mcl_mobspawners:spawner") + local spawners = minetest.find_nodes_in_area(p1, p2, "mcl_mobspawners:spawner") for s=1, #spawners do local meta = minetest.get_meta(spawners[s]) mcl_mobspawners.setup_spawner(spawners[s], "mobs_mc:silverfish") end -- Shuffle stone brick types - local bricks = minetest.find_nodes_in_area(area_start, area_end, "mcl_core:stonebrick") + local bricks = minetest.find_nodes_in_area(p1, p2, "mcl_core:stonebrick") for b=1, #bricks do local r_bricktype = pr:next(1, 100) local r_infested = pr:next(1, 100) @@ -317,7 +353,7 @@ local generate_end_portal_shrine_no_delay = function(newpos) end -- Also replace stairs - local stairs = minetest.find_nodes_in_area(area_start, area_end, {"mcl_stairs:stair_stonebrick", "mcl_stairs:stair_stonebrick_outer", "mcl_stairs:stair_stonebrick_inner"}) + local stairs = minetest.find_nodes_in_area(p1, p2, {"mcl_stairs:stair_stonebrick", "mcl_stairs:stair_stonebrick_outer", "mcl_stairs:stair_stonebrick_inner"}) for s=1, #stairs do local stair = minetest.get_node(stairs[s]) local r_type = pr:next(1, 100) @@ -344,7 +380,7 @@ local generate_end_portal_shrine_no_delay = function(newpos) end -- Randomly add ender eyes into end portal frames, but never fill the entire frame - local frames = minetest.find_nodes_in_area(area_start, area_end, "mcl_portals:end_portal_frame") + local frames = minetest.find_nodes_in_area(p1, p2, "mcl_portals:end_portal_frame") local eyes = 0 for f=1, #frames do local r_eye = pr:next(1, 10) @@ -357,40 +393,34 @@ local generate_end_portal_shrine_no_delay = function(newpos) end end end - - return ret end -local function ecb_generate_end_portal_shrine(blockpos, action, calls_remaining, param) - if calls_remaining <= 0 then - generate_end_portal_shrine_no_delay({x=param.x, y=param.y, z=param.z}) - end -end - -mcl_structures.generate_end_portal_shrine = function(pos) - local offset = {x=6, y=8, z=6} +mcl_structures.generate_end_portal_shrine = function(pos, rotation, pr) + local offset = {x=6, y=4, z=6} local size = {x=13, y=8, z=13} local newpos = { x = pos.x - offset.x, y = pos.y, z = pos.z - offset.z } - minetest.emerge_area(vector.subtract(newpos,10), vector.add(vector.add(newpos, size),10), ecb_generate_end_portal_shrine, {x=newpos.x, y=newpos.y, z=newpos.z}) + + local path = minetest.get_modpath("mcl_structures").."/schematics/mcl_structures_end_portal_room_simple.mts" + mcl_structures.place_schematic(newpos, path, rotation or "0", nil, true, nil, shrine_placement_callback, pr) end -mcl_structures.generate_desert_temple = function(pos) - -- No Generating for the temple ... Why using it ? No Change - local path = minetest.get_modpath("mcl_structures").."/schematics/mcl_structures_desert_temple.mts" - local newpos = {x=pos.x,y=pos.y-12,z=pos.z} - local size = {x=22, y=24, z=22} - if newpos == nil then - return - end - local ret = minetest.place_schematic(newpos, path, "random", nil, true) - if ret == nil then - return ret +local function temple_placement_callback(p1, p2, size, rotation, pr) + + -- Delete cacti leftovers: + local cactus_nodes = minetest.find_nodes_in_area_under_air(p1, p2, "mcl_core:cactus") + if cactus_nodes and #cactus_nodes > 0 then + for _, pos in pairs(cactus_nodes) do + local node_below = minetest.get_node({x=pos.x, y=pos.y-1, z=pos.z}) + if node_below and node_below.name == "mcl_core:sandstone" then + minetest.swap_node(pos, {name="air"}) + end + end end -- Find chests. -- FIXME: Searching this large area just for the chets is not efficient. Need a better way to find the chests; -- probably let's just infer it from newpos because the schematic always the same. - local chests = minetest.find_nodes_in_area({x=newpos.x-size.x, y=newpos.y, z=newpos.z-size.z}, vector.add(newpos, size), "mcl_chests:chest") + local chests = minetest.find_nodes_in_area(p1, p2, "mcl_chests:chest") -- Add desert temple loot into chests for c=1, #chests do @@ -402,7 +432,7 @@ mcl_structures.generate_desert_temple = function(pos) { itemstring = "mcl_mobitems:bone", weight = 25, amount_min = 4, amount_max=6 }, { itemstring = "mcl_mobitems:rotten_flesh", weight = 25, amount_min = 3, amount_max=7 }, { itemstring = "mcl_mobitems:spider_eye", weight = 25, amount_min = 1, amount_max=3 }, - { itemstack = mcl_enchanting.get_uniform_randomly_enchanted_book({"soul_speed"}), weight = 20, }, + { itemstack = mcl_enchanting.get_uniform_randomly_enchanted_book({"soul_speed"}, pr), weight = 20, }, { itemstring = "mcl_mobitems:saddle", weight = 20, }, { itemstring = "mcl_core:apple_gold", weight = 20, }, { itemstring = "mcl_core:gold_ingot", weight = 15, amount_min = 2, amount_max = 7 }, @@ -432,11 +462,11 @@ mcl_structures.generate_desert_temple = function(pos) init_node_construct(chests[c]) local meta = minetest.get_meta(chests[c]) local inv = meta:get_inventory() - mcl_loot.fill_inventory(inv, "main", lootitems) + mcl_loot.fill_inventory(inv, "main", lootitems, pr) end -- Initialize pressure plates and randomly remove up to 5 plates - local pplates = minetest.find_nodes_in_area({x=newpos.x-size.x, y=newpos.y, z=newpos.z-size.z}, vector.add(newpos, size), "mesecons_pressureplates:pressure_plate_stone_off") + local pplates = minetest.find_nodes_in_area(p1, p2, "mesecons_pressureplates:pressure_plate_stone_off") local pplates_remove = 5 for p=1, #pplates do if pplates_remove > 0 and pr:next(1, 100) >= 50 then @@ -448,8 +478,17 @@ mcl_structures.generate_desert_temple = function(pos) minetest.registered_nodes["mesecons_pressureplates:pressure_plate_stone_off"].on_construct(pplates[p]) end end +end - return ret +mcl_structures.generate_desert_temple = function(pos, rotation, pr) + -- No Generating for the temple ... Why using it ? No Change + local path = minetest.get_modpath("mcl_structures").."/schematics/mcl_structures_desert_temple.mts" + local newpos = {x=pos.x,y=pos.y-12,z=pos.z} + local size = {x=22, y=24, z=22} + if newpos == nil then + return + end + mcl_structures.place_schematic(newpos, path, rotation or "random", nil, true, nil, temple_placement_callback, pr) end local registered_structures = {} @@ -479,39 +518,58 @@ mcl_structures.register_structures = function(structure_type, structures) registered_structures[structure_type] = structures end +local function dir_to_rotation(dir) + local ax, az = math.abs(dir.x), math.abs(dir.z) + if ax > az then + if dir.x < 0 then + return "270" + end + return "90" + end + if dir.z < 0 then + return "180" + end + return "0" +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", + params = "desert_temple | desert_well | igloo | witch_hut | boulder | ice_spike_small | ice_spike_large | fossil | end_exit_portal | end_portal_shrine | dungeon", description = S("Generate a pre-defined structure near your position."), privs = {debug = true}, func = function(name, param) - local pos = minetest.get_player_by_name(name):get_pos() - if not pos then - return - end + local player = minetest.get_player_by_name(name) + if not player then return end + local pos = player:get_pos() + if not pos then return end pos = vector.round(pos) + local dir = minetest.yaw_to_dir(player:get_look_horizontal()) + local rot = dir_to_rotation(dir) + local pr = PseudoRandom(pos.x+pos.y+pos.z) local errord = false local message = S("Structure placed.") if param == "desert_temple" then - mcl_structures.generate_desert_temple(pos) + mcl_structures.generate_desert_temple(pos, rot, pr) elseif param == "desert_well" then - mcl_structures.generate_desert_well(pos) + mcl_structures.generate_desert_well(pos, rot) elseif param == "igloo" then - mcl_structures.generate_igloo(pos) + mcl_structures.generate_igloo(pos, rot, pr) elseif param == "witch_hut" then - mcl_structures.generate_witch_hut(pos) + mcl_structures.generate_witch_hut(pos, rot, pr) elseif param == "boulder" then - mcl_structures.generate_boulder(pos) + mcl_structures.generate_boulder(pos, rot, pr) elseif param == "fossil" then - mcl_structures.generate_fossil(pos) + mcl_structures.generate_fossil(pos, rot, pr) elseif param == "ice_spike_small" then - mcl_structures.generate_ice_spike_small(pos) + mcl_structures.generate_ice_spike_small(pos, rot, pr) elseif param == "ice_spike_large" then - mcl_structures.generate_ice_spike_large(pos) + mcl_structures.generate_ice_spike_large(pos, rot, pr) elseif param == "end_exit_portal" then - mcl_structures.generate_end_exit_portal(pos) + mcl_structures.generate_end_exit_portal(pos, rot, pr) elseif param == "end_portal_shrine" then - mcl_structures.generate_end_portal_shrine(pos) + 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 == "" then message = S("Error: No structure type given. Please use “/spawnstruct ”.") errord = true diff --git a/mods/MAPGEN/mcl_structures/mod.conf b/mods/MAPGEN/mcl_structures/mod.conf index 862441905..3150c7cec 100644 --- a/mods/MAPGEN/mcl_structures/mod.conf +++ b/mods/MAPGEN/mcl_structures/mod.conf @@ -1 +1,4 @@ name = mcl_structures +author = Wuzzy +description = Structures for MCL2 +depends = mcl_loot diff --git a/mods/MAPGEN/mcl_villages/buildings.lua b/mods/MAPGEN/mcl_villages/buildings.lua index 0d58739ed..18d6c1e0b 100644 --- a/mods/MAPGEN/mcl_villages/buildings.lua +++ b/mods/MAPGEN/mcl_villages/buildings.lua @@ -4,8 +4,8 @@ ------------------------------------------------------------------------------- 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_util.get_far_node(pos, true) - if not platform_material then + local platform_material = mcl_mapgen_core.get_node(pos) + if not platform_material or (platform_material.name == "air" or platform_material.name == "ignore") then return end platform_material = platform_material.name @@ -81,12 +81,15 @@ function settlements.create_site_plan(maxp, minp, pr) local possible_rotations = {"0", "90", "180", "270"} -- find center of chunk local center = { - x=maxp.x-half_map_chunk_size, + x=math.floor((minp.x+maxp.x)/2), y=maxp.y, - z=maxp.z-half_map_chunk_size + z=math.floor((minp.z+maxp.z)/2) } -- find center_surface of chunk - local center_surface , surface_material = settlements.find_surface(center) + local center_surface , surface_material = settlements.find_surface(center, true) + local chunks = {} + chunks[mcl_vars.get_chunk_number(center)] = true + -- go build settlement around center if not center_surface then return false end @@ -114,49 +117,57 @@ function settlements.create_site_plan(maxp, minp, pr) local x, z, r = center_surface.x, center_surface.z, building_all_info["hsize"] -- draw j circles around center and increase radius by math.random(2,5) for j = 1,20 do - if number_built < number_of_buildings then - -- set position on imaginary circle - for j = 0, 360, 15 do - local angle = j * math.pi / 180 - local ptx, ptz = x + r * math.cos( angle ), z + r * math.sin( angle ) - ptx = settlements.round(ptx, 0) - ptz = settlements.round(ptz, 0) - local pos1 = { x=ptx, y=center_surface.y+50, z=ptz} - local pos_surface, surface_material = settlements.find_surface(pos1) - if not pos_surface then break end + -- set position on imaginary circle + for j = 0, 360, 15 do + local angle = j * math.pi / 180 + local ptx, ptz = x + r * math.cos( angle ), z + r * math.sin( angle ) + ptx = settlements.round(ptx, 0) + ptz = settlements.round(ptz, 0) + local pos1 = { x=ptx, y=center_surface.y+50, z=ptz} + local chunk_number = mcl_vars.get_chunk_number(pos1) + local pos_surface, surface_material + if chunks[chunk_number] then + pos_surface, surface_material = settlements.find_surface(pos1) + else + chunks[chunk_number] = true + pos_surface, surface_material = settlements.find_surface(pos1, true) + end + if not pos_surface then break end - local randomized_schematic_table = shuffle(settlements.schematic_table, pr) - -- pick schematic - local size = #randomized_schematic_table - for i = size, 1, -1 do - -- already enough buildings of that type? - if count_buildings[randomized_schematic_table[i]["name"]] < randomized_schematic_table[i]["max_num"]*number_of_buildings then - building_all_info = randomized_schematic_table[i] - -- check distance to other buildings - local distance_to_other_buildings_ok = settlements.check_distance(settlement_info, pos_surface, building_all_info["hsize"]) - if distance_to_other_buildings_ok then - -- count built houses - count_buildings[building_all_info["name"]] = count_buildings[building_all_info["name"]] +1 - rotation = possible_rotations[ pr:next(1, #possible_rotations ) ] - number_built = number_built + 1 - settlement_info[index] = { - pos = pos_surface, - name = building_all_info["name"], - hsize = building_all_info["hsize"], - rotat = rotation, - surface_mat = surface_material - } - index = index + 1 - break - end + local randomized_schematic_table = shuffle(settlements.schematic_table, pr) + -- pick schematic + local size = #randomized_schematic_table + for i = size, 1, -1 do + -- already enough buildings of that type? + if count_buildings[randomized_schematic_table[i]["name"]] < randomized_schematic_table[i]["max_num"]*number_of_buildings then + building_all_info = randomized_schematic_table[i] + -- check distance to other buildings + local distance_to_other_buildings_ok = settlements.check_distance(settlement_info, pos_surface, building_all_info["hsize"]) + if distance_to_other_buildings_ok then + -- count built houses + count_buildings[building_all_info["name"]] = count_buildings[building_all_info["name"]] +1 + rotation = possible_rotations[ pr:next(1, #possible_rotations ) ] + number_built = number_built + 1 + settlement_info[index] = { + pos = pos_surface, + name = building_all_info["name"], + hsize = building_all_info["hsize"], + rotat = rotation, + surface_mat = surface_material + } + index = index + 1 + break end end - if number_of_buildings == number_built then - break - end end - r = r + pr:next(2,5) + if number_of_buildings == number_built then + break + end end + if number_built >= number_of_buildings then + break + end + r = r + pr:next(2,5) end settlements.debug("really ".. number_built) return settlement_info @@ -164,6 +175,36 @@ end ------------------------------------------------------------------------------- -- evaluate settlement_info and place schematics ------------------------------------------------------------------------------- +-- Initialize node +local function construct_node(p1, p2, name) + local r = minetest.registered_nodes[name] + if r then + if r.on_construct then + local nodes = minetest.find_nodes_in_area(p1, p2, name) + for p=1, #nodes do + local pos = nodes[p] + r.on_construct(pos) + end + return nodes + end + minetest.log("warning","[mcl_villages] No on_construct defined for node name " .. name) + return + end + minetest.log("warning","[mcl_villages] Attempt to 'construct' inexistant nodes: " .. name) +end +local function init_nodes(p1, p2, size, rotation, pr) + construct_node(p1, p2, "mcl_itemframes:item_frame") + construct_node(p1, p2, "mcl_furnaces:furnace") + construct_node(p1, p2, "mcl_anvils:anvil") + + local nodes = construct_node(p1, p2, "mcl_chests:chest") + if nodes and #nodes > 0 then + for p=1, #nodes do + local pos = nodes[p] + settlements.fill_chest(pos, pr) + end + end +end function settlements.place_schematics(settlement_info, pr) local building_all_info for i, built_house in ipairs(settlement_info) do @@ -227,11 +268,15 @@ function settlements.place_schematics(settlement_info, pr) local schematic = loadstring(schem_lua)() -- build foundation for the building an make room above -- place schematic - minetest.place_schematic( + mcl_structures.place_schematic( pos, schematic, rotation, nil, - true) + true, + nil, + init_nodes, + pr + ) end end diff --git a/mods/MAPGEN/mcl_villages/depends.txt b/mods/MAPGEN/mcl_villages/depends.txt deleted file mode 100644 index e9d14ad9b..000000000 --- a/mods/MAPGEN/mcl_villages/depends.txt +++ /dev/null @@ -1,5 +0,0 @@ -mcl_util -mcl_core -mcl_loot -mcl_farming? -mobs_mc? diff --git a/mods/MAPGEN/mcl_villages/foundation.lua b/mods/MAPGEN/mcl_villages/foundation.lua index 98726966c..67a2385f7 100644 --- a/mods/MAPGEN/mcl_villages/foundation.lua +++ b/mods/MAPGEN/mcl_villages/foundation.lua @@ -51,11 +51,12 @@ function settlements.terraform(settlement_info, pr) settlements.ground(p, pr) else -- write ground - local p = {x=pos.x+xi, y=pos.y+yi, z=pos.z+zi} - local node = mcl_util.get_far_node(p, true) - if node and node.name ~= "air" then - minetest.swap_node(p,{name="air"}) - end +-- local p = {x=pos.x+xi, y=pos.y+yi, z=pos.z+zi} +-- local node = mcl_mapgen_core.get_node(p) +-- if node and node.name ~= "air" then +-- minetest.swap_node(p,{name="air"}) +-- end + minetest.swap_node({x=pos.x+xi, y=pos.y+yi, z=pos.z+zi},{name="air"}) end end end diff --git a/mods/MAPGEN/mcl_villages/init.lua b/mods/MAPGEN/mcl_villages/init.lua index 287b4c9be..19de10b98 100644 --- a/mods/MAPGEN/mcl_villages/init.lua +++ b/mods/MAPGEN/mcl_villages/init.lua @@ -52,7 +52,7 @@ end -- -- on map generation, try to build a settlement -- -local function build_a_settlement_no_delay(minp, maxp, blockseed) +local function build_a_settlement(minp, maxp, blockseed) local pr = PseudoRandom(blockseed) -- fill settlement_info with buildings and their data @@ -67,35 +67,30 @@ local function build_a_settlement_no_delay(minp, maxp, blockseed) -- evaluate settlement_info and place schematics settlements.place_schematics(settlement_info, pr) - - -- evaluate settlement_info and initialize furnaces and chests - settlements.initialize_nodes(settlement_info, pr) end -local function ecb_build_a_settlement(blockpos, action, calls_remaining, param) - if calls_remaining <= 0 then - build_a_settlement_no_delay(param.minp, param.maxp, param.blockseed) - end +local function ecb_village(blockpos, action, calls_remaining, param) + if calls_remaining >= 1 then return end + local minp, maxp, blockseed = param.minp, param.maxp, param.blockseed + build_a_settlement(minp, maxp, blockseed) end -- Disable natural generation in singlenode. local mg_name = minetest.get_mapgen_setting("mg_name") if mg_name ~= "singlenode" then - minetest.register_on_generated(function(minp, maxp, blockseed) - -- needed for manual and automated settlement building - local heightmap = minetest.get_mapgen_object("heightmap") - - -- randomly try to build settlements - if blockseed % 77 ~= 17 then return end - + mcl_mapgen_core.register_generator("villages", nil, function(minp, maxp, blockseed) -- don't build settlement underground if maxp.y < 0 then return end - + -- randomly try to build settlements + if blockseed % 77 ~= 17 then return end + -- needed for manual and automated settlement building -- don't build settlements on (too) uneven terrain - local height_difference = settlements.evaluate_heightmap(minp, maxp) + local heightmap = minetest.get_mapgen_object("heightmap") + local height_difference = settlements.evaluate_heightmap() if height_difference > max_height_difference then return end - -- we need 'minetest.after' here to exit from emerging thread we probably currently in: - minetest.after(0.1, build_a_settlement_no_delay, vector.new(minp), vector.new(maxp), blockseed) + + local param={minp=vector.new(minp), maxp=vector.new(maxp), blockseed=blockseed} + minetest.emerge_area(minp, maxp, ecb_village, param) end) end -- manually place villages @@ -108,7 +103,8 @@ if minetest.is_creative_enabled("") then if not pointed_thing.under then return end local minp = vector.subtract( pointed_thing.under, half_map_chunk_size) local maxp = vector.add( pointed_thing.under, half_map_chunk_size) - build_a_settlement_no_delay(minp, maxp, math.random(0,32767)) + build_a_settlement(minp, maxp, math.random(0,32767)) end }) + mcl_wip.register_experimental_item("mcl_villages:tool") end diff --git a/mods/MAPGEN/mcl_villages/mod.conf b/mods/MAPGEN/mcl_villages/mod.conf new file mode 100644 index 000000000..d8e2aa7d4 --- /dev/null +++ b/mods/MAPGEN/mcl_villages/mod.conf @@ -0,0 +1,5 @@ +name = mcl_villages +author = Rochambeau +description = This mod adds settlements on world generation. +depends = mcl_util, mcl_mapgen_core, mcl_structures, mcl_core, mcl_loot +optional_depends = mcl_farming, mobs_mc diff --git a/mods/MAPGEN/mcl_villages/utils.lua b/mods/MAPGEN/mcl_villages/utils.lua index c539e7dc1..2d96ba26f 100644 --- a/mods/MAPGEN/mcl_villages/utils.lua +++ b/mods/MAPGEN/mcl_villages/utils.lua @@ -45,31 +45,27 @@ end -- function to find surface block y coordinate -- returns surface postion ------------------------------------------------------------------------------- -function settlements.find_surface(pos) +function settlements.find_surface(pos, wait) local p6 = vector.new(pos) local cnt = 0 - local itter -- count up or down + local itter = 1 -- count up or down local cnt_max = 200 -- check, in which direction to look for surface - local surface_node = mcl_util.get_far_node(p6, true) - if surface_node and string.find(surface_node.name,"air") then - itter = -1 + local surface_node + if wait then + surface_node = mcl_mapgen_core.get_node(p6, true, 10000000) else - itter = 1 + surface_node = mcl_mapgen_core.get_node(p6) + end + if surface_node.name=="air" or surface_node.name=="ignore" then + itter = -1 end -- go through nodes an find surface while cnt < cnt_max do - cnt = cnt+1 - surface_node = mcl_util.get_far_node(p6, true) - if surface_node.name == "ignore" then - settlements.debug("find_surface1: nil or ignore") - return nil - end - -- Check Surface_node and Node above -- if settlements.surface_mat[surface_node.name] then - local surface_node_plus_1 = mcl_util.get_far_node({ x=p6.x, y=p6.y+1, z=p6.z}, true) + local surface_node_plus_1 = mcl_mapgen_core.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 @@ -93,6 +89,8 @@ function settlements.find_surface(pos) settlements.debug("find_surface4: y<0") return nil end + cnt = cnt+1 + surface_node = mcl_mapgen_core.get_node(p6) end settlements.debug("find_surface5: cnt_max overflow") return nil @@ -180,7 +178,7 @@ function settlements.fill_chest(pos, pr) end local items = get_treasures(pr) - mcl_loot.fill_inventory(inv, "main", items) + mcl_loot.fill_inventory(inv, "main", items, pr) end ------------------------------------------------------------------------------- @@ -220,43 +218,6 @@ function settlements.initialize_anvil(pos) end end ------------------------------------------------------------------------------- --- initialize furnace, chests, anvil -------------------------------------------------------------------------------- -local building_all_info -function settlements.initialize_nodes(settlement_info, pr) - for i, built_house in ipairs(settlement_info) do - for j, schem in ipairs(settlements.schematic_table) do - if settlement_info[i]["name"] == schem["name"] then - building_all_info = schem - break - end - end - - local width = building_all_info["hwidth"] - local depth = building_all_info["hdepth"] - local height = building_all_info["hheight"] - - local p = settlement_info[i]["pos"] - for yi = 1,height do - for xi = 0,width do - for zi = 0,depth do - local ptemp = {x=p.x+xi, y=p.y+yi, z=p.z+zi} - local node = mcl_util.get_far_node(ptemp, true) - if node.name == "mcl_furnaces:furnace" or - node.name == "mcl_chests:chest" or - node.name == "mcl_anvils:anvil" then - minetest.registered_nodes[node.name].on_construct(ptemp) - end - -- when chest is found -> fill with stuff - if node.name == "mcl_chests:chest" then - minetest.after(3, settlements.fill_chest, ptemp, pr) - end - end - end - end - end -end -------------------------------------------------------------------------------- -- randomize table ------------------------------------------------------------------------------- function shuffle(tbl, pr) @@ -272,44 +233,39 @@ end -- evaluate heightmap ------------------------------------------------------------------------------- function settlements.evaluate_heightmap() - local heightmap = minetest.get_mapgen_object("heightmap") - -- max height and min height, initialize with impossible values for easier first time setting - local max_y = -50000 - local min_y = 50000 - -- only evaluate the center square of heightmap 40 x 40 - local square_start = 1621 - local square_end = 1661 - for j = 1 , 40, 1 do - for i = square_start, square_end, 1 do - -- skip buggy heightmaps, return high value - if heightmap[i] == -31000 or - heightmap[i] == 31000 - then - return max_height_difference + 1 - end - if heightmap[i] < min_y - then - min_y = heightmap[i] - end - if heightmap[i] > max_y - then - max_y = heightmap[i] - end - end - -- set next line - square_start = square_start + 80 - square_end = square_end + 80 - end - -- return the difference between highest and lowest pos in chunk - local height_diff = max_y - min_y - -- filter buggy heightmaps - if height_diff <= 1 - then - return max_height_difference + 1 - end - -- debug info - settlements.debug("heightdiff ".. height_diff) - return height_diff + local heightmap = minetest.get_mapgen_object("heightmap") + -- max height and min height, initialize with impossible values for easier first time setting + local max_y = -50000 + local min_y = 50000 + -- only evaluate the center square of heightmap 40 x 40 + local square_start = 1621 + local square_end = 1661 + for j = 1 , 40, 1 do + for i = square_start, square_end, 1 do + -- skip buggy heightmaps, return high value + if heightmap[i] == -31000 or heightmap[i] == 31000 then + return max_height_difference + 1 + end + if heightmap[i] < min_y then + min_y = heightmap[i] + end + if heightmap[i] > max_y then + max_y = heightmap[i] + end + end + -- set next line + square_start = square_start + 80 + square_end = square_end + 80 + end + -- return the difference between highest and lowest pos in chunk + local height_diff = max_y - min_y + -- filter buggy heightmaps + if height_diff <= 1 then + return max_height_difference + 1 + end + -- debug info + settlements.debug("heightdiff ".. height_diff) + return height_diff end ------------------------------------------------------------------------------- -- Set array to list diff --git a/mods/MAPGEN/tsm_railcorridors/depends.txt b/mods/MAPGEN/tsm_railcorridors/depends.txt deleted file mode 100644 index a22565d76..000000000 --- a/mods/MAPGEN/tsm_railcorridors/depends.txt +++ /dev/null @@ -1,8 +0,0 @@ -mcl_init -mcl_worlds -mcl_core -mcl_loot -mcl_tnt -mcl_farming -mcl_mobspawners -mcl_minecarts diff --git a/mods/MAPGEN/tsm_railcorridors/description.txt b/mods/MAPGEN/tsm_railcorridors/description.txt deleted file mode 100644 index 33bfd506a..000000000 --- a/mods/MAPGEN/tsm_railcorridors/description.txt +++ /dev/null @@ -1 +0,0 @@ -Adds simple underground mines with railways and occasional treasure chests. diff --git a/mods/MAPGEN/tsm_railcorridors/gameconfig.lua b/mods/MAPGEN/tsm_railcorridors/gameconfig.lua index 00e2af687..904c3af08 100644 --- a/mods/MAPGEN/tsm_railcorridors/gameconfig.lua +++ b/mods/MAPGEN/tsm_railcorridors/gameconfig.lua @@ -66,7 +66,7 @@ function tsm_railcorridors.get_treasures(pr) items = { { itemstring = "mcl_mobs:nametag", weight = 30 }, { itemstring = "mcl_core:apple_gold", weight = 20 }, - { itemstack = mcl_enchanting.get_uniform_randomly_enchanted_book({"soul_speed"}), weight = 10 }, + { itemstack = mcl_enchanting.get_uniform_randomly_enchanted_book({"soul_speed"}, pr), weight = 10 }, { itemstring = "", weight = 5}, { itemstring = "mcl_core:pick_iron", weight = 5 }, { itemstring = "mcl_core:apple_gold_enchanted", weight = 1 }, diff --git a/mods/MAPGEN/tsm_railcorridors/init.lua b/mods/MAPGEN/tsm_railcorridors/init.lua index f2e02d997..893f3d739 100644 --- a/mods/MAPGEN/tsm_railcorridors/init.lua +++ b/mods/MAPGEN/tsm_railcorridors/init.lua @@ -380,7 +380,7 @@ local function PlaceChest(pos, param2) local meta = minetest.get_meta(pos) local inv = meta:get_inventory() local items = tsm_railcorridors.get_treasures(pr) - mcl_loot.fill_inventory(inv, "main", items) + mcl_loot.fill_inventory(inv, "main", items, pr) end end @@ -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) @@ -1089,7 +1089,7 @@ local function create_corridor_system(main_cave_coords) end -- The rail corridor algorithm starts here -minetest.register_on_generated(function(minp, maxp, blockseed) +mcl_mapgen_core.register_generator("railcorridors", nil, function(minp, maxp, blockseed, _pr) -- We re-init the randomizer for every mapchunk as we start generating in the middle of each mapchunk. -- We can't use the mapgen seed as this would make the algorithm depending on the order the mapchunk generate. InitRandomizer(blockseed) @@ -1115,4 +1115,4 @@ minetest.register_on_generated(function(minp, maxp, blockseed) end end end -end) +end, 10) diff --git a/mods/MAPGEN/tsm_railcorridors/mod.conf b/mods/MAPGEN/tsm_railcorridors/mod.conf index db3b9740b..c846cff19 100644 --- a/mods/MAPGEN/tsm_railcorridors/mod.conf +++ b/mods/MAPGEN/tsm_railcorridors/mod.conf @@ -1 +1,4 @@ name = tsm_railcorridors +author = UgnilJoZ +description = Adds simple underground mines with railways and occasional treasure chests. +depends = mcl_init, mcl_worlds, mcl_core, mcl_mapgen_core, mcl_loot, mcl_tnt, mcl_farming, mcl_mobspawners, mcl_minecarts diff --git a/mods/MISC/findbiome/mod.conf b/mods/MISC/findbiome/mod.conf index a8ab4e3c1..918f18436 100644 --- a/mods/MISC/findbiome/mod.conf +++ b/mods/MISC/findbiome/mod.conf @@ -1,3 +1,4 @@ -name=findbiome -description=Add commands to list and find biomes -optional_depends=biomeinfo +name = findbiome +author = paramat +description = Add commands to list and find biomes +optional_depends = biomeinfo diff --git a/mods/MISC/mcl_commands/alias.lua b/mods/MISC/mcl_commands/alias.lua new file mode 100644 index 000000000..2989b7b37 --- /dev/null +++ b/mods/MISC/mcl_commands/alias.lua @@ -0,0 +1,30 @@ +local S = minetest.get_translator("mcl_commands") + +local function register_chatcommand_alias(alias, cmd) + local def = minetest.chatcommands[cmd] + minetest.register_chatcommand(alias, def) +end + +local function rename_chatcommand(newname, cmd) + local def = minetest.chatcommands[cmd] + minetest.register_chatcommand(newname, def) + minetest.unregister_chatcommand(cmd) +end + +if minetest.settings:get_bool("mcl_builtin_commands_overide", true) then + register_chatcommand_alias("?", "help") + register_chatcommand_alias("pardon", "unban") + rename_chatcommand("stop", "shutdown") + register_chatcommand_alias("tell", "msg") + register_chatcommand_alias("w", "msg") + register_chatcommand_alias("tp", "teleport") + rename_chatcommand("clear", "clearinv") + + minetest.register_chatcommand("banlist", { + description = S("List bans"), + privs = minetest.chatcommands["ban"].privs, + func = function(name) + return true, S("Ban list: @1", minetest.get_ban_list()) + end, + }) +end \ No newline at end of file diff --git a/mods/MISC/mcl_commands/depends.txt b/mods/MISC/mcl_commands/depends.txt deleted file mode 100644 index 6e14ff130..000000000 --- a/mods/MISC/mcl_commands/depends.txt +++ /dev/null @@ -1 +0,0 @@ -mcl_death_messages? diff --git a/mods/MISC/mcl_commands/init.lua b/mods/MISC/mcl_commands/init.lua index 8b931d0b8..7a9fe4868 100644 --- a/mods/MISC/mcl_commands/init.lua +++ b/mods/MISC/mcl_commands/init.lua @@ -1,163 +1,15 @@ -local minecraftaliases = true - local S = minetest.get_translator("mcl_commands") local mod_death_messages = minetest.get_modpath("mcl_death_messages") -local function handle_kill_command(suspect, victim) - if minetest.settings:get_bool("enable_damage") == false then - return false, S("Players can't be killed right now, damage has been disabled.") - end - local victimref = minetest.get_player_by_name(victim) - if victimref == nil then - return false, S("Player @1 does not exist.", victim) - elseif victimref:get_hp() <= 0 then - if suspect == victim then - return false, S("You are already dead") - else - return false, S("@1 is already dead", victim) - end - end - -- If player holds a totem of undying, destroy it before killing, - -- so it doesn't rescue the player. - local wield = victimref:get_wielded_item() - if wield:get_name() == "mobs_mc:totem" then - victimref:set_wielded_item("") - end - if mod_death_messages then - local msg - if suspect == victim then - msg = S("@1 committed suicide.", victim) - else - msg = S("@1 was killed by @2.", victim, suspect) - end - mcl_death_messages.player_damage(victimref, msg) - end - -- DIE! - victimref:set_hp(0) - -- Log - if not suspect == victim then - minetest.log("action", string.format("%s killed %s using /kill", suspect, victim)) - else - minetest.log("action", string.format("%s committed suicide using /kill", victim)) - end - return true -end +local modpath = minetest.get_modpath(minetest.get_current_modname()) -if minetest.registered_chatcommands["kill"] then - minetest.unregister_chatcommand("kill") -end -minetest.register_chatcommand("kill", { - params = S("[]"), - description = S("Kill player or yourself"), - privs = {server=true}, - func = function(name, param) - if(param == "") then - -- Selfkill - return handle_kill_command(name, name) - else - return handle_kill_command(name, param) - end - end, -}) - -minetest.register_privilege("announce", { - description = S("Can use /say"), - give_to_singleplayer = false, -}) -minetest.register_chatcommand("say", { - params = S(""), - description = S("Send a message to every player"), - privs = {announce=true}, - func = function(name, param) - if not param then - return false, S("Invalid usage, see /help say.") - end - minetest.chat_send_all(("["..name.."] "..param)) - return true - end, -}) - -minetest.register_chatcommand("setblock", { - params = S(",, "), - description = S("Set node at given position"), - privs = {give=true, interact=true}, - func = function(name, param) - local p = {} - local nodestring = nil - p.x, p.y, p.z, nodestring = param:match("^([%d.-]+)[, ] *([%d.-]+)[, ] *([%d.-]+) +(.+)$") - p.x, p.y, p.z = tonumber(p.x), tonumber(p.y), tonumber(p.z) - if p.x and p.y and p.z and nodestring then - local itemstack = ItemStack(nodestring) - if itemstack:is_empty() or not minetest.registered_nodes[itemstack:get_name()] then - return false, S("Invalid node") - end - minetest.set_node(p, {name=nodestring}) - return true, S("@1 spawned.", nodestring) - end - return false, S("Invalid parameters (see /help setblock)") - end, -}) - -minetest.register_chatcommand("list", { - description = S("Show who is logged on"), - params = "", - privs = {}, - func = function(name) - local players = "" - for _, player in ipairs(minetest.get_connected_players()) do - players = players..player:get_player_name().."\n" - end - minetest.chat_send_player(name, players) - end -}) - -minetest.register_chatcommand("seed", { - description = S("Displays the world seed"), - params = "", - privs = {}, - func = function(name) - minetest.chat_send_player(name, minetest.get_mapgen_setting("seed")) - end -}) - -local function register_chatcommand_alias(alias, cmd) - local def = minetest.chatcommands[cmd] - minetest.register_chatcommand(alias, def) -end - --- Replace spawnentity cmd to disallow spawning of hostile mobs if disabled -local orig_func = minetest.registered_chatcommands["spawnentity"].func -local cmd = table.copy(minetest.registered_chatcommands["spawnentity"]) -cmd.func = function(name, param) - local ent = minetest.registered_entities[param] - if minetest.settings:get_bool("only_peaceful_mobs", false) and ent and ent._cmi_is_mob and ent.type == "monster" then - return false, S("Only peaceful mobs allowed!") - else - local bool, msg = orig_func(name, param) - return bool, msg - end -end -minetest.unregister_chatcommand("spawnentity") -minetest.register_chatcommand("spawnentity", cmd) - -if minecraftaliases then - register_chatcommand_alias("?", "help") - register_chatcommand_alias("who", "list") - register_chatcommand_alias("pardon", "unban") - register_chatcommand_alias("stop", "shutdown") - register_chatcommand_alias("summon", "spawnentity") - register_chatcommand_alias("tell", "msg") - register_chatcommand_alias("w", "msg") - register_chatcommand_alias("tp", "teleport") - register_chatcommand_alias("clear", "clearinv") - - minetest.register_chatcommand("banlist", { - description = S("List bans"), - privs = minetest.chatcommands["ban"].privs, - func = function(name) - return true, S("Ban list: @1", minetest.get_ban_list()) - end, - }) -end +dofile(modpath.."/kill.lua") +dofile(modpath.."/setblock.lua") +dofile(modpath.."/seed.lua") +dofile(modpath.."/summon.lua") +dofile(modpath.."/say.lua") +dofile(modpath.."/list.lua") +dofile(modpath.."/sound.lua") +dofile(modpath.."/alias.lua") \ No newline at end of file diff --git a/mods/MISC/mcl_commands/kill.lua b/mods/MISC/mcl_commands/kill.lua new file mode 100644 index 000000000..2de69e6a0 --- /dev/null +++ b/mods/MISC/mcl_commands/kill.lua @@ -0,0 +1,59 @@ +local S = minetest.get_translator("mcl_commands") +local mod_death_messages = minetest.get_modpath("mcl_death_messages") + +local function handle_kill_command(suspect, victim) + if minetest.settings:get_bool("enable_damage") == false then + return false, S("Players can't be killed right now, damage has been disabled.") + end + local victimref = minetest.get_player_by_name(victim) + if victimref == nil then + return false, S("Player @1 does not exist.", victim) + elseif victimref:get_hp() <= 0 then + if suspect == victim then + return false, S("You are already dead") + else + return false, S("@1 is already dead", victim) + end + end + -- If player holds a totem of undying, destroy it before killing, + -- so it doesn't rescue the player. + local wield = victimref:get_wielded_item() + if wield:get_name() == "mobs_mc:totem" then + victimref:set_wielded_item("") + end + if mod_death_messages then + local msg + if suspect == victim then + msg = S("@1 committed suicide.", victim) + else + msg = S("@1 was killed by @2.", victim, suspect) + end + mcl_death_messages.player_damage(victimref, msg) + end + -- DIE! + victimref:set_hp(0) + -- Log + if not suspect == victim then + minetest.log("action", string.format("%s killed %s using /kill", suspect, victim)) + else + minetest.log("action", string.format("%s committed suicide using /kill", victim)) + end + return true +end + +if minetest.registered_chatcommands["kill"] then + minetest.unregister_chatcommand("kill") +end +minetest.register_chatcommand("kill", { + params = S("[]"), + description = S("Kill player or yourself"), + privs = {server=true}, + func = function(name, param) + if(param == "") then + -- Selfkill + return handle_kill_command(name, name) + else + return handle_kill_command(name, param) + end + end, +}) \ No newline at end of file diff --git a/mods/MISC/mcl_commands/list.lua b/mods/MISC/mcl_commands/list.lua new file mode 100644 index 000000000..0257e2837 --- /dev/null +++ b/mods/MISC/mcl_commands/list.lua @@ -0,0 +1,14 @@ +local S = minetest.get_translator("mcl_commands") + +minetest.register_chatcommand("list", { + description = S("Show who is logged on"), + params = "", + privs = {}, + func = function(name) + local players = "" + for _, player in ipairs(minetest.get_connected_players()) do + players = players..player:get_player_name().."\n" + end + minetest.chat_send_player(name, players) + end +}) \ No newline at end of file diff --git a/mods/MISC/mcl_commands/mod.conf b/mods/MISC/mcl_commands/mod.conf new file mode 100644 index 000000000..d651fad7b --- /dev/null +++ b/mods/MISC/mcl_commands/mod.conf @@ -0,0 +1,4 @@ +name = mcl_commands +author = Wuzzy +description = MCL2 commands +optional_depends = mcl_death_messages diff --git a/mods/MISC/mcl_commands/say.lua b/mods/MISC/mcl_commands/say.lua new file mode 100644 index 000000000..2b01a7e93 --- /dev/null +++ b/mods/MISC/mcl_commands/say.lua @@ -0,0 +1,18 @@ +local S = minetest.get_translator("mcl_commands") + +minetest.register_privilege("announce", { + description = S("Can use /say"), + give_to_singleplayer = false, +}) +minetest.register_chatcommand("say", { + params = S(""), + description = S("Send a message to every player"), + privs = {announce=true}, + func = function(name, param) + if not param then + return false, S("Invalid usage, see /help say.") + end + minetest.chat_send_all(("["..name.."] "..param)) + return true + end, +}) \ No newline at end of file diff --git a/mods/MISC/mcl_commands/seed.lua b/mods/MISC/mcl_commands/seed.lua new file mode 100644 index 000000000..da5f6a303 --- /dev/null +++ b/mods/MISC/mcl_commands/seed.lua @@ -0,0 +1,10 @@ +local S = minetest.get_translator("mcl_commands") + +minetest.register_chatcommand("seed", { + description = S("Displays the world seed"), + params = "", + privs = {}, + func = function(name) + minetest.chat_send_player(name, "Seed: "..minetest.get_mapgen_setting("seed")) + end +}) \ No newline at end of file diff --git a/mods/MISC/mcl_commands/setblock.lua b/mods/MISC/mcl_commands/setblock.lua new file mode 100644 index 000000000..30d68b74f --- /dev/null +++ b/mods/MISC/mcl_commands/setblock.lua @@ -0,0 +1,22 @@ +local S = minetest.get_translator("mcl_commands") + +minetest.register_chatcommand("setblock", { + params = S(",, "), + description = S("Set node at given position"), + privs = {give=true, interact=true}, + func = function(name, param) + local p = {} + local nodestring = nil + p.x, p.y, p.z, nodestring = param:match("^([%d.-]+)[, ] *([%d.-]+)[, ] *([%d.-]+) +(.+)$") + p.x, p.y, p.z = tonumber(p.x), tonumber(p.y), tonumber(p.z) + if p.x and p.y and p.z and nodestring then + local itemstack = ItemStack(nodestring) + if itemstack:is_empty() or not minetest.registered_nodes[itemstack:get_name()] then + return false, S("Invalid node") + end + minetest.set_node(p, {name=nodestring}) + return true, S("@1 spawned.", nodestring) + end + return false, S("Invalid parameters (see /help setblock)") + end, +}) \ No newline at end of file diff --git a/mods/MISC/mcl_commands/sound.lua b/mods/MISC/mcl_commands/sound.lua new file mode 100644 index 000000000..934abb80e --- /dev/null +++ b/mods/MISC/mcl_commands/sound.lua @@ -0,0 +1,48 @@ +local S = minetest.get_translator("mcl_commands") + +minetest.register_chatcommand("playsound",{ + params = S(" "), --TODO:add source + description = S("Play a sound. Arguments: : name of the sound. : Target."), + privs = {server = true}, + func = function(name, params) + local P = {} + local i = 0 + for str in string.gmatch(params, "([^ ]+)") do + i = i + 1 + P[i] = str + end + + local params = {} + if P[1] == tostring(P[1]) then + params.name = P[1] + else + return false, S("Sound name is invalid!") --TODO: add mc chat message + end + + if P[2] == tostring(P[2]) and minetest.player_exists(P[2]) then + params.target = P[2] + else + return false, S("Target is invalid!!") + end + + -- if P[3] then + -- params.pos = nil --TODO:position + -- else + -- params.pos = nil + -- end + + -- if P[4] == tonumber(P[4]) then + -- params.gain = P[4] + -- else + -- params.gain = 1.0 + -- end + + -- if P[5] == tonumber(P[5]) then + -- params.pitch = P[5] + -- else + -- params.pitch = 1.0 + -- end + minetest.sound_play({name = params.name}, {to_player = params.target}, true) --TODO: /stopsound + return true + end, +}) \ No newline at end of file diff --git a/mods/MISC/mcl_commands/summon.lua b/mods/MISC/mcl_commands/summon.lua new file mode 100644 index 000000000..eb6066ff8 --- /dev/null +++ b/mods/MISC/mcl_commands/summon.lua @@ -0,0 +1,15 @@ +local S = minetest.get_translator("mcl_commands") + +local orig_func = minetest.registered_chatcommands["spawnentity"].func +local cmd = table.copy(minetest.registered_chatcommands["spawnentity"]) +cmd.func = function(name, param) + local ent = minetest.registered_entities[param] + if minetest.settings:get_bool("only_peaceful_mobs", false) and ent and ent._cmi_is_mob and ent.type == "monster" then + return false, S("Only peaceful mobs allowed!") + else + local bool, msg = orig_func(name, param) + return bool, msg + end +end +minetest.unregister_chatcommand("spawnentity") +minetest.register_chatcommand("summon", cmd) \ No newline at end of file diff --git a/mods/MISC/mcl_privs/description.txt b/mods/MISC/mcl_privs/description.txt deleted file mode 100644 index 23beb168b..000000000 --- a/mods/MISC/mcl_privs/description.txt +++ /dev/null @@ -1 +0,0 @@ -Shared privileges in MineClone 2 diff --git a/mods/MISC/mcl_privs/mod.conf b/mods/MISC/mcl_privs/mod.conf new file mode 100644 index 000000000..ab1f61877 --- /dev/null +++ b/mods/MISC/mcl_privs/mod.conf @@ -0,0 +1,4 @@ +name = mcl_privs +author = Wuzzy +description = Shared privileges in MineClone 2 + diff --git a/mods/MISC/mcl_temp_helper_recipes/depends.txt b/mods/MISC/mcl_temp_helper_recipes/depends.txt deleted file mode 100644 index 71556b9ae..000000000 --- a/mods/MISC/mcl_temp_helper_recipes/depends.txt +++ /dev/null @@ -1,7 +0,0 @@ -mcl_core -mcl_mobitems -mcl_end -mcl_nether -mcl_ocean -mcl_stairs -xpanes diff --git a/mods/MISC/mcl_temp_helper_recipes/mod.conf b/mods/MISC/mcl_temp_helper_recipes/mod.conf new file mode 100644 index 000000000..8fff70ece --- /dev/null +++ b/mods/MISC/mcl_temp_helper_recipes/mod.conf @@ -0,0 +1,5 @@ +name = mcl_temp_helper_recipes +author = Wuzzy +description = Temporary helper recipes. +depends = mcl_core, mcl_mobitems, mcl_end, mcl_nether, mcl_ocean, mcl_stairs, xpanes + diff --git a/mods/MISC/mcl_wip/depends.txt b/mods/MISC/mcl_wip/depends.txt deleted file mode 100644 index 4f2001472..000000000 --- a/mods/MISC/mcl_wip/depends.txt +++ /dev/null @@ -1,10 +0,0 @@ -mcl_core -mcl_fishing -mcl_maps -mcl_minecarts -doc_identifier -mobs_mc -mcl_comparators -mcl_minecarts -mcl_paintings -mcl_potions diff --git a/mods/MISC/mcl_wip/description.txt b/mods/MISC/mcl_wip/description.txt deleted file mode 100644 index d90115acf..000000000 --- a/mods/MISC/mcl_wip/description.txt +++ /dev/null @@ -1 +0,0 @@ -Development mod for MineClone 2 which add a “WIP” (Work In Progress) comment to items which are considered to be very unfinished. diff --git a/mods/MISC/mcl_wip/init.lua b/mods/MISC/mcl_wip/init.lua index 22785d85a..0eb56dd84 100644 --- a/mods/MISC/mcl_wip/init.lua +++ b/mods/MISC/mcl_wip/init.lua @@ -2,68 +2,44 @@ local S = minetest.get_translator("mcl_wip") -local wip_items = { - "mcl_maps:empty_map", - "mcl_comparators:comparator_off_comp", - "mcl_minecarts:hopper_minecart", - "mcl_minecarts:command_block_minecart", - "mcl_minecarts:chest_minecart", - "mcl_minecarts:furnace_minecart", - "mobs_mc:enderdragon", - "mobs_mc:wither", - "mobs_mc:witch", - "screwdriver:screwdriver", - "mcl_paintings:painting", - "mcl_potions:night_vision", - "mcl_potions:night_vision_plus", - -- "mcl_potions:weakness", - -- "mcl_potions:weakness_plus", - -- "mcl_potions:strength", - -- "mcl_potions:strength_plus", - -- "mcl_potions:strength_2", - "mcl_potions:night_vision_splash", - "mcl_potions:night_vision_plus_splash", - -- "mcl_potions:weakness_splash", - -- "mcl_potions:weakness_plus_splash", - -- "mcl_potions:strength_splash", - -- "mcl_potions:strength_plus_splash", - -- "mcl_potions:strength_2_splash", - "mcl_potions:night_vision_lingering", - "mcl_potions:night_vision_plus_lingering", - -- "mcl_potions:weakness_lingering", - -- "mcl_potions:weakness_plus_lingering", - -- "mcl_potions:strength_lingering", - -- "mcl_potions:strength_plus_lingering", - -- "mcl_potions:strength_2_lingering", - "mcl_potions:night_vision_arrow", - "mcl_potions:night_vision_plus_arrow", -} -local experimental_items = { -} +mcl_wip = {} +mcl_wip.registered_wip_items = {} +mcl_wip.registered_experimental_items = {} -for i=1,#wip_items do - local def = minetest.registered_items[wip_items[i]] - if not def then - minetest.log("error", "[mcl_wip] Unknown item: "..wip_items[i]) - break - end - local new_description = def.description - local new_groups = table.copy(def.groups) - if new_description == "" then - new_description = wip_items[i] - end - new_description = new_description .. "\n"..core.colorize("#FF0000", S("(WIP)")) - --new_groups.not_in_craft_guide = 1 - minetest.override_item(wip_items[i], { description = new_description, groups = new_groups }) +function mcl_wip.register_wip_item(itemname) + table.insert(mcl_wip.registered_wip_items, itemname) --Only check for valid node name after mods loaded end -for i=1,#experimental_items do - local def = minetest.registered_items[experimental_items[i]] - if not def then - minetest.log("error", "[mcl_wip] Unknown item: "..experimental_items[i]) - break - end - local new_description = def.description - new_description = new_description .. "\n"..core.colorize("#FFFF00", S("(Temporary)")) - minetest.override_item(experimental_items[i], { description = new_description }) +function mcl_wip.register_experimental_item(itemname) + table.insert(mcl_wip.registered_experimental_items, itemname) end + +minetest.register_on_mods_loaded(function() + for _,name in pairs(mcl_wip.registered_wip_items) do + local def = minetest.registered_items[name] + if not def then + minetest.log("error", "[mcl_wip] Unknown item: "..name) + break + end + local new_description = def.description + if new_description == "" then + new_description = name + end + new_description = new_description .. "\n"..minetest.colorize(mcl_colors.RED, S("(WIP)")) + minetest.override_item(name, {description = new_description}) + end + + for _,name in pairs(mcl_wip.registered_experimental_items) do + local def = minetest.registered_items[name] + if not def then + minetest.log("error", "[mcl_wip] Unknown item: "..name) + break + end + local new_description = def.description + if new_description == "" then + new_description = name + end + new_description = new_description .. "\n"..minetest.colorize(mcl_colors.YELLOW, S("(Temporary)")) + minetest.override_item(name, {description = new_description}) + end +end) diff --git a/mods/MISC/mcl_wip/mod.conf b/mods/MISC/mcl_wip/mod.conf index 2af1d4592..e705379a1 100644 --- a/mods/MISC/mcl_wip/mod.conf +++ b/mods/MISC/mcl_wip/mod.conf @@ -1 +1,4 @@ name = mcl_wip +author = Wuzzy +description = Development mod for MineClone 2 which add a “WIP” (Work In Progress) comment to items which are considered to be very unfinished. +depends = mcl_colors diff --git a/mods/PLAYER/mcl_death_drop/depends.txt b/mods/PLAYER/mcl_death_drop/depends.txt deleted file mode 100644 index 4c2d1c21f..000000000 --- a/mods/PLAYER/mcl_death_drop/depends.txt +++ /dev/null @@ -1,2 +0,0 @@ -mcl_armor -mcl_enchanting diff --git a/mods/PLAYER/mcl_death_drop/description.txt b/mods/PLAYER/mcl_death_drop/description.txt deleted file mode 100644 index 761832f6e..000000000 --- a/mods/PLAYER/mcl_death_drop/description.txt +++ /dev/null @@ -1 +0,0 @@ -Makes all items in inventory drop after player death. diff --git a/mods/PLAYER/mcl_death_drop/mod.conf b/mods/PLAYER/mcl_death_drop/mod.conf index 93ed70ad4..09a8c61fa 100644 --- a/mods/PLAYER/mcl_death_drop/mod.conf +++ b/mods/PLAYER/mcl_death_drop/mod.conf @@ -1 +1,4 @@ name = mcl_death_drop +author = Wuzzy +description = Makes all items in inventory drop after player death. +depends = mcl_armor, mcl_enchanting diff --git a/mods/PLAYER/mcl_hunger/depends.txt b/mods/PLAYER/mcl_hunger/depends.txt deleted file mode 100644 index ed8cc4236..000000000 --- a/mods/PLAYER/mcl_hunger/depends.txt +++ /dev/null @@ -1,2 +0,0 @@ -hudbars -mcl_death_messages? diff --git a/mods/PLAYER/mcl_hunger/description.txt b/mods/PLAYER/mcl_hunger/description.txt deleted file mode 100644 index 77e6159d5..000000000 --- a/mods/PLAYER/mcl_hunger/description.txt +++ /dev/null @@ -1 +0,0 @@ -Adds a simple hunger meachanic with satiation, food poisoning and different healing. 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_hunger/mod.conf b/mods/PLAYER/mcl_hunger/mod.conf index a1a3d1cc2..7795da7a2 100644 --- a/mods/PLAYER/mcl_hunger/mod.conf +++ b/mods/PLAYER/mcl_hunger/mod.conf @@ -1 +1,5 @@ name = mcl_hunger +author = BlockMen +description = Adds a simple hunger meachanic with satiation, food poisoning and different healing. +depends = hudbars +optional_depends = mcl_death_messages diff --git a/mods/PLAYER/mcl_meshhand/depends.txt b/mods/PLAYER/mcl_meshhand/depends.txt deleted file mode 100644 index c86b5f93b..000000000 --- a/mods/PLAYER/mcl_meshhand/depends.txt +++ /dev/null @@ -1,2 +0,0 @@ -mcl_tools -mcl_skins? diff --git a/mods/PLAYER/mcl_meshhand/description.txt b/mods/PLAYER/mcl_meshhand/description.txt deleted file mode 100644 index 7a4daae59..000000000 --- a/mods/PLAYER/mcl_meshhand/description.txt +++ /dev/null @@ -1 +0,0 @@ -Applies the player skin texture to the hand. diff --git a/mods/PLAYER/mcl_meshhand/init.lua b/mods/PLAYER/mcl_meshhand/init.lua index 18eda9ec6..cdd5da946 100644 --- a/mods/PLAYER/mcl_meshhand/init.lua +++ b/mods/PLAYER/mcl_meshhand/init.lua @@ -35,13 +35,41 @@ for _,texture in pairs(list) do groups = { dig_immediate = 3, not_in_creative_inventory = 1 }, range = def.range, }) + + minetest.register_node("mcl_meshhand:"..texture.. "_female", { + description = "", + tiles = {texture..".png"}, + use_texture_alpha = minetest.features.use_texture_alpha_string_modes and "opaque" or false, + visual_scale = 1, + wield_scale = {x=1,y=1,z=1}, + paramtype = "light", + drawtype = "mesh", + mesh = "mcl_meshhand_female.b3d", + -- Prevent construction + node_placement_prediction = "", + on_construct = function(pos) + minetest.log("error", "[mcl_meshhand] Trying to construct mcl_meshhand:"..texture.." at "..minetest.pos_to_string(pos)) + minetest.remove_node(pos) + end, + drop = "", + on_drop = function() + return "" + end, + groups = { dig_immediate = 3, not_in_creative_inventory = 1 }, + range = def.range, + }) end if has_mcl_skins == true then --change the player's hand to their skin mcl_skins.register_on_set_skin(function(player, skin) local name = player:get_player_name() - player:get_inventory():set_stack("hand", 1, "mcl_meshhand:"..skin) + local meta = mcl_skins.meta[skin] + if meta.gender == "female" then + player:get_inventory():set_stack("hand", 1, "mcl_meshhand:"..skin.."_female") + else + player:get_inventory():set_stack("hand", 1, "mcl_meshhand:"..skin) + end end) else minetest.register_on_joinplayer(function(player) diff --git a/mods/PLAYER/mcl_meshhand/mod.conf b/mods/PLAYER/mcl_meshhand/mod.conf index 6b57f4a49..6a988417f 100644 --- a/mods/PLAYER/mcl_meshhand/mod.conf +++ b/mods/PLAYER/mcl_meshhand/mod.conf @@ -1 +1,6 @@ name = mcl_meshhand +author = jordan4ibanez +description = Applies the player skin texture to the hand. +depends = mcl_tools +optional_depends = mcl_skins + diff --git a/mods/PLAYER/mcl_meshhand/models/mcl_meshhand_female.b3d b/mods/PLAYER/mcl_meshhand/models/mcl_meshhand_female.b3d new file mode 100644 index 000000000..b2ec6efcf Binary files /dev/null and b/mods/PLAYER/mcl_meshhand/models/mcl_meshhand_female.b3d differ diff --git a/mods/PLAYER/mcl_meshhand/models/mcl_meshhand_female.blend b/mods/PLAYER/mcl_meshhand/models/mcl_meshhand_female.blend new file mode 100644 index 000000000..be642496f Binary files /dev/null and b/mods/PLAYER/mcl_meshhand/models/mcl_meshhand_female.blend differ diff --git a/mods/PLAYER/mcl_player/init.lua b/mods/PLAYER/mcl_player/init.lua index e39e8f956..2a9e77055 100644 --- a/mods/PLAYER/mcl_player/init.lua +++ b/mods/PLAYER/mcl_player/init.lua @@ -6,6 +6,20 @@ mcl_player = {} -- Note: This is currently broken due to a bug in Irrlicht, leave at 0 local animation_blend = 0 +local function get_mouse_button(player) + local controls = player:get_player_control() + local get_wielded_item_name = player:get_wielded_item():get_name() + if controls.RMB + and not string.find(player:get_wielded_item():get_name(), "mcl_bows:bow") + and not string.find(player:get_wielded_item():get_name(), "mcl_bows:crossbow") + and not string.find(player:get_wielded_item():get_name(), "mcl_bows:loaded_crossbow") + or controls.LMB then + return true + else + return false + end +end + mcl_player.registered_player_models = { } -- Local for speed. @@ -33,6 +47,7 @@ mcl_player.player_register_model("character.b3d", { sneak_walk_mine = {x=325, y=344}, run_walk = {x=440, y=460}, run_walk_mine = {x=461, y=481}, + sit_mount = {x=484, y=484}, }, }) @@ -137,7 +152,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] @@ -156,45 +171,49 @@ minetest.register_globalstep(function(dtime) animation_speed_mod = animation_speed_mod / 2 end - -- ask if player is in a place which he should crawl - local node_in_feet = minetest.registered_nodes[mcl_playerinfo[name].node_feet] + + -- ask if player is swiming - local standing_on_water = minetest.get_item_group(mcl_playerinfo[name].node_feet, "water") ~= 0 + local head_in_water = minetest.get_item_group(mcl_playerinfo[name].node_head, "water") ~= 0 -- ask if player is sprinting local is_sprinting = mcl_sprint.is_sprinting(name) + local velocity = player:get_velocity() or player:get_player_velocity() + -- Apply animations based on what the player is doing if player:get_hp() == 0 then player_set_animation(player, "lay") - elseif walking then + 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 player_sneak[name] = controls.sneak end - if controls.LMB and not controls.sneak and standing_on_water and is_sprinting == true then + if get_mouse_button(player) == true and not controls.sneak and head_in_water and is_sprinting == true then player_set_animation(player, "swim_walk_mine", animation_speed_mod) - elseif not controls.sneak and standing_on_water and is_sprinting == true then + elseif not controls.sneak and head_in_water and is_sprinting == true then player_set_animation(player, "swim_walk", animation_speed_mod) - elseif is_sprinting == true and controls.LMB and not controls.sneak and not standing_on_water then + elseif is_sprinting == true and get_mouse_button(player) == true and not controls.sneak and not head_in_water then player_set_animation(player, "run_walk_mine", animation_speed_mod) - elseif controls.LMB and not controls.sneak then + elseif get_mouse_button(player) == true and not controls.sneak then player_set_animation(player, "walk_mine", animation_speed_mod) - elseif controls.LMB and controls.sneak and is_sprinting ~= true then + elseif get_mouse_button(player) == true and controls.sneak and is_sprinting ~= true then player_set_animation(player, "sneak_walk_mine", animation_speed_mod) - elseif is_sprinting == true and not controls.sneak and not standing_on_water then + elseif is_sprinting == true and not controls.sneak and not head_in_water then player_set_animation(player, "run_walk", animation_speed_mod) - elseif controls.sneak and not controls.LMB then + elseif controls.sneak and not get_mouse_button(player) == true then player_set_animation(player, "sneak_walk", animation_speed_mod) else player_set_animation(player, "walk", animation_speed_mod) end - elseif controls.LMB and not controls.sneak and standing_on_water and is_sprinting == true then + elseif get_mouse_button(player) == true and not controls.sneak and head_in_water and is_sprinting == true then player_set_animation(player, "swim_mine") - elseif controls.LMB and not controls.sneak then + elseif not get_mouse_button(player) == true and not controls.sneak and head_in_water and is_sprinting == true then + player_set_animation(player, "swim_stand") + elseif get_mouse_button(player) == true and not controls.sneak then player_set_animation(player, "mine") - elseif controls.LMB and controls.sneak then + elseif get_mouse_button(player) == true and controls.sneak then player_set_animation(player, "sneak_mine") - elseif not controls.sneak and standing_on_water and is_sprinting == true then + elseif not controls.sneak and head_in_water and is_sprinting == true then player_set_animation(player, "swim_stand", animation_speed_mod) elseif not controls.sneak then player_set_animation(player, "stand", animation_speed_mod) diff --git a/mods/PLAYER/mcl_player/mod.conf b/mods/PLAYER/mcl_player/mod.conf new file mode 100644 index 000000000..97ccce8e6 --- /dev/null +++ b/mods/PLAYER/mcl_player/mod.conf @@ -0,0 +1,3 @@ +name = mcl_player +author = celeron55 +description = Adds the 3D player model, taken from Minetest Game 0.4.16. diff --git a/mods/PLAYER/mcl_player_init/mod.conf b/mods/PLAYER/mcl_player_init/mod.conf index 8d559910c..d7a86c438 100644 --- a/mods/PLAYER/mcl_player_init/mod.conf +++ b/mods/PLAYER/mcl_player_init/mod.conf @@ -1,2 +1,3 @@ name = mcl_player_init +author = Wuzzy description = Initialize player gameplay stuff that are neither model nor HUD-related diff --git a/mods/PLAYER/mcl_playerinfo/depends.txt b/mods/PLAYER/mcl_playerinfo/depends.txt deleted file mode 100644 index d0334ff54..000000000 --- a/mods/PLAYER/mcl_playerinfo/depends.txt +++ /dev/null @@ -1,4 +0,0 @@ -mcl_init -mcl_core -mcl_particles -mcl_death_messages 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_playerinfo/mod.conf b/mods/PLAYER/mcl_playerinfo/mod.conf index ee2b80e7e..9f2b0c4a5 100644 --- a/mods/PLAYER/mcl_playerinfo/mod.conf +++ b/mods/PLAYER/mcl_playerinfo/mod.conf @@ -1 +1,4 @@ name = mcl_playerinfo +author = TenPlus1 +description = This is a helper mod for other mod to query the nodes around the player. +depends = mcl_init, mcl_core, mcl_particles, mcl_death_messages diff --git a/mods/PLAYER/mcl_playerplus/depends.txt b/mods/PLAYER/mcl_playerplus/depends.txt deleted file mode 100644 index 7a259f8c1..000000000 --- a/mods/PLAYER/mcl_playerplus/depends.txt +++ /dev/null @@ -1,10 +0,0 @@ -mcl_init -mcl_core -mcl_particles -mcl_hunger -mcl_death_messages -playerphysics -mcl_playerinfo -mcl_weather -mcl_spawn -mcl_enchanting diff --git a/mods/PLAYER/mcl_playerplus/description.txt b/mods/PLAYER/mcl_playerplus/description.txt deleted file mode 100644 index 4664d5f8c..000000000 --- a/mods/PLAYER/mcl_playerplus/description.txt +++ /dev/null @@ -1 +0,0 @@ -Adds some simple player-related gameplay effects: Hurt by touching a cactus, suffocation and more. diff --git a/mods/PLAYER/mcl_playerplus/init.lua b/mods/PLAYER/mcl_playerplus/init.lua index 6bc9b86fb..710a6ad95 100644 --- a/mods/PLAYER/mcl_playerplus/init.lua +++ b/mods/PLAYER/mcl_playerplus/init.lua @@ -1,5 +1,21 @@ local S = minetest.get_translator("mcl_playerplus") +local get_connected_players = minetest.get_connected_players +local dir_to_yaw = minetest.dir_to_yaw +local get_item_group = minetest.get_item_group +local check_player_privs = minetest.check_player_privs +local find_node_near = minetest.find_node_near +local get_name_from_content_id = minetest.get_name_from_content_id +local get_voxel_manip = minetest.get_voxel_manip +local add_particle = minetest.add_particle +local add_particlespawner = minetest.add_particlespawner + +local is_sprinting = mcl_sprint.is_sprinting +local exhaust = mcl_hunger.exhaust +local playerphysics = playerphysics + +local vector = vector +local math = math -- Internal player state local mcl_playerplus_internal = {} @@ -25,21 +41,22 @@ 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(minetest.get_connected_players()) do + for _,player in pairs(get_connected_players()) do local controls = player:get_player_control() name = player:get_player_name() - local player_velocity = player:get_player_velocity() + local player_velocity = player:get_velocity() or player:get_player_velocity() -- controls head bone local pitch = degrees(player:get_look_vertical()) * -1 local yaw = degrees(player:get_look_horizontal()) * -1 - if degrees(minetest.dir_to_yaw(player_velocity)) == 0 then - player_vel_yaw = 0 + local player_vel_yaw = 0 + + if degrees(dir_to_yaw(player_velocity)) == 0 then yaw = 0 else - player_vel_yaw = degrees(minetest.dir_to_yaw(player_velocity)) + player_vel_yaw = degrees(dir_to_yaw(player_velocity)) end if string.find(player:get_wielded_item():get_name(), "mcl_bows:crossbow") and controls.RMB then @@ -58,7 +75,7 @@ minetest.register_globalstep(function(dtime) elseif string.find(player:get_wielded_item():get_name(), "mcl_bows:loaded_crossbow") and not controls.LMB and not controls.up and not controls.down and not controls.left and not controls.right and not minetest.get_item_group(mcl_playerinfo[name].node_stand, "water") ~= 0 then player:set_bone_position("Arm_Right_Pitch_Control", vector.new(-3,5.785,0), vector.new(pitch+90,-15,pitch * -1 * .35)) player:set_bone_position("Arm_Left_Pitch_Control", vector.new(3.5,5.785,0), vector.new(pitch+90,55,pitch * .35)) - elseif controls.LMB then + 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)) else @@ -71,21 +88,42 @@ minetest.register_globalstep(function(dtime) player:set_bone_position("Head", vector.new(0,6.3,0), vector.new(pitch+36,0,0)) -- 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.35, nametag_color = { r = 225, b = 225, a = 0, g = 225 }}) - + -- sneaking body conrols 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)) + -- 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)) elseif minetest.get_item_group(mcl_playerinfo[name].node_feet, "water") ~= 0 and player:get_attach() == nil and mcl_sprint.is_sprinting(name) == true then -- controls head pitch when swiming 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)) - -- 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.65, nametag_color = { r = 225, b = 225, a = 225, g = 225 }}) - 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)) - else - -- controls head pitch when not sneaking + 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.65, nametag_color = { r = 225, b = 225, a = 225, g = 225 }}) - 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)) + 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 + 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("Body_Control", vector.new(0,6.3,0), vector.new(0,0,0)) end if mcl_playerplus_internal[name].jump_cooldown > 0 then @@ -119,18 +157,18 @@ minetest.register_globalstep(function(dtime) as of 0.4.15. ]] - if minetest.get_item_group(node_feet, "liquid") == 0 and - minetest.get_item_group(node_stand, "liquid") == 0 and + if get_item_group(node_feet, "liquid") == 0 and + get_item_group(node_stand, "liquid") == 0 and not minetest.registered_nodes[node_feet].climbable and not minetest.registered_nodes[node_stand].climbable and (minetest.registered_nodes[node_stand].walkable or minetest.registered_nodes[node_stand_below].walkable) - and minetest.get_item_group(node_stand, "disable_jump") == 0 - and minetest.get_item_group(node_stand_below, "disable_jump") == 0 then + and get_item_group(node_stand, "disable_jump") == 0 + and get_item_group(node_stand_below, "disable_jump") == 0 then -- Cause exhaustion for jumping - if mcl_sprint.is_sprinting(name) then - mcl_hunger.exhaust(name, mcl_hunger.EXHAUST_SPRINT_JUMP) + if is_sprinting(name) then + exhaust(name, mcl_hunger.EXHAUST_SPRINT_JUMP) else - mcl_hunger.exhaust(name, mcl_hunger.EXHAUST_JUMP) + exhaust(name, mcl_hunger.EXHAUST_JUMP) end -- Reset cooldown timer @@ -149,7 +187,7 @@ minetest.register_globalstep(function(dtime) time = 0 -- check players - for _,player in ipairs(minetest.get_connected_players()) do + for _,player in pairs(get_connected_players()) do -- who am I? local name = player:get_player_name() @@ -189,6 +227,18 @@ minetest.register_globalstep(function(dtime) 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 + local boots = player:get_inventory():get_stack("armor", 5) + local depth_strider = mcl_enchanting.get_enchantment(boots, "depth_strider") + + if depth_strider > 0 then + playerphysics.add_physics_factor(player, "speed", "mcl_playerplus:surface", (depth_strider / 3) + 0.75) + end + else + playerphysics.remove_physics_factor(player, "speed", "mcl_playerplus:surface") + end + -- Is player suffocating inside node? (Only for solid full opaque cube type nodes -- without group disable_suffocation=1) local ndef = minetest.registered_nodes[node_head] @@ -200,7 +250,7 @@ minetest.register_globalstep(function(dtime) and (ndef.groups.opaque == 1) and (node_head ~= "ignore") -- Check privilege, too - and (not minetest.check_player_privs(name, {noclip = true})) then + and (not check_player_privs(name, {noclip = true})) then if player:get_hp() > 0 then mcl_death_messages.player_damage(player, S("@1 suffocated to death.", name)) player:set_hp(player:get_hp() - 1) @@ -208,9 +258,9 @@ minetest.register_globalstep(function(dtime) end -- Am I near a cactus? - local near = minetest.find_node_near(pos, 1, "mcl_core:cactus") + local near = find_node_near(pos, 1, "mcl_core:cactus") if not near then - near = minetest.find_node_near({x=pos.x, y=pos.y-1, z=pos.z}, 1, "mcl_core:cactus") + near = find_node_near({x=pos.x, y=pos.y-1, z=pos.z}, 1, "mcl_core:cactus") end if near then -- Am I touching the cactus? If so, it hurts @@ -227,15 +277,15 @@ minetest.register_globalstep(function(dtime) --[[ Swimming: Cause exhaustion. NOTE: As of 0.4.15, it only counts as swimming when you are with the feet inside the liquid! Head alone does not count. We respect that for now. ]] - if minetest.get_item_group(node_feet, "liquid") ~= 0 or - minetest.get_item_group(node_stand, "liquid") ~= 0 then + if not player:get_attach() and (get_item_group(node_feet, "liquid") ~= 0 or + get_item_group(node_stand, "liquid") ~= 0) then local lastPos = mcl_playerplus_internal[name].lastPos if lastPos then local dist = vector.distance(lastPos, pos) mcl_playerplus_internal[name].swimDistance = mcl_playerplus_internal[name].swimDistance + dist if mcl_playerplus_internal[name].swimDistance >= 1 then local superficial = math.floor(mcl_playerplus_internal[name].swimDistance) - mcl_hunger.exhaust(name, mcl_hunger.EXHAUST_SWIM * superficial) + exhaust(name, mcl_hunger.EXHAUST_SWIM * superficial) mcl_playerplus_internal[name].swimDistance = mcl_playerplus_internal[name].swimDistance - superficial end end @@ -243,9 +293,8 @@ minetest.register_globalstep(function(dtime) end -- Underwater: Spawn bubble particles - if minetest.get_item_group(node_head, "water") ~= 0 then - - minetest.add_particlespawner({ + if get_item_group(node_head, "water") ~= 0 then + add_particlespawner({ amount = 10, time = 0.15, minpos = { x = -0.25, y = 0.3, z = -0.25 }, @@ -268,7 +317,7 @@ minetest.register_globalstep(function(dtime) if wi == "mcl_core:barrier" or wi == "mcl_core:realm_barrier" then local pos = vector.round(player:get_pos()) local r = 8 - local vm = minetest.get_voxel_manip() + local vm = get_voxel_manip() local emin, emax = vm:read_from_map({x=pos.x-r, y=pos.y-r, z=pos.z-r}, {x=pos.x+r, y=pos.y+r, z=pos.z+r}) local area = VoxelArea:new{ MinEdge = emin, @@ -279,7 +328,7 @@ minetest.register_globalstep(function(dtime) for y=pos.y-r, pos.y+r do for z=pos.z-r, pos.z+r do local vi = area:indexp({x=x, y=y, z=z}) - local nodename = minetest.get_name_from_content_id(data[vi]) + local nodename = get_name_from_content_id(data[vi]) local tex if nodename == "mcl_core:barrier" then tex = "mcl_core_barrier.png" @@ -287,7 +336,7 @@ minetest.register_globalstep(function(dtime) tex = "mcl_core_barrier.png^[colorize:#FF00FF:127^[transformFX" end if tex then - minetest.add_particle({ + add_particle({ pos = {x=x, y=y, z=z}, expirationtime = 1, size = 8, diff --git a/mods/PLAYER/mcl_playerplus/mod.conf b/mods/PLAYER/mcl_playerplus/mod.conf index 660def45e..95121f8ea 100644 --- a/mods/PLAYER/mcl_playerplus/mod.conf +++ b/mods/PLAYER/mcl_playerplus/mod.conf @@ -1 +1,5 @@ name = mcl_playerplus +author = TenPlus1 +description = Adds some simple player-related gameplay effects: Hurt by touching a cactus, suffocation and more. +depends = mcl_init, mcl_core, mcl_particles, mcl_hunger, mcl_death_messages, playerphysics, mcl_playerinfo, mcl_weather, mcl_spawn, mcl_enchanting + diff --git a/mods/PLAYER/mcl_skins/depends.txt b/mods/PLAYER/mcl_skins/depends.txt deleted file mode 100644 index 09bdf5205..000000000 --- a/mods/PLAYER/mcl_skins/depends.txt +++ /dev/null @@ -1,4 +0,0 @@ -mcl_player -mcl_inventory? -intllib? -mcl_armor? diff --git a/mods/PLAYER/mcl_skins/description.txt b/mods/PLAYER/mcl_skins/description.txt deleted file mode 100644 index 61c7bff64..000000000 --- a/mods/PLAYER/mcl_skins/description.txt +++ /dev/null @@ -1 +0,0 @@ -Mod that allows players to set their individual skins. \ No newline at end of file diff --git a/mods/PLAYER/mcl_skins/init.lua b/mods/PLAYER/mcl_skins/init.lua index 0bff9cb18..ac770f8f5 100644 --- a/mods/PLAYER/mcl_skins/init.lua +++ b/mods/PLAYER/mcl_skins/init.lua @@ -62,6 +62,7 @@ while true do mcl_skins.meta[skin] = { name = data and data.name or "", author = data and data.author or "", + gender = data and data.gender or "", } if id > 0 then @@ -93,8 +94,15 @@ mcl_skins.set_player_skin = function(player, skin_id) elseif skin_id == 0 then skin = "character" preview = "player" + mcl_player.player_set_model(player, "mcl_armor_character.b3d") else skin = "mcl_skins_character_" .. tostring(skin_id) + local meta = mcl_skins.meta[skin] + if meta.gender == "female" then + mcl_player.player_set_model(player, "mcl_armor_character_female.b3d") + else + mcl_player.player_set_model(player, "mcl_armor_character.b3d") + end if mcl_skins.has_preview[skin_id] then preview = "mcl_skins_player_" .. tostring(skin_id) else diff --git a/mods/PLAYER/mcl_skins/meta/mcl_skins_character.txt b/mods/PLAYER/mcl_skins/meta/mcl_skins_character.txt index 00061a654..c31bd7168 100644 --- a/mods/PLAYER/mcl_skins/meta/mcl_skins_character.txt +++ b/mods/PLAYER/mcl_skins/meta/mcl_skins_character.txt @@ -1,2 +1,3 @@ name = "Steve", author = "%TEXTURE_PACK_AUTHOR%", +gender = "male", diff --git a/mods/PLAYER/mcl_skins/meta/mcl_skins_character_1.txt b/mods/PLAYER/mcl_skins/meta/mcl_skins_character_1.txt index f96b13f68..e6c90dc0f 100644 --- a/mods/PLAYER/mcl_skins/meta/mcl_skins_character_1.txt +++ b/mods/PLAYER/mcl_skins/meta/mcl_skins_character_1.txt @@ -1,2 +1,3 @@ name = "Alex", author = "%TEXTURE_PACK_AUTHOR%", +gender = "female", diff --git a/mods/PLAYER/mcl_skins/mod.conf b/mods/PLAYER/mcl_skins/mod.conf index 96f827646..6ccbe98f1 100644 --- a/mods/PLAYER/mcl_skins/mod.conf +++ b/mods/PLAYER/mcl_skins/mod.conf @@ -1 +1,5 @@ name = mcl_skins +author = TenPlus1 +description = Mod that allows players to set their individual skins. +depends = mcl_player +optional_depends = mcl_inventory, intllib, mcl_armor diff --git a/mods/PLAYER/mcl_spawn/depends.txt b/mods/PLAYER/mcl_spawn/depends.txt deleted file mode 100644 index 3b355984e..000000000 --- a/mods/PLAYER/mcl_spawn/depends.txt +++ /dev/null @@ -1 +0,0 @@ -mcl_init diff --git a/mods/PLAYER/mcl_spawn/description.txt b/mods/PLAYER/mcl_spawn/description.txt deleted file mode 100644 index 6712e4432..000000000 --- a/mods/PLAYER/mcl_spawn/description.txt +++ /dev/null @@ -1 +0,0 @@ -Set and get the player's respawn position diff --git a/mods/PLAYER/mcl_spawn/init.lua b/mods/PLAYER/mcl_spawn/init.lua index 5a4f3d634..6a3d543d3 100644 --- a/mods/PLAYER/mcl_spawn/init.lua +++ b/mods/PLAYER/mcl_spawn/init.lua @@ -386,6 +386,10 @@ end mcl_spawn.get_world_spawn_pos = function() + local ssp = minetest.setting_get_pos("static_spawnpoint") + if ssp then + return ssp + end if success then return wsp end diff --git a/mods/PLAYER/mcl_spawn/mod.conf b/mods/PLAYER/mcl_spawn/mod.conf index ff54191b2..954f831db 100644 --- a/mods/PLAYER/mcl_spawn/mod.conf +++ b/mods/PLAYER/mcl_spawn/mod.conf @@ -1 +1,4 @@ name = mcl_spawn +author = Wuzzy +description = Set and get the player's respawn position +depends = mcl_init diff --git a/mods/PLAYER/mcl_sprint/depends.txt b/mods/PLAYER/mcl_sprint/depends.txt deleted file mode 100644 index aa6711ef0..000000000 --- a/mods/PLAYER/mcl_sprint/depends.txt +++ /dev/null @@ -1,3 +0,0 @@ -mcl_playerinfo -playerphysics -mcl_hunger diff --git a/mods/PLAYER/mcl_sprint/init.lua b/mods/PLAYER/mcl_sprint/init.lua index 9e7690f4b..9dc678000 100644 --- a/mods/PLAYER/mcl_sprint/init.lua +++ b/mods/PLAYER/mcl_sprint/init.lua @@ -31,9 +31,11 @@ minetest.register_on_joinplayer(function(player) sprinting = false, timeOut = 0, shouldSprint = false, + clientSprint = false, lastPos = player:get_pos(), sprintDistance = 0, - fov = 1.0 + fov = 1.0, + channel = minetest.mod_channel_join("mcl_sprint:" .. playerName), } end) minetest.register_on_leaveplayer(function(player) @@ -41,18 +43,34 @@ minetest.register_on_leaveplayer(function(player) players[playerName] = nil end) +local function cancelClientSprinting(name) + players[name].channel:send_all("") + players[name].clientSprint = false +end + local function setSprinting(playerName, sprinting) --Sets the state of a player (0=stopped/moving, 1=sprinting) local player = minetest.get_player_by_name(playerName) + local controls = player:get_player_control() if players[playerName] then players[playerName].sprinting = sprinting - if sprinting == true then - players[playerName].fov = math.min(players[playerName].fov + 0.05, 1.2) - player:set_fov(players[playerName].fov, true, 0.15) - playerphysics.add_physics_factor(player, "speed", "mcl_sprint:sprint", mcl_sprint.SPEED) - elseif sprinting == false then + if sprinting == true or controls.RMB and string.find(player:get_wielded_item():get_name(), "mcl_bows:bow") and player:get_wielded_item():get_name() ~= "mcl_bows:bow" then + if sprinting == true then + players[playerName].fov = math.min(players[playerName].fov + 0.05, 1.2) + players[playerName].fade_time = .15 + else + players[playerName].fov = .7 + players[playerName].fade_time = .3 + end + player:set_fov(players[playerName].fov, true, players[playerName].fade_time) + if sprinting == true then + playerphysics.add_physics_factor(player, "speed", "mcl_sprint:sprint", mcl_sprint.SPEED) + end + elseif sprinting == false and player:get_wielded_item():get_name() ~= "mcl_bows:bow_0" and player:get_wielded_item():get_name() ~= "mcl_bows:bow_1" and player:get_wielded_item():get_name() ~= "mcl_bows:bow_2" then players[playerName].fov = math.max(players[playerName].fov - 0.05, 1.0) player:set_fov(players[playerName].fov, true, 0.15) - playerphysics.remove_physics_factor(player, "speed", "mcl_sprint:sprint") + if sprinting == false then + playerphysics.remove_physics_factor(player, "speed", "mcl_sprint:sprint") + end end return true end @@ -97,6 +115,16 @@ local function get_top_node_tile(param2, paramtype2) end end +minetest.register_on_modchannel_message(function(channel_name, sender, message) + if channel_name == "mcl_sprint:" .. sender then + players[sender].clientSprint = minetest.is_yes(message) + end +end) + +minetest.register_on_respawnplayer(function(player) + cancelClientSprinting(player:get_player_name()) +end) + minetest.register_globalstep(function(dtime) --Get the gametime local gameTime = minetest.get_gametime() @@ -107,7 +135,7 @@ minetest.register_globalstep(function(dtime) if player ~= nil then local ctrl = player:get_player_control() --Check if the player should be sprinting - if ctrl.aux1 and ctrl.up and not ctrl.sneak then + if players[playerName]["clientSprint"] or ctrl.aux1 and ctrl.up and not ctrl.sneak then players[playerName]["shouldSprint"] = true else players[playerName]["shouldSprint"] = false @@ -115,7 +143,7 @@ minetest.register_globalstep(function(dtime) local playerPos = player:get_pos() --If the player is sprinting, create particles behind and cause exhaustion - if playerInfo["sprinting"] == true and gameTime % 0.1 == 0 then + if playerInfo["sprinting"] == true and not player:get_attach() and gameTime % 0.1 == 0 then -- Exhaust player for sprinting local lastPos = players[playerName].lastPos @@ -158,8 +186,9 @@ minetest.register_globalstep(function(dtime) if players[playerName]["shouldSprint"] == true then --Stopped local sprinting -- Prevent sprinting if hungry or sleeping - if (mcl_hunger.active and mcl_hunger.get_hunger(player) <= 6) or (player:get_meta():get_string("mcl_beds:sleeping") == "true")then + if (mcl_hunger.active and mcl_hunger.get_hunger(player) <= 6) or (player:get_meta():get_string("mcl_beds:sleeping") == "true") then sprinting = false + cancelClientSprinting(playerName) else sprinting = true end diff --git a/mods/PLAYER/mcl_sprint/mod.conf b/mods/PLAYER/mcl_sprint/mod.conf index 7a3692459..0d20f80a3 100644 --- a/mods/PLAYER/mcl_sprint/mod.conf +++ b/mods/PLAYER/mcl_sprint/mod.conf @@ -1 +1,4 @@ name = mcl_sprint +author = GunshipPenguin +description = Allows the player to sprint by pressing the “Use” key (default: E). +depends = mcl_playerinfo, playerphysics, mcl_hunger diff --git a/mods/PLAYER/playerphysics/description.txt b/mods/PLAYER/playerphysics/description.txt deleted file mode 100644 index c692c5cdb..000000000 --- a/mods/PLAYER/playerphysics/description.txt +++ /dev/null @@ -1 +0,0 @@ -This mod makes it possible for multiple mods to modify player physics (speed, jumping strength, gravity) without conflict. diff --git a/mods/PLAYER/playerphysics/mod.conf b/mods/PLAYER/playerphysics/mod.conf index da01bf07e..1c2f2fa07 100644 --- a/mods/PLAYER/playerphysics/mod.conf +++ b/mods/PLAYER/playerphysics/mod.conf @@ -1 +1,3 @@ name = playerphysics +author = Wuzzy +description = This mod makes it possible for multiple mods to modify player physics (speed, jumping strength, gravity) without conflict. diff --git a/mods/PLAYER/wieldview/depends.txt b/mods/PLAYER/wieldview/depends.txt deleted file mode 100644 index 2bbf820fd..000000000 --- a/mods/PLAYER/wieldview/depends.txt +++ /dev/null @@ -1 +0,0 @@ -mcl_armor diff --git a/mods/PLAYER/wieldview/description.txt b/mods/PLAYER/wieldview/description.txt deleted file mode 100644 index 0d51ad954..000000000 --- a/mods/PLAYER/wieldview/description.txt +++ /dev/null @@ -1 +0,0 @@ -Makes hand wielded items visible to other players. diff --git a/mods/PLAYER/wieldview/init.lua b/mods/PLAYER/wieldview/init.lua index dab577fa8..dea44b2a2 100644 --- a/mods/PLAYER/wieldview/init.lua +++ b/mods/PLAYER/wieldview/init.lua @@ -71,12 +71,53 @@ minetest.register_on_joinplayer(function(player) wieldview.wielded_item[name] = "" 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: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) +minetest.register_entity("wieldview:wieldnode", { + initial_properties = { + hp_max = 1, + visual = "wielditem", + physical = false, + textures = {""}, + automatic_rotate = 1.5, + is_visible = true, + pointable = false, + collide_with_objects = false, + static_save = false, + collisionbox = {-0.21, -0.21, -0.21, 0.21, 0.21, 0.21}, + selectionbox = {-0.21, -0.21, -0.21, 0.21, 0.21, 0.21}, + visual_size = {x = 0.21, y = 0.21}, + }, + + itemstring = "", + + on_step = function(self) + local player = minetest.get_player_by_name(self.wielder) + 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}) + if armor.textures[self.wielder].wielditem == "blank.png" then + self.object:set_properties({textures = {itemstring}}) + else + self.object:set_properties({textures = {""}}) + end + self.itemstring = itemstring + end + else + self.object:remove() + end + end, +}) diff --git a/mods/PLAYER/wieldview/mod.conf b/mods/PLAYER/wieldview/mod.conf new file mode 100644 index 000000000..4cd2a6935 --- /dev/null +++ b/mods/PLAYER/wieldview/mod.conf @@ -0,0 +1,5 @@ +name = wieldview +author = stujones11 +description = Makes hand wielded items visible to other players. +depends = mcl_armor + diff --git a/mods/PLAYER/wieldview/transform.lua b/mods/PLAYER/wieldview/transform.lua index 0b0145c7f..854f608ab 100644 --- a/mods/PLAYER/wieldview/transform.lua +++ b/mods/PLAYER/wieldview/transform.lua @@ -22,11 +22,6 @@ wieldview.transform = { ["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", diff --git a/settingtypes.txt b/settingtypes.txt index 264757db8..af0e18d85 100644 --- a/settingtypes.txt +++ b/settingtypes.txt @@ -95,7 +95,7 @@ fire_animation_frames (Fire Animation Frames) int 8 animated_chests (Animated chests) bool true # Whether to preview the player in inventory in 3D (requires Minetest 5.4) -3d_player_preview (3D Player preview) bool false +3d_player_preview (3D Player preview) bool true [Experimental] # Whether ice is translucent. If disabled, ice is fully opaque. @@ -126,6 +126,9 @@ mcl_generate_fallen_logs (Generate fallen logs) bool false # But creating new flat worlds after changing this setting should be safe. mcl_superflat_classic (Classic superflat map generation) bool false +# If disabled, no ores will be generated. +mcl_generate_ores (Generate Ores) 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. @@ -133,6 +136,9 @@ mcl_superflat_classic (Classic superflat map generation) bool false # game by a lot. mcl_node_particles (Block particles detail level) enum none high,medium,low,none +# Enable hard overiding of builtin commands. +mcl_builtin_commands_overide (Enable hard overiding of builtin commands.) bool true + # If enabled, this will substitute a few blocks in village schematics so they blend into normal, snowy, and sandy areas. Defaults to true. basic_pseudobiome_villages (Enables very basic, and experimental "pseudobiome-based" villages) bool true