This commit is contained in:
Elias Fleckenstein 2021-03-15 09:23:58 +01:00
commit cb0d49a5a5
22 changed files with 514 additions and 341 deletions

9
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` * Dispenser support: `ITEMS/REDSTONE/mcl_dispensers`
## Mobs ## 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. 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. 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` * Get flowing direction of liquids: `CORE/flowlib`
* `on_walk_over` callback for nodes: `CORE/walkover` * `on_walk_over` callback for nodes: `CORE/walkover`
* Get node names close to player (to reduce constant querying): `PLAYER/mcl_playerinfo` * Get node names close to player (to reduce constant querying): `PLAYER/mcl_playerinfo`
* Explosion API
* Music discs API
* Flowers and flower pots
### Unstable APIs ### 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! 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 ### Planned APIs
* Flowers
* Saplings and trees * Saplings and trees
* Custom banner patterns * Custom banner patterns
* Custom dimensions * Custom dimensions
* Custom portals * Custom portals
* Music discs
* Dispenser and dropper support * Dispenser and dropper support
* Proper sky and weather APIs * Proper sky and weather APIs
* Explosion API

@ -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=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 * `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=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 * `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 * `creative_breakable=1`: Block is breakable by hand in creative mode. This group is implied if the node belongs to any other digging group

@ -12,14 +12,15 @@ local function detach_driver(self)
if not self._driver then if not self._driver then
return return
end end
if self._driver:is_player() then mcl_player.player_attached[self._driver] = nil
mcl_player.player_attached[self._driver:get_player_name()] = nil local player = minetest.get_player_by_name(self._driver)
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
self._driver = nil self._driver = nil
self._start_pos = 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 end
local function activate_tnt_minecart(self, timer) 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, 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 _punched = false, -- used to re-send _velocity and position
_velocity = {x=0, y=0, z=0}, -- only used on punch _velocity = {x=0, y=0, z=0}, -- only used on punch
_start_pos = nil, -- Used to calculate distance for “On A Rail” achievement _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 end
function cart:on_punch(puncher, time_from_last_punch, tool_capabilities, direction) 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() local pos = self.object:get_pos()
if not self._railtype then
-- Disable detector rail local node = minetest.get_node(vector.floor(pos)).name
local rou_pos = vector.round(pos) self._railtype = minetest.get_item_group(node, "connect_to_raillike")
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 end
-- Drop items and remove cart entity if not puncher or not puncher:is_player() then
if not minetest.is_creative_enabled(puncher:get_player_name()) then local cart_dir = mcl_minecarts:get_rail_direction(pos, {x=1, y=0, z=0}, nil, nil, self._railtype)
for d=1, #drop do if vector.equals(cart_dir, {x=0, y=0, z=0}) then
minetest.add_item(self.object:get_pos(), drop[d]) return
end end
elseif puncher and puncher:is_player() then self._velocity = vector.multiply(cart_dir, 3)
local inv = puncher:get_inventory() self._old_pos = nil
for d=1, #drop do self._punched = true
if not inv:contains_item("main", drop[d]) then return
inv:add_item("main", drop[d]) 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
end end
self.object:remove()
return
end 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 end
cart.on_activate_by_rail = on_activate_by_rail cart.on_activate_by_rail = on_activate_by_rail
function cart:on_step(dtime) function cart:on_step(dtime)
local ctrl, player = nil, nil local ctrl, player = nil, nil
local update = {} if self._driver then
local vel = self.object:get_velocity() player = minetest.get_player_by_name(self._driver)
local pos, rou_pos, node if player then
pos = self.object:get_pos() ctrl = player:get_player_control()
rou_pos = vector.round(pos) -- player detach
node = minetest.get_node(rou_pos) if ctrl.sneak then
local g = minetest.get_item_group(node.name, "connect_to_raillike") detach_driver(self)
if self._driver and self._driver:is_player() then return
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}))
end end
end end
end end
local vel = self.object:get_velocity()
local update = {}
if self._last_float_check == nil then if self._last_float_check == nil then
self._last_float_check = 0 self._last_float_check = 0
else else
self._last_float_check = self._last_float_check + dtime self._last_float_check = self._last_float_check + dtime
end end
local pos, rou_pos, node
-- Drop minecart if it isn't on a rail anymore -- Drop minecart if it isn't on a rail anymore
if self._last_float_check >= mcl_minecarts.check_float_time then if self._last_float_check >= mcl_minecarts.check_float_time then
pos = self.object:get_pos()
rou_pos = vector.round(pos)
for _,object in pairs(minetest.get_objects_inside_radius(pos, 1.3)) do node = minetest.get_node(rou_pos)
if object ~= self.object then local g = minetest.get_item_group(node.name, "connect_to_raillike")
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
if g ~= self._railtype and self._railtype ~= nil then if g ~= self._railtype and self._railtype ~= nil then
-- Detach driver -- Detach driver
if player then if player then
@ -289,12 +300,8 @@ local function register_entity(entity_id, mesh, textures, drop, on_rightclick, o
end end
end end
if update.vel then if self._punched then
vel = vector.add(vel, self._velocity) 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.object:set_velocity(vel)
self._old_dir.y = 0 self._old_dir.y = 0
elseif vector.equals(vel, {x=0, y=0, z=0}) and (not has_fuel) then 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_normal.png",
{"mcl_minecarts:minecart"}, {"mcl_minecarts:minecart"},
function(self, clicker) function(self, clicker)
if not clicker or not clicker:is_player() then return end local name = clicker:get_player_name()
if clicker == self._driver then 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) detach_driver(self)
else elseif not self._driver then
local name = clicker:get_player_name() self._driver = player_name
self._driver = clicker
self._start_pos = self.object:get_pos() 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}) clicker:set_attach(self.object, "", {x=0, y=-1.75, z=-2}, {x=0, y=0, z=0})
mcl_player.player_attached[name] = true mcl_player.player_attached[name] = true
minetest.after(0.2, function(name) minetest.after(0.2, function(name)
@ -637,7 +647,6 @@ register_minecart(
mcl_tmp_message.message(clicker, S("Sneak to dismount")) mcl_tmp_message.message(clicker, S("Sneak to dismount"))
end end
end, name) end, name)
clicker:set_look_horizontal(self.object:get_yaw())
end end
end, activate_normal_minecart end, activate_normal_minecart
) )

@ -451,6 +451,6 @@ mobs:spawn_specific("mobs_mc:donkey", mobs_mc.spawn.grassland_savanna, {"air"},
-- spawn eggs -- spawn eggs
mobs:register_egg("mobs_mc:horse", S("Horse"), "mobs_mc_spawn_icon_horse.png", 0) mobs:register_egg("mobs_mc:horse", S("Horse"), "mobs_mc_spawn_icon_horse.png", 0)
mobs:register_egg("mobs_mc:skeleton_horse", S("Skeleton Horse"), "mobs_mc_spawn_icon_horse_skeleton.png", 0) mobs:register_egg("mobs_mc:skeleton_horse", S("Skeleton Horse"), "mobs_mc_spawn_icon_horse_skeleton.png", 0)
mobs:register_egg("mobs_mc:zombie_horse", S("Zombie Horse"), "mobs_mc_spawn_icon_horse_zombie.png", 0) --mobs:register_egg("mobs_mc: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: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) mobs:register_egg("mobs_mc:mule", S("Mule"), "mobs_mc_spawn_icon_mule.png", 0)

Binary file not shown.

Before

Width:  |  Height:  |  Size: 11 KiB

@ -35,53 +35,13 @@ S("Arrows might get stuck on solid blocks and can be retrieved again. They are a
end, 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={ local ARROW_ENTITY={
physical = true, physical = true,
visual = "wielditem", pointable = false,
visual_size = {x=0.4, y=0.4}, visual = "mesh",
textures = {"mcl_bows:arrow_box"}, 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}, collisionbox = {-0.19, -0.125, -0.19, 0.19, 0.125, 0.19},
collide_with_objects = false, collide_with_objects = false,
_fire_damage_resistant = true, _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) -- Check for object "collision". Done every tick (hopefully this is not too stressing)
else 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. -- We just check for any hurtable objects nearby.
-- The radius of 3 is fairly liberal, but anything lower than than will cause -- The radius of 3 is fairly liberal, but anything lower than than will cause
-- arrow to hilariously go through mobs often. -- arrow to hilariously go through mobs often.

@ -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

Binary file not shown.

Before

Width:  |  Height:  |  Size: 173 B

After

Width:  |  Height:  |  Size: 359 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 132 B

After

Width:  |  Height:  |  Size: 212 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 317 B

After

Width:  |  Height:  |  Size: 260 B

@ -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)

@ -1,4 +1,5 @@
local S = minetest.get_translator("mcl_buckets") local S = minetest.get_translator("mcl_buckets")
local modpath = minetest.get_modpath(minetest.get_current_modname())
-- Minetest 0.4 mod: bucket -- Minetest 0.4 mod: bucket
-- See README.txt for licensing and other information. -- 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}) minetest.add_node(pos, {name=itemstring, param2=fullness})
end end
-- Register a new liquid function mcl_buckets.register_liquid(def)
-- source_place = a string or function. for i=1, #def.source_take do
-- * string: name of the node to place mcl_buckets.liquids[def.source_take[i]] = {
-- * function(pos): will returns name of the node to place with pos being the placement position source_place = def.source_place,
-- source_take = table of liquid source node names to take source_take = def.source_take[i],
-- itemname = itemstring of the new bucket item (or nil if liquid is not takeable) itemname = def.itemname,
-- 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,
} }
if type(source_place) == "string" then if type(def.source_place) == "string" then
mcl_buckets.liquids[source_place] = mcl_buckets.liquids[source_take[i]] mcl_buckets.liquids[def.source_place] = mcl_buckets.liquids[def.source_take[i]]
end end
end end
if itemname ~= nil then if def.itemname ~= nil then
minetest.register_craftitem(itemname, { minetest.register_craftitem(def.itemname, {
description = name, description = def.name,
_doc_items_longdesc = longdesc, _doc_items_longdesc = def.longdesc,
_doc_items_usagehelp = usagehelp, _doc_items_usagehelp = def.usagehelp,
_tt_help = tt_help, _tt_help = def.tt_help,
inventory_image = inventory_image, inventory_image = def.inventory_image,
stack_max = 16, stack_max = 16,
groups = groups, groups = def.groups,
on_place = function(itemstack, user, pointed_thing) on_place = function(itemstack, user, pointed_thing)
-- Must be pointing to node -- Must be pointing to node
if pointed_thing.type ~= "node" then if pointed_thing.type ~= "node" then
@ -99,10 +84,10 @@ function mcl_buckets.register_liquid(source_place, source_take, itemname, invent
end end
local node_place local node_place
if type(source_place) == "function" then if type(def.source_place) == "function" then
node_place = source_place(place_pos) node_place = def.source_place(place_pos)
else else
node_place = source_place node_place = def.source_place
end end
-- Check if pointing to a buildable node -- Check if pointing to a buildable node
local item = itemstack:get_name() local item = itemstack:get_name()
@ -163,17 +148,17 @@ function mcl_buckets.register_liquid(source_place, source_take, itemname, invent
end, end,
_on_dispense = function(stack, pos, droppos, dropnode, dropdir) _on_dispense = function(stack, pos, droppos, dropnode, dropdir)
local iname = stack:get_name() 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 -- Fail placement of liquid
elseif buildable then elseif buildable then
-- buildable; replace the node -- buildable; replace the node
local node_place local node_place
if type(source_place) == "function" then if type(def.source_place) == "function" then
node_place = source_place(droppos) node_place = def.source_place(droppos)
else else
node_place = source_place node_place = def.source_place
end end
place_liquid(droppos, node_place) place_liquid(droppos, node_place)
stack:set_name("mcl_buckets:bucket_empty") stack:set_name("mcl_buckets:bucket_empty")
@ -292,114 +277,4 @@ minetest.register_craftitem("mcl_buckets:bucket_empty", {
end, end,
}) })
if mod_mcl_core then dofile(modpath.."/register.lua")
-- 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"}},
})

@ -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"}},
})

@ -1,3 +0,0 @@
mcl_init
mcl_formspec
mcl_sounds

@ -1 +0,0 @@
Adds a crafting table.

@ -1,5 +1,36 @@
local S = minetest.get_translator("mcl_crafting_table") 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", { minetest.register_node("mcl_crafting_table:crafting_table", {
description = S("Crafting Table"), description = S("Crafting Table"),
_tt_help = S("3×3 crafting grid"), _tt_help = S("3×3 crafting grid"),
@ -12,27 +43,7 @@ minetest.register_node("mcl_crafting_table:crafting_table", {
paramtype2 = "facedir", paramtype2 = "facedir",
groups = {handy=1,axey=1, deco_block=1, material_wood=1,flammable=-1}, groups = {handy=1,axey=1, deco_block=1, material_wood=1,flammable=-1},
on_rightclick = function(pos, node, player, itemstack) on_rightclick = function(pos, node, player, itemstack)
player:get_inventory():set_width("craft", 3) show_crafting_form(player)
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)
end, end,
sounds = mcl_sounds.node_sound_wood_defaults(), sounds = mcl_sounds.node_sound_wood_defaults(),
_mcl_blast_resistance = 2.5, _mcl_blast_resistance = 2.5,

@ -1 +1,4 @@
name = mcl_crafting_table name = mcl_crafting_table
description = Adds a crafting table.
depends = mcl_init, mcl_formspec, mcl_sounds
optional_depends = mcl_colors

@ -28,7 +28,72 @@ local alldirs=
{ x = 0, y = 0, z = 1} { 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 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, { mcl_particles.add_node_particlespawner(pos, {
amount = 0.1, amount = 0.1,
time = 0, time = 0,
@ -48,6 +113,8 @@ local spawn_smoke = function(pos)
length = 2.1, length = 2.1,
}, },
}, "high") }, "high")
-- ]]
end end
-- --

@ -64,7 +64,7 @@ local function destroy_nether_portal(pos)
local meta = minetest.get_meta(pos) local meta = minetest.get_meta(pos)
local node = minetest.get_node(pos) local node = minetest.get_node(pos)
local nn, orientation = node.name, node.param2 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")) local has_meta = minetest.string_to_pos(meta:get_string("portal_frame1"))
if has_meta then if has_meta then
@ -138,8 +138,6 @@ minetest.register_node("mcl_portals:portal", {
sunlight_propagates = true, sunlight_propagates = true,
use_texture_alpha = minetest.features.use_texture_alpha_string_modes and "blend" or true, use_texture_alpha = minetest.features.use_texture_alpha_string_modes and "blend" or true,
walkable = false, walkable = false,
diggable = false,
pointable = false,
buildable_to = false, buildable_to = false,
is_ground_content = false, is_ground_content = false,
drop = "", drop = "",
@ -152,7 +150,8 @@ minetest.register_node("mcl_portals:portal", {
{-0.5, -0.5, -0.1, 0.5, 0.5, 0.1}, {-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, on_destruct = destroy_nether_portal,
_mcl_hardness = -1, _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_time", tostring(0))
meta:set_string("portal_target", "") meta:set_string("portal_target", "")
end end
return true return true
end end
-- Attempts to light a Nether portal at pos -- Attempts to light a Nether portal at pos
@ -842,7 +841,7 @@ minetest.override_item("mcl_core:obsidian", {
_on_ignite = function(user, pointed_thing) _on_ignite = function(user, pointed_thing)
local x, y, z = pointed_thing.under.x, pointed_thing.under.y, pointed_thing.under.z 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: -- 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 - 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 - 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}) 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
end, end,
}) })

@ -100,9 +100,10 @@ function mcl_potions.register_arrow(name, desc, color, def)
local ARROW_ENTITY={ local ARROW_ENTITY={
physical = true, physical = true,
visual = "wielditem", visual = "mesh",
visual_size = {x=0.4, y=0.4}, mesh = "mcl_bows_arrow.obj",
textures = {"mcl_potions:"..name.."_arrow_box"}, visual_size = {x=1, y=1},
textures = arrow_image(color, 100),
collisionbox = {-0.19, -0.125, -0.19, 0.19, 0.125, 0.19}, collisionbox = {-0.19, -0.125, -0.19, 0.19, 0.125, 0.19},
collide_with_objects = false, 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) -- Check for object "collision". Done every tick (hopefully this is not too stressing)
else 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. -- We just check for any hurtable objects nearby.
-- The radius of 3 is fairly liberal, but anything lower than than will cause -- The radius of 3 is fairly liberal, but anything lower than than will cause
-- arrow to hilariously go through mobs often. -- arrow to hilariously go through mobs often.

@ -6,6 +6,16 @@ mcl_player = {}
-- Note: This is currently broken due to a bug in Irrlicht, leave at 0 -- Note: This is currently broken due to a bug in Irrlicht, leave at 0
local animation_blend = 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 = { } mcl_player.registered_player_models = { }
-- Local for speed. -- Local for speed.
@ -174,30 +184,30 @@ minetest.register_globalstep(function(dtime)
player_anim[name] = nil player_anim[name] = nil
player_sneak[name] = controls.sneak player_sneak[name] = controls.sneak
end 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) player_set_animation(player, "swim_walk_mine", animation_speed_mod)
elseif not controls.sneak and head_in_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) 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) 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) 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) player_set_animation(player, "sneak_walk_mine", animation_speed_mod)
elseif is_sprinting == true and not controls.sneak and not head_in_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) 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) player_set_animation(player, "sneak_walk", animation_speed_mod)
else else
player_set_animation(player, "walk", animation_speed_mod) player_set_animation(player, "walk", animation_speed_mod)
end 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") 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") 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") 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") player_set_animation(player, "sneak_mine")
elseif not controls.sneak and head_in_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) player_set_animation(player, "swim_stand", animation_speed_mod)

@ -50,16 +50,27 @@ end
local function setSprinting(playerName, sprinting) --Sets the state of a player (0=stopped/moving, 1=sprinting) 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 player = minetest.get_player_by_name(playerName)
local controls = player:get_player_control()
if players[playerName] then if players[playerName] then
players[playerName].sprinting = sprinting players[playerName].sprinting = sprinting
if sprinting == true 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
players[playerName].fov = math.min(players[playerName].fov + 0.05, 1.2) if sprinting == true then
player:set_fov(players[playerName].fov, true, 0.15) players[playerName].fov = math.min(players[playerName].fov + 0.05, 1.2)
playerphysics.add_physics_factor(player, "speed", "mcl_sprint:sprint", mcl_sprint.SPEED) players[playerName].fade_time = .15
elseif sprinting == false then 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) players[playerName].fov = math.max(players[playerName].fov - 0.05, 1.0)
player:set_fov(players[playerName].fov, true, 0.15) 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 end
return true return true
end end