Merge branch 'master' into datapacks
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
|
||||||
|
|
||||||
|
|
|
@ -33,8 +33,7 @@ mgvalleys_spflags = noaltitude_chill,noaltitude_dry,nohumid_rivers,vary_river_de
|
||||||
keepInventory = false
|
keepInventory = false
|
||||||
|
|
||||||
# Performance settings
|
# Performance settings
|
||||||
dedicated_server_step = 0.01
|
dedicated_server_step = 0.001
|
||||||
liquid_update = 0.25
|
|
||||||
abm_interval = 0.25
|
abm_interval = 0.25
|
||||||
max_objects_per_block = 4096
|
max_objects_per_block = 4096
|
||||||
max_packets_per_iteration = 10096
|
max_packets_per_iteration = 10096
|
||||||
|
|
|
@ -1,3 +1,6 @@
|
||||||
|
local get_connected_players = minetest.get_connected_players
|
||||||
|
local clock = os.clock
|
||||||
|
|
||||||
controls = {}
|
controls = {}
|
||||||
controls.players = {}
|
controls.players = {}
|
||||||
|
|
||||||
|
@ -42,7 +45,7 @@ minetest.register_on_leaveplayer(function(player)
|
||||||
end)
|
end)
|
||||||
|
|
||||||
minetest.register_globalstep(function(dtime)
|
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_name = player:get_player_name()
|
||||||
local player_controls = player:get_player_control()
|
local player_controls = player:get_player_control()
|
||||||
if controls.players[player_name] then
|
if controls.players[player_name] then
|
||||||
|
@ -53,15 +56,15 @@ minetest.register_globalstep(function(dtime)
|
||||||
for _, func in pairs(controls.registered_on_press) do
|
for _, func in pairs(controls.registered_on_press) do
|
||||||
func(player, cname)
|
func(player, cname)
|
||||||
end
|
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
|
elseif cbool==true and controls.players[player_name][cname][1]==true then
|
||||||
for _, func in pairs(controls.registered_on_hold) do
|
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
|
end
|
||||||
--Release a key
|
--Release a key
|
||||||
elseif cbool==false and controls.players[player_name][cname][1]==true then
|
elseif cbool==false and controls.players[player_name][cname][1]==true then
|
||||||
for _, func in pairs(controls.registered_on_release) do
|
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
|
end
|
||||||
controls.players[player_name][cname] = {false}
|
controls.players[player_name][cname] = {false}
|
||||||
end
|
end
|
||||||
|
|
|
@ -18,6 +18,16 @@ local CONTENT_FIRE = minetest.get_content_id("mcl_fire:fire")
|
||||||
|
|
||||||
local S = minetest.get_translator("mcl_explosions")
|
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
|
-- Saved sphere explosion shapes for various radiuses
|
||||||
local sphere_shapes = {}
|
local sphere_shapes = {}
|
||||||
|
|
||||||
|
@ -64,7 +74,7 @@ local function compute_sphere_rays(radius)
|
||||||
local d = x * x + y * y + z * z
|
local d = x * x + y * y + z * z
|
||||||
if d <= radius * radius then
|
if d <= radius * radius then
|
||||||
local pos = { x = x, y = y, z = z }
|
local pos = { x = x, y = y, z = z }
|
||||||
sphere[minetest.hash_node_position(pos)] = pos
|
sphere[hash_node_position(pos)] = pos
|
||||||
break
|
break
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
@ -79,7 +89,7 @@ local function compute_sphere_rays(radius)
|
||||||
local d = x * x + y * y + z * z
|
local d = x * x + y * y + z * z
|
||||||
if d <= radius * radius then
|
if d <= radius * radius then
|
||||||
local pos = { x = x, y = y, z = z }
|
local pos = { x = x, y = y, z = z }
|
||||||
sphere[minetest.hash_node_position(pos)] = pos
|
sphere[hash_node_position(pos)] = pos
|
||||||
break
|
break
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
@ -94,7 +104,7 @@ local function compute_sphere_rays(radius)
|
||||||
local d = x * x + y * y + z * z
|
local d = x * x + y * y + z * z
|
||||||
if d <= radius * radius then
|
if d <= radius * radius then
|
||||||
local pos = { x = x, y = y, z = z }
|
local pos = { x = x, y = y, z = z }
|
||||||
sphere[minetest.hash_node_position(pos)] = pos
|
sphere[hash_node_position(pos)] = pos
|
||||||
break
|
break
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
@ -156,7 +166,7 @@ end
|
||||||
-- inlined to avoid function calls and unnecessary table creation. This was
|
-- inlined to avoid function calls and unnecessary table creation. This was
|
||||||
-- measured to give a significant performance increase.
|
-- measured to give a significant performance increase.
|
||||||
local function trace_explode(pos, strength, raydirs, radius, info, puncher)
|
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),
|
local emin, emax = vm:read_from_map(vector.subtract(pos, radius),
|
||||||
vector.add(pos, radius))
|
vector.add(pos, radius))
|
||||||
|
@ -207,7 +217,7 @@ local function trace_explode(pos, strength, raydirs, radius, info, puncher)
|
||||||
br = max_blast_resistance
|
br = max_blast_resistance
|
||||||
end
|
end
|
||||||
|
|
||||||
local hash = minetest.hash_node_position(npos)
|
local hash = hash_node_position(npos)
|
||||||
|
|
||||||
rpos_x = rpos_x + STEP_LENGTH * rdir_x
|
rpos_x = rpos_x + STEP_LENGTH * rdir_x
|
||||||
rpos_y = rpos_y + STEP_LENGTH * rdir_y
|
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
|
-- Entities in radius of explosion
|
||||||
local punch_radius = 2 * strength
|
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
|
-- Trace rays for entity damage
|
||||||
for _, obj in pairs(objs) do
|
for _, obj in pairs(objs) do
|
||||||
|
@ -359,46 +369,46 @@ local function trace_explode(pos, strength, raydirs, radius, info, puncher)
|
||||||
local remove = true
|
local remove = true
|
||||||
|
|
||||||
if do_drop or on_blast ~= nil then
|
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
|
if on_blast ~= nil then
|
||||||
on_blast(npos, 1.0, do_drop)
|
on_blast(npos, 1.0, do_drop)
|
||||||
remove = false
|
remove = false
|
||||||
else
|
else
|
||||||
local name = minetest.get_name_from_content_id(data[idx])
|
local name = get_name_from_content_id(data[idx])
|
||||||
local drop = minetest.get_node_drops(name, "")
|
local drop = get_node_drops(name, "")
|
||||||
|
|
||||||
for _, item in ipairs(drop) do
|
for _, item in ipairs(drop) do
|
||||||
if type(item) ~= "string" then
|
if type(item) ~= "string" then
|
||||||
item = item:get_name() .. item:get_count()
|
item = item:get_name() .. item:get_count()
|
||||||
end
|
end
|
||||||
minetest.add_item(npos, item)
|
add_item(npos, item)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
if remove then
|
if remove then
|
||||||
if mod_fire and fire and math.random(1, 3) == 1 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
|
else
|
||||||
table.insert(airs, minetest.get_position_from_hash(hash))
|
table.insert(airs, get_position_from_hash(hash))
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
-- We use bulk_set_node instead of LVM because we want to have on_destruct and
|
-- We use bulk_set_node instead of LVM because we want to have on_destruct and
|
||||||
-- on_construct being called
|
-- on_construct being called
|
||||||
if #airs > 0 then
|
if #airs > 0 then
|
||||||
minetest.bulk_set_node(airs, {name="air"})
|
bulk_set_node(airs, {name="air"})
|
||||||
end
|
end
|
||||||
if #fires > 0 then
|
if #fires > 0 then
|
||||||
minetest.bulk_set_node(fires, {name="mcl_fire:fire"})
|
bulk_set_node(fires, {name="mcl_fire:fire"})
|
||||||
end
|
end
|
||||||
-- Update falling nodes
|
-- Update falling nodes
|
||||||
for a=1, #airs do
|
for a=1, #airs do
|
||||||
local p = airs[a]
|
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
|
end
|
||||||
for f=1, #fires do
|
for f=1, #fires do
|
||||||
local p = fires[f]
|
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
|
end
|
||||||
|
|
||||||
-- Log explosion
|
-- Log explosion
|
||||||
|
|
|
@ -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,12 +97,31 @@ 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)
|
local pos = self.object:get_pos()
|
||||||
if self._boomtimer then return end
|
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
|
||||||
|
|
||||||
|
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
|
||||||
|
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._driver then
|
||||||
|
if self._old_pos then
|
||||||
|
self.object:set_pos(self._old_pos)
|
||||||
|
end
|
||||||
detach_driver(self)
|
detach_driver(self)
|
||||||
end
|
end
|
||||||
local pos = self.object:get_pos()
|
|
||||||
|
|
||||||
-- Disable detector rail
|
-- Disable detector rail
|
||||||
local rou_pos = vector.round(pos)
|
local rou_pos = vector.round(pos)
|
||||||
|
@ -127,70 +147,61 @@ local function register_entity(entity_id, mesh, textures, drop, on_rightclick, o
|
||||||
end
|
end
|
||||||
|
|
||||||
self.object:remove()
|
self.object:remove()
|
||||||
|
return
|
||||||
|
end
|
||||||
|
|
||||||
|
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()
|
|
||||||
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()
|
ctrl = player:get_player_control()
|
||||||
-- player detach
|
-- player detach
|
||||||
if ctrl.sneak then
|
if ctrl.sneak then
|
||||||
detach_driver(self)
|
detach_driver(self)
|
||||||
return
|
return
|
||||||
end
|
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
|
||||||
|
|
||||||
|
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
|
|
||||||
if clicker == self._driver then
|
|
||||||
detach_driver(self)
|
|
||||||
else
|
|
||||||
local name = clicker:get_player_name()
|
local name = clicker:get_player_name()
|
||||||
self._driver = clicker
|
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)
|
||||||
|
elseif not self._driver then
|
||||||
|
self._driver = player_name
|
||||||
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)
|
||||||
|
|
Before Width: | Height: | Size: 11 KiB |
|
@ -11,6 +11,18 @@ of the license, or (at your option) any later version.
|
||||||
|
|
||||||
local S = minetest.get_translator("lightning")
|
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 = {}
|
||||||
|
|
||||||
lightning.interval_low = 17
|
lightning.interval_low = 17
|
||||||
|
@ -45,7 +57,7 @@ minetest.register_globalstep(revertsky)
|
||||||
-- select a random strike point, midpoint
|
-- select a random strike point, midpoint
|
||||||
local function choose_pos(pos)
|
local function choose_pos(pos)
|
||||||
if not pos then
|
if not pos then
|
||||||
local playerlist = minetest.get_connected_players()
|
local playerlist = get_connected_players()
|
||||||
local playercount = table.getn(playerlist)
|
local playercount = table.getn(playerlist)
|
||||||
|
|
||||||
-- nobody on
|
-- 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))
|
pos.z = math.floor(pos.z - (lightning.range_h / 2) + rng:next(1, lightning.range_h))
|
||||||
end
|
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
|
-- nothing but air found
|
||||||
if b then
|
if b then
|
||||||
return nil, nil
|
return nil, nil
|
||||||
end
|
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
|
if n.name == "air" or n.name == "ignore" then
|
||||||
return nil, nil
|
return nil, nil
|
||||||
end
|
end
|
||||||
|
@ -87,7 +99,7 @@ end
|
||||||
-- * returns: bool - success if a strike happened
|
-- * returns: bool - success if a strike happened
|
||||||
lightning.strike = function(pos)
|
lightning.strike = function(pos)
|
||||||
if lightning.auto then
|
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
|
end
|
||||||
|
|
||||||
local pos2
|
local pos2
|
||||||
|
@ -97,7 +109,7 @@ lightning.strike = function(pos)
|
||||||
return false
|
return false
|
||||||
end
|
end
|
||||||
|
|
||||||
minetest.add_particlespawner({
|
add_particlespawner({
|
||||||
amount = 1,
|
amount = 1,
|
||||||
time = 0.2,
|
time = 0.2,
|
||||||
-- make it hit the top of a block exactly with the bottom
|
-- make it hit the top of a block exactly with the bottom
|
||||||
|
@ -120,16 +132,16 @@ lightning.strike = function(pos)
|
||||||
glow = minetest.LIGHT_MAX,
|
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
|
-- 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
|
for o=1, #objs do
|
||||||
local obj = objs[o]
|
local obj = objs[o]
|
||||||
local lua = obj:get_luaentity()
|
local lua = obj:get_luaentity()
|
||||||
if obj:is_player() then
|
if obj:is_player() then
|
||||||
-- Player damage
|
-- 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()))
|
mcl_death_messages.player_damage(obj, S("@1 was struck by lightning.", obj:get_player_name()))
|
||||||
end
|
end
|
||||||
obj:set_hp(obj:get_hp()-5, { type = "punch", from = "mod" })
|
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
|
if lua.name == "mobs_mc:pig" then
|
||||||
local rot = obj:get_yaw()
|
local rot = obj:get_yaw()
|
||||||
obj:remove()
|
obj:remove()
|
||||||
obj = minetest.add_entity(pos2, "mobs_mc:pigman")
|
obj = add_entity(pos2, "mobs_mc:pigman")
|
||||||
obj:set_yaw(rot)
|
obj:set_yaw(rot)
|
||||||
-- mooshroom: toggle color red/brown (no damage)
|
-- mooshroom: toggle color red/brown (no damage)
|
||||||
elseif lua.name == "mobs_mc:mooshroom" then
|
elseif lua.name == "mobs_mc:mooshroom" then
|
||||||
|
@ -163,7 +175,7 @@ lightning.strike = function(pos)
|
||||||
elseif lua.name == "mobs_mc:creeper" then
|
elseif lua.name == "mobs_mc:creeper" then
|
||||||
local rot = obj:get_yaw()
|
local rot = obj:get_yaw()
|
||||||
obj:remove()
|
obj:remove()
|
||||||
obj = minetest.add_entity(pos2, "mobs_mc:creeper_charged")
|
obj = add_entity(pos2, "mobs_mc:creeper_charged")
|
||||||
obj:set_yaw(rot)
|
obj:set_yaw(rot)
|
||||||
-- Other mobs: Just damage
|
-- Other mobs: Just damage
|
||||||
else
|
else
|
||||||
|
@ -172,7 +184,7 @@ lightning.strike = function(pos)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
local playerlist = minetest.get_connected_players()
|
local playerlist = get_connected_players()
|
||||||
for i = 1, #playerlist do
|
for i = 1, #playerlist do
|
||||||
local player = playerlist[i]
|
local player = playerlist[i]
|
||||||
local sky = {}
|
local sky = {}
|
||||||
|
@ -197,25 +209,25 @@ lightning.strike = function(pos)
|
||||||
if rng:next(1,100) <= 3 then
|
if rng:next(1,100) <= 3 then
|
||||||
skeleton_lightning = true
|
skeleton_lightning = true
|
||||||
end
|
end
|
||||||
if minetest.get_item_group(minetest.get_node({x = pos2.x, y = pos2.y - 1, z = pos2.z}).name, "liquid") < 1 then
|
if get_item_group(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_node(pos2).name == "air" then
|
||||||
-- Low chance for a lightning to spawn skeleton horse + skeletons
|
-- Low chance for a lightning to spawn skeleton horse + skeletons
|
||||||
if skeleton_lightning then
|
if skeleton_lightning then
|
||||||
minetest.add_entity(pos2, "mobs_mc:skeleton_horse")
|
add_entity(pos2, "mobs_mc:skeleton_horse")
|
||||||
|
|
||||||
local angle, posadd
|
local angle, posadd
|
||||||
angle = math.random(0, math.pi*2)
|
angle = math.random(0, math.pi*2)
|
||||||
for i=1,3 do
|
for i=1,3 do
|
||||||
posadd = {x=math.cos(angle),y=0,z=math.sin(angle)}
|
posadd = {x=math.cos(angle),y=0,z=math.sin(angle)}
|
||||||
posadd = vector.normalize(posadd)
|
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)
|
mob:set_yaw(angle-math.pi/2)
|
||||||
angle = angle + (math.pi*2) / 3
|
angle = angle + (math.pi*2) / 3
|
||||||
end
|
end
|
||||||
|
|
||||||
-- Cause a fire
|
-- Cause a fire
|
||||||
else
|
else
|
||||||
minetest.set_node(pos2, {name = "mcl_fire:fire"})
|
set_node(pos2, {name = "mcl_fire:fire"})
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
@ -223,9 +235,9 @@ lightning.strike = function(pos)
|
||||||
end
|
end
|
||||||
|
|
||||||
-- if other mods disable auto lightning during initialization, don't trigger the first lightning.
|
-- 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
|
if lightning.auto then
|
||||||
minetest.after(rng:next(lightning.interval_low,
|
after(rng:next(lightning.interval_low,
|
||||||
lightning.interval_high), lightning.strike)
|
lightning.interval_high), lightning.strike)
|
||||||
end
|
end
|
||||||
end)
|
end)
|
||||||
|
|
|
@ -1,6 +1,14 @@
|
||||||
local S = minetest.get_translator("mcl_void_damage")
|
local S = minetest.get_translator("mcl_void_damage")
|
||||||
local enable_damage = minetest.settings:get_bool("enable_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 voidtimer = 0
|
||||||
local VOID_DAMAGE_FREQ = 0.5
|
local VOID_DAMAGE_FREQ = 0.5
|
||||||
local VOID_DAMAGE = 4
|
local VOID_DAMAGE = 4
|
||||||
|
@ -33,7 +41,7 @@ minetest.register_on_mods_loaded(function()
|
||||||
self._void_timer = 0
|
self._void_timer = 0
|
||||||
|
|
||||||
local pos = obj:get_pos()
|
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
|
if void_deadly then
|
||||||
local ent = obj:get_luaentity()
|
local ent = obj:get_luaentity()
|
||||||
obj:remove()
|
obj:remove()
|
||||||
|
@ -51,11 +59,11 @@ minetest.register_globalstep(function(dtime)
|
||||||
if voidtimer > VOID_DAMAGE_FREQ then
|
if voidtimer > VOID_DAMAGE_FREQ then
|
||||||
voidtimer = 0
|
voidtimer = 0
|
||||||
local enable_damage = minetest.settings:get_bool("enable_damage")
|
local enable_damage = minetest.settings:get_bool("enable_damage")
|
||||||
local players = minetest.get_connected_players()
|
local players = get_connected()
|
||||||
for p=1, #players do
|
for p=1, #players do
|
||||||
local player = players[p]
|
local player = players[p]
|
||||||
local pos = player:get_pos()
|
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
|
if void_deadly then
|
||||||
local immortal_val = player:get_armor_groups().immortal
|
local immortal_val = player:get_armor_groups().immortal
|
||||||
local is_immortal = false
|
local is_immortal = false
|
||||||
|
@ -65,14 +73,14 @@ minetest.register_globalstep(function(dtime)
|
||||||
if is_immortal or not enable_damage then
|
if is_immortal or not enable_damage then
|
||||||
-- If damage is disabled, we can't kill players.
|
-- If damage is disabled, we can't kill players.
|
||||||
-- So we just teleport the player back to spawn.
|
-- 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)
|
player:set_pos(spawn)
|
||||||
mcl_worlds.dimension_change(player, mcl_worlds.pos_to_dimension(spawn))
|
dim_change(player, pos_to_dim(spawn))
|
||||||
minetest.chat_send_player(player:get_player_name(), S("The void is off-limits to you!"))
|
send_chat(player:get_player_name(), S("The void is off-limits to you!"))
|
||||||
elseif enable_damage and not is_immortal then
|
elseif enable_damage and not is_immortal then
|
||||||
-- Damage enabled, not immortal: Deal void damage (4 HP / 0.5 seconds)
|
-- Damage enabled, not immortal: Deal void damage (4 HP / 0.5 seconds)
|
||||||
if player:get_hp() > 0 then
|
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)
|
player:set_hp(player:get_hp() - VOID_DAMAGE)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -511,9 +511,9 @@ local function update_health(player)
|
||||||
end
|
end
|
||||||
|
|
||||||
-- update built-in HUD bars
|
-- 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 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
|
if hb.settings.forceload_default_hudbars then
|
||||||
hb.unhide_hudbar(player, "health")
|
hb.unhide_hudbar(player, "health")
|
||||||
end
|
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 or timer > 4 then
|
||||||
if main_timer > hb.settings.tick then main_timer = 0 end
|
if main_timer > hb.settings.tick then main_timer = 0 end
|
||||||
-- only proceed if damage is enabled
|
-- 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
|
for _, player in pairs(hb.players) do
|
||||||
-- update all hud elements
|
-- update all hud elements
|
||||||
update_hud(player)
|
update_hud(player, has_dmg)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -319,10 +319,10 @@ local anvildef = {
|
||||||
|
|
||||||
after_dig_node = function(pos, oldnode, oldmetadata, digger)
|
after_dig_node = function(pos, oldnode, oldmetadata, digger)
|
||||||
local meta = minetest.get_meta(pos)
|
local meta = minetest.get_meta(pos)
|
||||||
local meta2 = meta
|
local meta2 = meta:to_table()
|
||||||
meta:from_table(oldmetadata)
|
meta:from_table(oldmetadata)
|
||||||
drop_anvil_items(pos, meta)
|
drop_anvil_items(pos, meta)
|
||||||
meta:from_table(meta2:to_table())
|
meta:from_table(meta2)
|
||||||
end,
|
end,
|
||||||
allow_metadata_inventory_take = function(pos, listname, index, stack, player)
|
allow_metadata_inventory_take = function(pos, listname, index, stack, player)
|
||||||
local name = player:get_player_name()
|
local name = player:get_player_name()
|
||||||
|
|
|
@ -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
|
Before Width: | Height: | Size: 173 B After Width: | Height: | Size: 359 B |
Before Width: | Height: | Size: 132 B After Width: | Height: | Size: 212 B |
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,7 +0,0 @@
|
||||||
mcl_core
|
|
||||||
mcl_sounds
|
|
||||||
mcl_hunger
|
|
||||||
mcl_buckets
|
|
||||||
mcl_farming
|
|
||||||
mcl_mobitems
|
|
||||||
doc?
|
|
|
@ -1 +1,4 @@
|
||||||
name = mcl_cake
|
name = mcl_cake
|
||||||
|
description = Add cakes to mcl
|
||||||
|
depends = mcl_core, mcl_sounds, mcl_hunger, mcl_buckets, mcl_farming, mcl_mobitems
|
||||||
|
optional_depends = doc
|
||||||
|
|
|
@ -1,3 +0,0 @@
|
||||||
mcl_sounds
|
|
||||||
mcl_core
|
|
||||||
doc?
|
|
|
@ -1 +0,0 @@
|
||||||
Cocoa pods which grow at jungle trees. Does not include cocoa beans.
|
|
|
@ -3,10 +3,7 @@ local S = minetest.get_translator("mcl_cocoas")
|
||||||
mcl_cocoas = {}
|
mcl_cocoas = {}
|
||||||
|
|
||||||
-- Place cocoa
|
-- Place cocoa
|
||||||
function mcl_cocoas.place(itemstack, placer, pointed_thing, plantname)
|
function mcl_cocoas.place(itemstack, placer, pt, plantname)
|
||||||
|
|
||||||
local pt = pointed_thing
|
|
||||||
|
|
||||||
-- check if pointing at a node
|
-- check if pointing at a node
|
||||||
if not pt or pt.type ~= "node" then
|
if not pt or pt.type ~= "node" then
|
||||||
return
|
return
|
||||||
|
|
|
@ -1 +1,4 @@
|
||||||
name = mcl_cocoas
|
name = mcl_cocoas
|
||||||
|
description = Cocoa pods which grow at jungle trees. Does not include cocoa beans.
|
||||||
|
depends = mcl_sounds, mcl_core
|
||||||
|
optional_depends = doc
|
|
@ -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
|
||||||
|
|
|
@ -159,7 +159,7 @@ function mcl_enchanting.combine(itemstack, combine_with)
|
||||||
local itemname = itemstack:get_name()
|
local itemname = itemstack:get_name()
|
||||||
local combine_name = combine_with:get_name()
|
local combine_name = combine_with:get_name()
|
||||||
local enchanted_itemname = mcl_enchanting.get_enchanted_itemstring(itemname)
|
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
|
return false
|
||||||
end
|
end
|
||||||
local enchantments = mcl_enchanting.get_enchantments(itemstack)
|
local enchantments = mcl_enchanting.get_enchantments(itemstack)
|
||||||
|
|
|
@ -1,5 +0,0 @@
|
||||||
mcl_core
|
|
||||||
mcl_worlds
|
|
||||||
mcl_sounds
|
|
||||||
mcl_particles
|
|
||||||
mcl_portals?
|
|
|
@ -1,5 +1,8 @@
|
||||||
local S = minetest.get_translator("mcl_fire")
|
local S = minetest.get_translator("mcl_fire")
|
||||||
|
|
||||||
|
local get_node = minetest.get_node
|
||||||
|
local add_entity = minetest.add_entity
|
||||||
|
|
||||||
-- Fire Charge
|
-- Fire Charge
|
||||||
minetest.register_craftitem("mcl_fire:fire_charge", {
|
minetest.register_craftitem("mcl_fire:fire_charge", {
|
||||||
description = S("Fire Charge"),
|
description = S("Fire Charge"),
|
||||||
|
@ -11,7 +14,7 @@ minetest.register_craftitem("mcl_fire:fire_charge", {
|
||||||
stack_max = 64,
|
stack_max = 64,
|
||||||
on_place = function(itemstack, user, pointed_thing)
|
on_place = function(itemstack, user, pointed_thing)
|
||||||
-- Use pointed node's on_rightclick function first, if present
|
-- 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 user and not user:get_player_control().sneak then
|
||||||
if minetest.registered_nodes[node.name] and minetest.registered_nodes[node.name].on_rightclick 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
|
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)
|
_on_dispense = function(stack, pos, droppos, dropnode, dropdir)
|
||||||
-- Throw fire charge
|
-- Throw fire charge
|
||||||
local shootpos = vector.add(pos, vector.multiply(dropdir, 0.51))
|
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()
|
local ent = fireball:get_luaentity()
|
||||||
ent._shot_from_dispenser = true
|
ent._shot_from_dispenser = true
|
||||||
local v = ent.velocity or 1
|
local v = ent.velocity or 1
|
||||||
|
|
|
@ -1,4 +1,6 @@
|
||||||
local S = minetest.get_translator("mcl_fire")
|
local S = minetest.get_translator("mcl_fire")
|
||||||
|
local get_node = minetest.get_node
|
||||||
|
local add_node = minetest.add_node
|
||||||
|
|
||||||
-- Flint and Steel
|
-- Flint and Steel
|
||||||
minetest.register_tool("mcl_fire: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, },
|
groups = { tool = 1, },
|
||||||
on_place = function(itemstack, user, pointed_thing)
|
on_place = function(itemstack, user, pointed_thing)
|
||||||
-- Use pointed node's on_rightclick function first, if present
|
-- 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 user and not user:get_player_control().sneak then
|
||||||
if minetest.registered_nodes[node.name] and minetest.registered_nodes[node.name].on_rightclick 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
|
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
|
local used = false
|
||||||
if pointed_thing.type == "node" then
|
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
|
if nodedef and nodedef._on_ignite then
|
||||||
local overwrite = nodedef._on_ignite(user, pointed_thing)
|
local overwrite = nodedef._on_ignite(user, pointed_thing)
|
||||||
if not overwrite then
|
if not overwrite then
|
||||||
|
@ -56,7 +58,7 @@ minetest.register_tool("mcl_fire:flint_and_steel", {
|
||||||
_on_dispense = function(stack, pos, droppos, dropnode, dropdir)
|
_on_dispense = function(stack, pos, droppos, dropnode, dropdir)
|
||||||
-- Ignite air
|
-- Ignite air
|
||||||
if dropnode.name == "air" then
|
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
|
if not minetest.is_creative_enabled("") then
|
||||||
stack:add_wear(65535/65) -- 65 uses
|
stack:add_wear(65535/65) -- 65 uses
|
||||||
end
|
end
|
||||||
|
|
|
@ -1,10 +1,29 @@
|
||||||
-- Global namespace for functions
|
-- Global namespace for functions
|
||||||
|
|
||||||
mcl_fire = {}
|
mcl_fire = {}
|
||||||
|
local modpath = minetest.get_modpath(minetest.get_current_modname())
|
||||||
|
|
||||||
local S = minetest.get_translator("mcl_fire")
|
local S = minetest.get_translator("mcl_fire")
|
||||||
local N = function(s) return s end
|
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:
|
-- inverse pyramid pattern above lava source, floor 1 of 2:
|
||||||
local lava_fire=
|
local lava_fire=
|
||||||
{
|
{
|
||||||
|
@ -28,6 +47,71 @@ 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 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)
|
local spawn_smoke = function(pos)
|
||||||
mcl_particles.add_node_particlespawner(pos, {
|
mcl_particles.add_node_particlespawner(pos, {
|
||||||
amount = 0.1,
|
amount = 0.1,
|
||||||
|
@ -48,6 +132,8 @@ local spawn_smoke = function(pos)
|
||||||
length = 2.1,
|
length = 2.1,
|
||||||
},
|
},
|
||||||
}, "high")
|
}, "high")
|
||||||
|
-- ]]
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
||||||
--
|
--
|
||||||
|
@ -90,7 +176,7 @@ local fire_timer = function(pos)
|
||||||
end
|
end
|
||||||
|
|
||||||
local spawn_fire = function(pos, age)
|
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})
|
minetest.check_single_for_falling({x=pos.x, y=pos.y+1, z=pos.z})
|
||||||
end
|
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},
|
groups = {fire = 1, dig_immediate = 3, not_in_creative_inventory = 1, dig_by_piston=1, destroys_items=1, set_on_fire=8},
|
||||||
floodable = true,
|
floodable = true,
|
||||||
on_flood = function(pos, oldnode, newnode)
|
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)
|
minetest.sound_play("fire_extinguish_flame", {pos = pos, gain = 0.25, max_hear_distance = 16}, true)
|
||||||
end
|
end
|
||||||
end,
|
end,
|
||||||
on_timer = function(pos)
|
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.
|
-- Age is a number from 0 to 15 and is increased every timer step.
|
||||||
-- "old" fire is more likely to be extinguished
|
-- "old" fire is more likely to be extinguished
|
||||||
local age = node.param2
|
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 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 = minetest.get_node({x=pos.x, y=pos.z-1, z=pos.z})
|
local below = 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 below_is_flammable = get_item_group(below.name, "flammable") > 0
|
||||||
-- Extinguish fire
|
-- Extinguish fire
|
||||||
if (not fire_enabled) and (math.random(1,3) == 1) then
|
if (not fire_enabled) and (math.random(1,3) == 1) then
|
||||||
minetest.remove_node(pos)
|
remove_node(pos)
|
||||||
return
|
return
|
||||||
end
|
end
|
||||||
if age == 15 and not below_is_flammable then
|
if age == 15 and not below_is_flammable then
|
||||||
minetest.remove_node(pos)
|
remove_node(pos)
|
||||||
return
|
return
|
||||||
elseif age > 3 and #flammables == 0 and not below_is_flammable and math.random(1,4) == 1 then
|
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
|
return
|
||||||
end
|
end
|
||||||
local age_add = 1
|
local age_add = 1
|
||||||
|
@ -149,14 +235,14 @@ minetest.register_node("mcl_fire:fire", {
|
||||||
if (not fire_enabled) then
|
if (not fire_enabled) then
|
||||||
if age + age_add <= 15 then
|
if age + age_add <= 15 then
|
||||||
node.param2 = age + age_add
|
node.param2 = age + age_add
|
||||||
minetest.set_node(pos, node)
|
set_node(pos, node)
|
||||||
end
|
end
|
||||||
-- Restart timer
|
-- Restart timer
|
||||||
fire_timer(pos)
|
fire_timer(pos)
|
||||||
return
|
return
|
||||||
end
|
end
|
||||||
-- Spawn fire to nearby flammable nodes
|
-- 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
|
if is_next_to_flammable and math.random(1,2) == 1 then
|
||||||
-- The fire we spawn copies the age of this fire.
|
-- The fire we spawn copies the age of this fire.
|
||||||
-- This prevents fire from spreading infinitely far as the fire fire dies off
|
-- 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)
|
local burntype = math.random(1,2)
|
||||||
if burntype == 1 then
|
if burntype == 1 then
|
||||||
-- Spawn fire in air
|
-- 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
|
while #nodes > 0 do
|
||||||
local r = math.random(1, #nodes)
|
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)
|
spawn_fire(nodes[r], age_next)
|
||||||
break
|
break
|
||||||
else
|
else
|
||||||
|
@ -178,12 +264,12 @@ minetest.register_node("mcl_fire:fire", {
|
||||||
end
|
end
|
||||||
else
|
else
|
||||||
-- Burn flammable block
|
-- 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
|
if #nodes > 0 then
|
||||||
local r = math.random(1, #nodes)
|
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 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
|
if ndef and ndef._on_burn then
|
||||||
ndef._on_burn(nodes[r])
|
ndef._on_burn(nodes[r])
|
||||||
elseif fgroup ~= -1 then
|
elseif fgroup ~= -1 then
|
||||||
|
@ -195,7 +281,7 @@ minetest.register_node("mcl_fire:fire", {
|
||||||
-- Regular age increase
|
-- Regular age increase
|
||||||
if age + age_add <= 15 then
|
if age + age_add <= 15 then
|
||||||
node.param2 = age + age_add
|
node.param2 = age + age_add
|
||||||
minetest.set_node(pos, node)
|
set_node(pos, node)
|
||||||
end
|
end
|
||||||
-- Restart timer
|
-- Restart timer
|
||||||
fire_timer(pos)
|
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
|
-- Turn into eternal fire on special blocks, light Nether portal (if possible), start burning timer
|
||||||
on_construct = function(pos)
|
on_construct = function(pos)
|
||||||
local bpos = {x=pos.x, y=pos.y-1, z=pos.z}
|
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)
|
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
|
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
|
end
|
||||||
|
|
||||||
if minetest.get_modpath("mcl_portals") then
|
if has_mcl_portals then
|
||||||
mcl_portals.light_nether_portal(pos)
|
mcl_portals.light_nether_portal(pos)
|
||||||
end
|
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},
|
groups = {fire = 1, dig_immediate = 3, not_in_creative_inventory = 1, dig_by_piston = 1, destroys_items = 1, set_on_fire=8},
|
||||||
floodable = true,
|
floodable = true,
|
||||||
on_flood = function(pos, oldnode, newnode)
|
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)
|
minetest.sound_play("fire_extinguish_flame", {pos = pos, gain = 0.25, max_hear_distance = 16}, true)
|
||||||
end
|
end
|
||||||
end,
|
end,
|
||||||
on_timer = function(pos)
|
on_timer = function(pos)
|
||||||
if fire_enabled then
|
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
|
while #airs > 0 do
|
||||||
local r = math.random(1, #airs)
|
local r = math.random(1, #airs)
|
||||||
if minetest.find_node_near(airs[r], 1, {"group:flammable"}) then
|
if find_node_near(airs[r], 1, {"group:flammable"}) then
|
||||||
local node = minetest.get_node(airs[r])
|
local node = get_node(airs[r])
|
||||||
local age = node.param2
|
local age = node.param2
|
||||||
local age_next = math.min(15, age + math.random(0, 1))
|
local age_next = math.min(15, age + math.random(0, 1))
|
||||||
spawn_fire(airs[r], age_next)
|
spawn_fire(airs[r], age_next)
|
||||||
|
@ -278,7 +364,7 @@ minetest.register_node("mcl_fire:eternal_fire", {
|
||||||
on_construct = function(pos)
|
on_construct = function(pos)
|
||||||
fire_timer(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)
|
mcl_portals.light_nether_portal(pos)
|
||||||
end
|
end
|
||||||
spawn_smoke(pos)
|
spawn_smoke(pos)
|
||||||
|
@ -313,7 +399,7 @@ if flame_sound then
|
||||||
local ppos = player:get_pos()
|
local ppos = player:get_pos()
|
||||||
local areamin = vector.subtract(ppos, radius)
|
local areamin = vector.subtract(ppos, radius)
|
||||||
local areamax = vector.add(ppos, radius)
|
local areamax = vector.add(ppos, radius)
|
||||||
local fpos, num = minetest.find_nodes_in_area(
|
local fpos, num = find_nodes_in_area(
|
||||||
areamin,
|
areamin,
|
||||||
areamax,
|
areamax,
|
||||||
{"mcl_fire:fire", "mcl_fire:eternal_fire"}
|
{"mcl_fire:fire", "mcl_fire:eternal_fire"}
|
||||||
|
@ -384,7 +470,7 @@ if flame_sound then
|
||||||
end
|
end
|
||||||
|
|
||||||
timer = 0
|
timer = 0
|
||||||
local players = minetest.get_connected_players()
|
local players = get_connected_players()
|
||||||
for n = 1, #players do
|
for n = 1, #players do
|
||||||
mcl_fire.update_player_sound(players[n])
|
mcl_fire.update_player_sound(players[n])
|
||||||
end
|
end
|
||||||
|
@ -416,7 +502,7 @@ minetest.register_abm({
|
||||||
chance = 1,
|
chance = 1,
|
||||||
catch_up = false,
|
catch_up = false,
|
||||||
action = function(pos, node, active_object_count, active_object_count_wider)
|
action = function(pos, node, active_object_count, active_object_count_wider)
|
||||||
minetest.remove_node(pos)
|
remove_node(pos)
|
||||||
minetest.sound_play("fire_extinguish_flame",
|
minetest.sound_play("fire_extinguish_flame",
|
||||||
{pos = pos, max_hear_distance = 16, gain = 0.15}, true)
|
{pos = pos, max_hear_distance = 16, gain = 0.15}, true)
|
||||||
end,
|
end,
|
||||||
|
@ -429,8 +515,8 @@ local function has_flammable(pos)
|
||||||
local npos, node
|
local npos, node
|
||||||
for n, v in ipairs(alldirs) do
|
for n, v in ipairs(alldirs) do
|
||||||
npos = vector.add(pos, v)
|
npos = vector.add(pos, v)
|
||||||
node = minetest.get_node_or_nil(npos)
|
node = get_node_or_nil(npos)
|
||||||
if node and node.name and minetest.get_item_group(node.name, "flammable") ~= 0 then
|
if node and node.name and get_item_group(node.name, "flammable") ~= 0 then
|
||||||
return npos
|
return npos
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
@ -447,7 +533,7 @@ if not fire_enabled then
|
||||||
interval = 10,
|
interval = 10,
|
||||||
chance = 10,
|
chance = 10,
|
||||||
catch_up = false,
|
catch_up = false,
|
||||||
action = minetest.remove_node,
|
action = remove_node,
|
||||||
})
|
})
|
||||||
|
|
||||||
else -- Fire enabled
|
else -- Fire enabled
|
||||||
|
@ -465,12 +551,12 @@ else -- Fire enabled
|
||||||
i = math.random(1,9)
|
i = math.random(1,9)
|
||||||
dir = lava_fire[i]
|
dir = lava_fire[i]
|
||||||
target = {x=pos.x+dir.x, y=pos.y+dir.y, z=pos.z+dir.z}
|
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
|
if not node or node.name ~= "air" then
|
||||||
i = ((i + math.random(0,7)) % 9) + 1
|
i = ((i + math.random(0,7)) % 9) + 1
|
||||||
dir = lava_fire[i]
|
dir = lava_fire[i]
|
||||||
target = {x=pos.x+dir.x, y=pos.y+dir.y, z=pos.z+dir.z}
|
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
|
if not node or node.name ~= "air" then
|
||||||
return
|
return
|
||||||
end
|
end
|
||||||
|
@ -480,7 +566,7 @@ else -- Fire enabled
|
||||||
local dir2, target2, node2
|
local dir2, target2, node2
|
||||||
dir2 = lava_fire[i2]
|
dir2 = lava_fire[i2]
|
||||||
target2 = {x=target.x+dir2.x, y=target.y+dir2.y, z=target.z+dir2.z}
|
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
|
if node2 and node2.name == "air" then
|
||||||
f = has_flammable(target2)
|
f = has_flammable(target2)
|
||||||
if f then
|
if f then
|
||||||
|
@ -521,9 +607,9 @@ mcl_fire.set_fire = function(pointed_thing, player, allow_on_fire)
|
||||||
else
|
else
|
||||||
pname = player:get_player_name()
|
pname = player:get_player_name()
|
||||||
end
|
end
|
||||||
local n = minetest.get_node(pointed_thing.above)
|
local n = get_node(pointed_thing.above)
|
||||||
local nu = minetest.get_node(pointed_thing.under)
|
local nu = get_node(pointed_thing.under)
|
||||||
if allow_on_fire == false and minetest.get_item_group(nu.name, "fire") ~= 0 then
|
if allow_on_fire == false and get_item_group(nu.name, "fire") ~= 0 then
|
||||||
return
|
return
|
||||||
end
|
end
|
||||||
if minetest.is_protected(pointed_thing.above, pname) then
|
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
|
return
|
||||||
end
|
end
|
||||||
if n.name == "air" then
|
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
|
||||||
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:basic_flame", "mcl_fire:fire")
|
||||||
minetest.register_alias("fire:permanent_flame", "mcl_fire:eternal_fire")
|
minetest.register_alias("fire:permanent_flame", "mcl_fire:eternal_fire")
|
||||||
|
|
||||||
dofile(minetest.get_modpath(minetest.get_current_modname()).."/flint_and_steel.lua")
|
dofile(modpath.."/flint_and_steel.lua")
|
||||||
dofile(minetest.get_modpath(minetest.get_current_modname()).."/fire_charge.lua")
|
dofile(modpath.."/fire_charge.lua")
|
||||||
|
|
|
@ -1 +1,3 @@
|
||||||
name = mcl_fire
|
name = mcl_fire
|
||||||
|
depends = mcl_core, mcl_worlds, mcl_sounds, mcl_particles
|
||||||
|
optional_depends = mcl_portals
|
|
@ -234,3 +234,13 @@ mcl_jukebox.register_record("Credit Roll (Jordach's HD Mix)", "Junichi Masuda",
|
||||||
mcl_jukebox.register_record("Winter Feeling", "Tom Peter", "strad", "mcl_jukebox_record_strad.png", "mcl_jukebox_track_6")
|
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("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")
|
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")
|
|
@ -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,
|
||||||
|
@ -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.
|
||||||
|
|
|
@ -1,2 +0,0 @@
|
||||||
mcl_core
|
|
||||||
doc?
|
|
|
@ -1 +0,0 @@
|
||||||
Core items not found in Minecraft
|
|
|
@ -1 +1,4 @@
|
||||||
name = mclx_core
|
name = mclx_core
|
||||||
|
description = Core items not found in Minecraft
|
||||||
|
depends = mcl_core
|
||||||
|
optional_depends = doc
|
||||||
|
|
|
@ -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)
|
||||||
|
|
|
@ -1,5 +1,21 @@
|
||||||
local S = minetest.get_translator("mcl_playerplus")
|
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
|
-- Internal player state
|
||||||
local mcl_playerplus_internal = {}
|
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.
|
-- 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.
|
-- 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()
|
local controls = player:get_player_control()
|
||||||
name = player:get_player_name()
|
name = player:get_player_name()
|
||||||
|
|
||||||
|
@ -37,10 +53,10 @@ minetest.register_globalstep(function(dtime)
|
||||||
|
|
||||||
local player_vel_yaw = 0
|
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
|
yaw = 0
|
||||||
else
|
else
|
||||||
player_vel_yaw = degrees(minetest.dir_to_yaw(player_velocity))
|
player_vel_yaw = degrees(dir_to_yaw(player_velocity))
|
||||||
end
|
end
|
||||||
|
|
||||||
-- controls right and left arms pitch when shooting a bow or punching
|
-- 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 }})
|
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
|
-- sneaking body conrols
|
||||||
player:set_bone_position("Body_Control", vector.new(0,6.3,0), vector.new(0,0,0))
|
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
|
-- set head pitch and yaw when swimming
|
||||||
player:set_bone_position("Head", vector.new(0,6.3,0), vector.new(pitch+90-degrees(dir_to_pitch(player_velocity)),yaw - player_vel_yaw * -1,0))
|
player:set_bone_position("Head", vector.new(0,6.3,0), vector.new(pitch+90-degrees(dir_to_pitch(player_velocity)),yaw - player_vel_yaw * -1,0))
|
||||||
-- sets eye height, and nametag color accordingly
|
-- sets eye height, and nametag color accordingly
|
||||||
|
@ -127,18 +143,18 @@ minetest.register_globalstep(function(dtime)
|
||||||
as of 0.4.15.
|
as of 0.4.15.
|
||||||
]]
|
]]
|
||||||
|
|
||||||
if minetest.get_item_group(node_feet, "liquid") == 0 and
|
if get_item_group(node_feet, "liquid") == 0 and
|
||||||
minetest.get_item_group(node_stand, "liquid") == 0 and
|
get_item_group(node_stand, "liquid") == 0 and
|
||||||
not minetest.registered_nodes[node_feet].climbable and
|
not minetest.registered_nodes[node_feet].climbable and
|
||||||
not minetest.registered_nodes[node_stand].climbable and
|
not minetest.registered_nodes[node_stand].climbable and
|
||||||
(minetest.registered_nodes[node_stand].walkable or minetest.registered_nodes[node_stand_below].walkable)
|
(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 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_below, "disable_jump") == 0 then
|
||||||
-- Cause exhaustion for jumping
|
-- Cause exhaustion for jumping
|
||||||
if mcl_sprint.is_sprinting(name) then
|
if is_sprinting(name) then
|
||||||
mcl_hunger.exhaust(name, mcl_hunger.EXHAUST_SPRINT_JUMP)
|
exhaust(name, mcl_hunger.EXHAUST_SPRINT_JUMP)
|
||||||
else
|
else
|
||||||
mcl_hunger.exhaust(name, mcl_hunger.EXHAUST_JUMP)
|
exhaust(name, mcl_hunger.EXHAUST_JUMP)
|
||||||
end
|
end
|
||||||
|
|
||||||
-- Reset cooldown timer
|
-- Reset cooldown timer
|
||||||
|
@ -157,7 +173,7 @@ minetest.register_globalstep(function(dtime)
|
||||||
time = 0
|
time = 0
|
||||||
|
|
||||||
-- check players
|
-- check players
|
||||||
for _,player in ipairs(minetest.get_connected_players()) do
|
for _,player in ipairs(get_connected_players()) do
|
||||||
-- who am I?
|
-- who am I?
|
||||||
local name = player:get_player_name()
|
local name = player:get_player_name()
|
||||||
|
|
||||||
|
@ -198,7 +214,7 @@ minetest.register_globalstep(function(dtime)
|
||||||
end
|
end
|
||||||
|
|
||||||
-- Swimming? Check if boots are enchanted with depth strider
|
-- 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 boots = player:get_inventory():get_stack("armor", 5)
|
||||||
local depth_strider = mcl_enchanting.get_enchantment(boots, "depth_strider")
|
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 (ndef.groups.opaque == 1)
|
||||||
and (node_head ~= "ignore")
|
and (node_head ~= "ignore")
|
||||||
-- Check privilege, too
|
-- 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
|
if player:get_hp() > 0 then
|
||||||
mcl_death_messages.player_damage(player, S("@1 suffocated to death.", name))
|
mcl_death_messages.player_damage(player, S("@1 suffocated to death.", name))
|
||||||
player:set_hp(player:get_hp() - 1)
|
player:set_hp(player:get_hp() - 1)
|
||||||
|
@ -228,9 +244,9 @@ minetest.register_globalstep(function(dtime)
|
||||||
end
|
end
|
||||||
|
|
||||||
-- Am I near a cactus?
|
-- 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
|
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
|
end
|
||||||
if near then
|
if near then
|
||||||
-- Am I touching the cactus? If so, it hurts
|
-- Am I touching the cactus? If so, it hurts
|
||||||
|
@ -247,15 +263,15 @@ minetest.register_globalstep(function(dtime)
|
||||||
--[[ Swimming: Cause exhaustion.
|
--[[ Swimming: Cause exhaustion.
|
||||||
NOTE: As of 0.4.15, it only counts as swimming when you are with the feet inside the liquid!
|
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. ]]
|
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
|
if not player:get_attach() and (get_item_group(node_feet, "liquid") ~= 0 or
|
||||||
minetest.get_item_group(node_stand, "liquid") ~= 0) then
|
get_item_group(node_stand, "liquid") ~= 0) then
|
||||||
local lastPos = mcl_playerplus_internal[name].lastPos
|
local lastPos = mcl_playerplus_internal[name].lastPos
|
||||||
if lastPos then
|
if lastPos then
|
||||||
local dist = vector.distance(lastPos, pos)
|
local dist = vector.distance(lastPos, pos)
|
||||||
mcl_playerplus_internal[name].swimDistance = mcl_playerplus_internal[name].swimDistance + dist
|
mcl_playerplus_internal[name].swimDistance = mcl_playerplus_internal[name].swimDistance + dist
|
||||||
if mcl_playerplus_internal[name].swimDistance >= 1 then
|
if mcl_playerplus_internal[name].swimDistance >= 1 then
|
||||||
local superficial = math.floor(mcl_playerplus_internal[name].swimDistance)
|
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
|
mcl_playerplus_internal[name].swimDistance = mcl_playerplus_internal[name].swimDistance - superficial
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
@ -263,9 +279,8 @@ minetest.register_globalstep(function(dtime)
|
||||||
end
|
end
|
||||||
|
|
||||||
-- Underwater: Spawn bubble particles
|
-- Underwater: Spawn bubble particles
|
||||||
if minetest.get_item_group(node_head, "water") ~= 0 then
|
if get_item_group(node_head, "water") ~= 0 then
|
||||||
|
add_particlespawner({
|
||||||
minetest.add_particlespawner({
|
|
||||||
amount = 10,
|
amount = 10,
|
||||||
time = 0.15,
|
time = 0.15,
|
||||||
minpos = { x = -0.25, y = 0.3, z = -0.25 },
|
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
|
if wi == "mcl_core:barrier" or wi == "mcl_core:realm_barrier" then
|
||||||
local pos = vector.round(player:get_pos())
|
local pos = vector.round(player:get_pos())
|
||||||
local r = 8
|
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 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{
|
local area = VoxelArea:new{
|
||||||
MinEdge = emin,
|
MinEdge = emin,
|
||||||
|
@ -299,7 +314,7 @@ minetest.register_globalstep(function(dtime)
|
||||||
for y=pos.y-r, pos.y+r do
|
for y=pos.y-r, pos.y+r do
|
||||||
for z=pos.z-r, pos.z+r do
|
for z=pos.z-r, pos.z+r do
|
||||||
local vi = area:indexp({x=x, y=y, z=z})
|
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
|
local tex
|
||||||
if nodename == "mcl_core:barrier" then
|
if nodename == "mcl_core:barrier" then
|
||||||
tex = "mcl_core_barrier.png"
|
tex = "mcl_core_barrier.png"
|
||||||
|
@ -307,7 +322,7 @@ minetest.register_globalstep(function(dtime)
|
||||||
tex = "mcl_core_barrier.png^[colorize:#FF00FF:127^[transformFX"
|
tex = "mcl_core_barrier.png^[colorize:#FF00FF:127^[transformFX"
|
||||||
end
|
end
|
||||||
if tex then
|
if tex then
|
||||||
minetest.add_particle({
|
add_particle({
|
||||||
pos = {x=x, y=y, z=z},
|
pos = {x=x, y=y, z=z},
|
||||||
expirationtime = 1,
|
expirationtime = 1,
|
||||||
size = 8,
|
size = 8,
|
||||||
|
|
|
@ -50,17 +50,28 @@ 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 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
|
if sprinting == true then
|
||||||
players[playerName].fov = math.min(players[playerName].fov + 0.05, 1.2)
|
players[playerName].fov = math.min(players[playerName].fov + 0.05, 1.2)
|
||||||
player:set_fov(players[playerName].fov, true, 0.15)
|
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)
|
playerphysics.add_physics_factor(player, "speed", "mcl_sprint:sprint", mcl_sprint.SPEED)
|
||||||
elseif sprinting == false then
|
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)
|
||||||
|
if sprinting == false then
|
||||||
playerphysics.remove_physics_factor(player, "speed", "mcl_sprint:sprint")
|
playerphysics.remove_physics_factor(player, "speed", "mcl_sprint:sprint")
|
||||||
end
|
end
|
||||||
|
end
|
||||||
return true
|
return true
|
||||||
end
|
end
|
||||||
return false
|
return false
|
||||||
|
|