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/minetest.conf b/minetest.conf index 3e80f10f3..7e1ca9cd8 100644 --- a/minetest.conf +++ b/minetest.conf @@ -33,8 +33,7 @@ mgvalleys_spflags = noaltitude_chill,noaltitude_dry,nohumid_rivers,vary_river_de keepInventory = false # Performance settings -dedicated_server_step = 0.01 -liquid_update = 0.25 +dedicated_server_step = 0.001 abm_interval = 0.25 max_objects_per_block = 4096 max_packets_per_iteration = 10096 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/mcl_explosions/init.lua b/mods/CORE/mcl_explosions/init.lua index 2ac6eb0c6..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 @@ -156,7 +166,7 @@ end -- 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)) @@ -207,7 +217,7 @@ local function trace_explode(pos, strength, raydirs, radius, info, puncher) br = max_blast_resistance end - local hash = minetest.hash_node_position(npos) + local hash = hash_node_position(npos) rpos_x = rpos_x + STEP_LENGTH * rdir_x rpos_y = rpos_y + STEP_LENGTH * rdir_y @@ -230,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 @@ -359,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 diff --git a/mods/ENTITIES/mcl_minecarts/init.lua b/mods/ENTITIES/mcl_minecarts/init.lua index 2fa626479..9c61fa5ed 100644 --- a/mods/ENTITIES/mcl_minecarts/init.lua +++ b/mods/ENTITIES/mcl_minecarts/init.lua @@ -12,14 +12,15 @@ local function detach_driver(self) if not self._driver then return end - if self._driver:is_player() then - mcl_player.player_attached[self._driver:get_player_name()] = nil - self._driver:set_detach() - self._driver:set_eye_offset({x=0, y=0, z=0},{x=0, y=0, z=0}) - mcl_player.player_set_animation(self._driver, "stand" , 30) - end + mcl_player.player_attached[self._driver] = nil + local player = minetest.get_player_by_name(self._driver) self._driver = nil self._start_pos = nil + if player then + player:set_detach() + player:set_eye_offset({x=0, y=0, z=0},{x=0, y=0, z=0}) + mcl_player.player_set_animation(player, "stand" , 30) + end end local function activate_tnt_minecart(self, timer) @@ -61,7 +62,7 @@ local function register_entity(entity_id, mesh, textures, drop, on_rightclick, o on_rightclick = on_rightclick, - _driver = nil, -- player (or mob) who sits in and controls the minecart (only for minecart!) + _driver = nil, -- player who sits in and controls the minecart (only for minecart!) _punched = false, -- used to re-send _velocity and position _velocity = {x=0, y=0, z=0}, -- only used on punch _start_pos = nil, -- Used to calculate distance for “On A Rail” achievement @@ -96,101 +97,111 @@ local function register_entity(entity_id, mesh, textures, drop, on_rightclick, o end function cart:on_punch(puncher, time_from_last_punch, tool_capabilities, direction) - -- Punch: Pick up minecart (unless TNT was ignited) - if self._boomtimer then return end - if self._driver then - detach_driver(self) - end local pos = self.object:get_pos() - - -- Disable detector rail - local rou_pos = vector.round(pos) - local node = minetest.get_node(rou_pos) - if node.name == "mcl_minecarts:detector_rail_on" then - local newnode = {name="mcl_minecarts:detector_rail", param2 = node.param2} - minetest.swap_node(rou_pos, newnode) - mesecon.receptor_off(rou_pos) + if not self._railtype then + local node = minetest.get_node(vector.floor(pos)).name + self._railtype = minetest.get_item_group(node, "connect_to_raillike") end - -- Drop items and remove cart entity - if not minetest.is_creative_enabled(puncher:get_player_name()) then - for d=1, #drop do - minetest.add_item(self.object:get_pos(), drop[d]) + if not puncher or not puncher:is_player() then + local cart_dir = mcl_minecarts:get_rail_direction(pos, {x=1, y=0, z=0}, nil, nil, self._railtype) + if vector.equals(cart_dir, {x=0, y=0, z=0}) then + return end - elseif puncher and puncher:is_player() then - local inv = puncher:get_inventory() - for d=1, #drop do - if not inv:contains_item("main", drop[d]) then - inv:add_item("main", drop[d]) + self._velocity = vector.multiply(cart_dir, 3) + self._old_pos = nil + self._punched = true + return + end + + -- Punch+sneak: Pick up minecart (unless TNT was ignited) + if puncher:get_player_control().sneak and not self._boomtimer then + if self._driver then + if self._old_pos then + self.object:set_pos(self._old_pos) + end + detach_driver(self) + end + + -- Disable detector rail + local rou_pos = vector.round(pos) + local node = minetest.get_node(rou_pos) + if node.name == "mcl_minecarts:detector_rail_on" then + local newnode = {name="mcl_minecarts:detector_rail", param2 = node.param2} + minetest.swap_node(rou_pos, newnode) + mesecon.receptor_off(rou_pos) + end + + -- Drop items and remove cart entity + if not minetest.is_creative_enabled(puncher:get_player_name()) then + for d=1, #drop do + minetest.add_item(self.object:get_pos(), drop[d]) + end + elseif puncher and puncher:is_player() then + local inv = puncher:get_inventory() + for d=1, #drop do + if not inv:contains_item("main", drop[d]) then + inv:add_item("main", drop[d]) + end end end + + self.object:remove() + return end - self.object:remove() + local vel = self.object:get_velocity() + if puncher:get_player_name() == self._driver then + if math.abs(vel.x + vel.z) > 7 then + return + end + end + + local punch_dir = mcl_minecarts:velocity_to_dir(puncher:get_look_dir()) + punch_dir.y = 0 + local cart_dir = mcl_minecarts:get_rail_direction(pos, punch_dir, nil, nil, self._railtype) + if vector.equals(cart_dir, {x=0, y=0, z=0}) then + return + end + + time_from_last_punch = math.min(time_from_last_punch, tool_capabilities.full_punch_interval) + local f = 3 * (time_from_last_punch / tool_capabilities.full_punch_interval) + + self._velocity = vector.multiply(cart_dir, f) + self._old_pos = nil + self._punched = true end cart.on_activate_by_rail = on_activate_by_rail function cart:on_step(dtime) local ctrl, player = nil, nil - local update = {} - local vel = self.object:get_velocity() - local pos, rou_pos, node - pos = self.object:get_pos() - rou_pos = vector.round(pos) - node = minetest.get_node(rou_pos) - local g = minetest.get_item_group(node.name, "connect_to_raillike") - if self._driver and self._driver:is_player() then - player = self._driver - ctrl = player:get_player_control() - -- player detach - if ctrl.sneak then - detach_driver(self) - return - end - if g == self._railtype then - if ctrl.right then - local c = vector.multiply(minetest.yaw_to_dir(self._driver:get_look_horizontal()-1.57), 0.2) - self.object:set_velocity(vector.add(vel, {x=c.x, y=0, z=c.z})) - end - if ctrl.left then - local c = vector.multiply(minetest.yaw_to_dir(self._driver:get_look_horizontal()+1.57), 0.2) - self.object:set_velocity(vector.add(vel, {x=c.x, y=0, z=c.z})) - end - if ctrl.up then - local c = vector.multiply(self._driver:get_look_dir(), 0.2) - self.object:set_velocity(vector.add(vel, {x=c.x, y=0, z=c.z})) - end - if ctrl.down then - local c = vector.multiply(self._driver:get_look_dir(), 0.2) - self.object:set_velocity(vector.subtract(vel, {x=c.x, y=0, z=c.z})) + 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 self._last_float_check = 0 else self._last_float_check = self._last_float_check + dtime end + local pos, rou_pos, node -- Drop minecart if it isn't on a rail anymore if self._last_float_check >= mcl_minecarts.check_float_time then - - - for _,object in pairs(minetest.get_objects_inside_radius(pos, 1.3)) do - if object ~= self.object then - local mob = object:get_luaentity() - if mob then mob = mob._cmi_is_mob == true end - if mob and (not self._driver) and not object:get_attach() then - self._driver = object - object:set_attach(self.object, "", {x=0, y=-1.75, z=-2}, {x=0, y=0, z=0}) - mobs:set_animation(self.object, "stand") - return - end - end - end - - + pos = self.object:get_pos() + rou_pos = vector.round(pos) + 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 -- Detach driver if player then @@ -289,12 +300,8 @@ local function register_entity(entity_id, mesh, textures, drop, on_rightclick, o end end - if update.vel then + if self._punched then vel = vector.add(vel, self._velocity) - if vel.x>8 then vel.x = 8 end - if vel.x<-8 then vel.x = -8 end - if vel.z>8 then vel.z = 8 end - if vel.z<-8 then vel.z = -8 end self.object:set_velocity(vel) self._old_dir.y = 0 elseif vector.equals(vel, {x=0, y=0, z=0}) and (not has_fuel) then @@ -619,14 +626,17 @@ register_minecart( "mcl_minecarts_minecart_normal.png", {"mcl_minecarts:minecart"}, function(self, clicker) - if not clicker or not clicker:is_player() then return end - if clicker == self._driver then + local name = clicker:get_player_name() + if not clicker or not clicker:is_player() then + return + end + local player_name = clicker:get_player_name() + if self._driver and player_name == self._driver then detach_driver(self) - else - local name = clicker:get_player_name() - self._driver = clicker + elseif not self._driver then + self._driver = player_name self._start_pos = self.object:get_pos() - mcl_player.player_attached[name] = true + mcl_player.player_attached[player_name] = true clicker:set_attach(self.object, "", {x=0, y=-1.75, z=-2}, {x=0, y=0, z=0}) mcl_player.player_attached[name] = true minetest.after(0.2, function(name) @@ -637,7 +647,6 @@ register_minecart( mcl_tmp_message.message(clicker, S("Sneak to dismount")) end end, name) - clicker:set_look_horizontal(self.object:get_yaw()) end end, activate_normal_minecart ) diff --git a/mods/ENTITIES/mobs_mc/horse.lua b/mods/ENTITIES/mobs_mc/horse.lua index b9d82660c..4e588855f 100644 --- a/mods/ENTITIES/mobs_mc/horse.lua +++ b/mods/ENTITIES/mobs_mc/horse.lua @@ -451,6 +451,6 @@ 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:zombie_horse", S("Zombie Horse"), "mobs_mc_spawn_icon_horse_zombie.png", 0) mobs:register_egg("mobs_mc:donkey", S("Donkey"), "mobs_mc_spawn_icon_donkey.png", 0) mobs:register_egg("mobs_mc:mule", S("Mule"), "mobs_mc_spawn_icon_mule.png", 0) diff --git a/mods/ENTITIES/mobs_mc/textures/mobs_mc_horse_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/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/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/HUD/hudbars/init.lua b/mods/HUD/hudbars/init.lua index e52aa8808..e1ff3f5f1 100644 --- a/mods/HUD/hudbars/init.lua +++ b/mods/HUD/hudbars/init.lua @@ -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/mcl_experience/init.lua b/mods/HUD/mcl_experience/init.lua index 7b89bd3b7..df733e138 100644 --- a/mods/HUD/mcl_experience/init.lua +++ b/mods/HUD/mcl_experience/init.lua @@ -184,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) 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_bows/arrow.lua b/mods/ITEMS/mcl_bows/arrow.lua index e8e3ec160..efa465ddf 100644 --- a/mods/ITEMS/mcl_bows/arrow.lua +++ b/mods/ITEMS/mcl_bows/arrow.lua @@ -35,53 +35,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, @@ -185,6 +145,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 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_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_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/init.lua b/mods/ITEMS/mcl_buckets/init.lua index 3a06272b3..9e830fd73 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, + 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 = 16, - groups = groups, + groups = def.groups, on_place = function(itemstack, user, pointed_thing) -- Must be pointing to node if pointed_thing.type ~= "node" then @@ -99,10 +84,10 @@ 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() @@ -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/register.lua b/mods/ITEMS/mcl_buckets/register.lua new file mode 100644 index 000000000..1af9fcdba --- /dev/null +++ b/mods/ITEMS/mcl_buckets/register.lua @@ -0,0 +1,115 @@ +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") + +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_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_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_enchanting/engine.lua b/mods/ITEMS/mcl_enchanting/engine.lua index 631c96a29..791527c5e 100644 --- a/mods/ITEMS/mcl_enchanting/engine.lua +++ b/mods/ITEMS/mcl_enchanting/engine.lua @@ -22,7 +22,7 @@ end function mcl_enchanting.load_enchantments(itemstack, enchantments) if not mcl_enchanting.is_book(itemstack:get_name()) then - mcl_enchanting.unload_enchantments(itemstack) + 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 @@ -159,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) 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_jukebox/init.lua b/mods/ITEMS/mcl_jukebox/init.lua index b9f762a51..c5bd3d268 100644 --- a/mods/ITEMS/mcl_jukebox/init.lua +++ b/mods/ITEMS/mcl_jukebox/init.lua @@ -233,4 +233,14 @@ mcl_jukebox.register_record("Minetest", "Jordach", "far", "mcl_jukebox_record_fa 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") \ No newline at end of file +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_portals/portal_nether.lua b/mods/ITEMS/mcl_portals/portal_nether.lua index 7e23a9f7b..32a24e092 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 @@ -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/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/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/PLAYER/mcl_player/init.lua b/mods/PLAYER/mcl_player/init.lua index 90cba148f..449b062c5 100644 --- a/mods/PLAYER/mcl_player/init.lua +++ b/mods/PLAYER/mcl_player/init.lua @@ -6,6 +6,16 @@ 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") or controls.LMB then + return true + else + return false + end +end + mcl_player.registered_player_models = { } -- Local for speed. @@ -174,30 +184,30 @@ minetest.register_globalstep(function(dtime) player_anim[name] = nil player_sneak[name] = controls.sneak end - if controls.LMB and not controls.sneak and head_in_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 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 head_in_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 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 head_in_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 not controls.LMB and not controls.sneak and head_in_water and is_sprinting == true 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 controls.LMB and not controls.sneak then + 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 head_in_water and is_sprinting == true then player_set_animation(player, "swim_stand", animation_speed_mod) diff --git a/mods/PLAYER/mcl_playerplus/init.lua b/mods/PLAYER/mcl_playerplus/init.lua index 26cbd6072..ab8487396 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,7 +41,7 @@ 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 ipairs(get_connected_players()) do local controls = player:get_player_control() name = player:get_player_name() @@ -37,10 +53,10 @@ minetest.register_globalstep(function(dtime) local player_vel_yaw = 0 - if degrees(minetest.dir_to_yaw(player_velocity)) == 0 then + 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 -- controls right and left arms pitch when shooting a bow or punching @@ -62,7 +78,7 @@ minetest.register_globalstep(function(dtime) 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 minetest.get_item_group(mcl_playerinfo[name].node_head, "water") ~= 0 and player:get_attach() == nil and mcl_sprint.is_sprinting(name) == true then + 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 @@ -127,18 +143,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 @@ -157,7 +173,7 @@ minetest.register_globalstep(function(dtime) time = 0 -- check players - for _,player in ipairs(minetest.get_connected_players()) do + for _,player in ipairs(get_connected_players()) do -- who am I? local name = player:get_player_name() @@ -198,7 +214,7 @@ minetest.register_globalstep(function(dtime) end -- Swimming? Check if boots are enchanted with depth strider - if minetest.get_item_group(node_feet, "liquid") ~= 0 and mcl_enchanting.get_enchantment(player:get_inventory():get_stack("armor", 5), "depth_strider") then + 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") @@ -220,7 +236,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) @@ -228,9 +244,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 @@ -247,15 +263,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 not player:get_attach() and (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 @@ -263,9 +279,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 }, @@ -288,7 +303,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, @@ -299,7 +314,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" @@ -307,7 +322,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_sprint/init.lua b/mods/PLAYER/mcl_sprint/init.lua index f3ea42f2c..9dc678000 100644 --- a/mods/PLAYER/mcl_sprint/init.lua +++ b/mods/PLAYER/mcl_sprint/init.lua @@ -50,16 +50,27 @@ 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