Merge branch 'master' into api-cauldrons

This commit is contained in:
AFCMS 2021-05-27 09:10:19 +02:00
commit 1b0b5fc733
180 changed files with 2276 additions and 2470 deletions

View File

@ -40,4 +40,16 @@ read_globals = {
"factorial" "factorial"
} }
}, },
------
--MODS
------
--GENERAL
"default",
--ENTITIES
"cmi",
--HUD
"sfinv", "sfinv_buttons", "unified_inventory", "cmsg", "inventory_plus",
} }

View File

@ -1,5 +1,5 @@
# Contributing to MineClone 2 # Contributing to MineClone 2
So you want to MineClone 2? So you want to contribute to MineClone 2?
Wow, thank you! :-) Wow, thank you! :-)
But first, some things to note: But first, some things to note:
@ -46,6 +46,28 @@ Your commit names should be relatively descriptive, e.g. when saying "Fix #issue
Contributors will be credited in `CREDITS.md`. Contributors will be credited in `CREDITS.md`.
## Code Style
Each mod must provide `mod.conf`.
Each mod which add API functions should store functions inside a global table named like the mod.
Public functions should not use self references but rather just access the table directly.
Functions should be defined in this way:
```
function mcl_xyz.stuff(param) end
```
Insteed of this way:
```
mcl_xyz.stuff = function(param) end
```
Indentation must be unified, more likely with tabs.
Time sensitive mods should make a local copy of most used API functions to improve performances.
```
local vector = vector
local get_node = minetest.get_node
```
## Features > 1.12 ## Features > 1.12
If you want to make a feature that was added in a Minecraft version later than 1.12, you should fork MineClone5 (mineclone5 branch in the repository) and add your changes to this. If you want to make a feature that was added in a Minecraft version later than 1.12, you should fork MineClone5 (mineclone5 branch in the repository) and add your changes to this.

BIN
menu/Header.blend Normal file

Binary file not shown.

View File

@ -121,7 +121,7 @@ local hardness_values = get_hardness_values_for_groups()
-- hardness_value. Used for quick lookup. -- hardness_value. Used for quick lookup.
local hardness_lookup = get_hardness_lookup_for_groups(hardness_values) local hardness_lookup = get_hardness_lookup_for_groups(hardness_values)
local function compute_creativetimes(group) --[[local function compute_creativetimes(group)
local creativetimes = {} local creativetimes = {}
for index, hardness in pairs(hardness_values[group]) do for index, hardness in pairs(hardness_values[group]) do
@ -129,7 +129,7 @@ local function compute_creativetimes(group)
end end
return creativetimes return creativetimes
end end]]
-- Get the list of digging times for using a specific tool on a specific -- Get the list of digging times for using a specific tool on a specific
-- diggroup. -- diggroup.
@ -239,13 +239,13 @@ function mcl_autogroup.can_harvest(nodename, toolname)
end end
-- Get one groupcap field for using a specific tool on a specific group. -- Get one groupcap field for using a specific tool on a specific group.
local function get_groupcap(group, can_harvest, multiplier, efficiency, uses) --[[local function get_groupcap(group, can_harvest, multiplier, efficiency, uses)
return { return {
times = get_digtimes(group, can_harvest, multiplier, efficiency), times = get_digtimes(group, can_harvest, multiplier, efficiency),
uses = uses, uses = uses,
maxlevel = 0, maxlevel = 0,
} }
end end]]
-- Returns the tool_capabilities from a tool definition or a default set of -- Returns the tool_capabilities from a tool definition or a default set of
-- tool_capabilities -- tool_capabilities
@ -271,7 +271,7 @@ end
-- toolname - Name of the tool being enchanted (like "mcl_tools:diamond_pickaxe") -- toolname - Name of the tool being enchanted (like "mcl_tools:diamond_pickaxe")
-- efficiency - The efficiency level the tool is enchanted with (default 0) -- efficiency - The efficiency level the tool is enchanted with (default 0)
-- --
-- NOTE: -- NOTE:
-- This function can only be called after mod initialization. Otherwise a mod -- This function can only be called after mod initialization. Otherwise a mod
-- would have to add _mcl_autogroup as a dependency which would break the mod -- would have to add _mcl_autogroup as a dependency which would break the mod
-- loading order. -- loading order.
@ -288,7 +288,7 @@ end
-- toolname - Name of the tool used -- toolname - Name of the tool used
-- diggroup - The name of the diggroup the tool is used on -- diggroup - The name of the diggroup the tool is used on
-- --
-- NOTE: -- NOTE:
-- This function can only be called after mod initialization. Otherwise a mod -- This function can only be called after mod initialization. Otherwise a mod
-- would have to add _mcl_autogroup as a dependency which would break the mod -- would have to add _mcl_autogroup as a dependency which would break the mod
-- loading order. -- loading order.
@ -298,7 +298,7 @@ function mcl_autogroup.get_wear(toolname, diggroup)
return math.ceil(65535 / uses) return math.ceil(65535 / uses)
end end
local overwrite = function() local function overwrite()
for nname, ndef in pairs(minetest.registered_nodes) do for nname, ndef in pairs(minetest.registered_nodes) do
local newgroups = table.copy(ndef.groups) local newgroups = table.copy(ndef.groups)
if (nname ~= "ignore" and ndef.diggable) then if (nname ~= "ignore" and ndef.diggable) then
@ -315,12 +315,12 @@ local overwrite = function()
newgroups.opaque = 1 newgroups.opaque = 1
end end
local creative_breakable = false --local creative_breakable = false
-- Assign groups used for digging this node depending on -- Assign groups used for digging this node depending on
-- the registered digging groups -- the registered digging groups
for g, gdef in pairs(mcl_autogroup.registered_diggroups) do for g, gdef in pairs(mcl_autogroup.registered_diggroups) do
creative_breakable = true --creative_breakable = true
local index = hardness_lookup[g][ndef._mcl_hardness or 0] local index = hardness_lookup[g][ndef._mcl_hardness or 0]
if ndef.groups[g] then if ndef.groups[g] then
if gdef.levels then if gdef.levels then

View File

@ -81,11 +81,11 @@ if v6_use_snow_biomes then
end end
local v6_freq_desert = tonumber(minetest.get_mapgen_setting("mgv6_freq_desert") or 0.45) local v6_freq_desert = tonumber(minetest.get_mapgen_setting("mgv6_freq_desert") or 0.45)
local NOISE_MAGIC_X = 1619 --local NOISE_MAGIC_X = 1619
local NOISE_MAGIC_Y = 31337 --local NOISE_MAGIC_Y = 31337
local NOISE_MAGIC_Z = 52591 --local NOISE_MAGIC_Z = 52591
local NOISE_MAGIC_SEED = 1013 --local NOISE_MAGIC_SEED = 1013
local noise2d = function(x, y, seed) local function noise2d(x, y, seed)
-- TODO: implement noise2d function for biome blend -- TODO: implement noise2d function for biome blend
return 0 return 0
--[[ --[[

View File

@ -1,95 +1,100 @@
local math = math
local get_node = minetest.get_node
local get_item_group = minetest.get_item_group
local registered_nodes = minetest.registered_nodes
flowlib = {} flowlib = {}
--sum of direction vectors must match an array index --sum of direction vectors must match an array index
--(sum,root)
--(0,1), (1,1+0=1), (2,1+1=2), (3,1+2^2=5), (4,2^2+2^2=8)
local inv_roots = {
[0] = 1,
[1] = 1,
[2] = 0.70710678118655,
[4] = 0.5,
[5] = 0.44721359549996,
[8] = 0.35355339059327,
}
local function to_unit_vector(dir_vector) local function to_unit_vector(dir_vector)
--(sum,root) local sum = dir_vector.x * dir_vector.x + dir_vector.z * dir_vector.z
-- (0,1), (1,1+0=1), (2,1+1=2), (3,1+2^2=5), (4,2^2+2^2=8) return {x = dir_vector.x * inv_roots[sum], y = dir_vector.y, z = dir_vector.z * inv_roots[sum]}
local inv_roots = {[0] = 1, [1] = 1, [2] = 0.70710678118655, [4] = 0.5
, [5] = 0.44721359549996, [8] = 0.35355339059327}
local sum = dir_vector.x*dir_vector.x + dir_vector.z*dir_vector.z
return {x=dir_vector.x*inv_roots[sum],y=dir_vector.y
,z=dir_vector.z*inv_roots[sum]}
end end
local is_touching = function(realpos,nodepos,radius) local function is_touching(realpos,nodepos,radius)
local boarder = 0.5 - radius local boarder = 0.5 - radius
return (math.abs(realpos - nodepos) > (boarder)) return math.abs(realpos - nodepos) > (boarder)
end end
flowlib.is_touching = is_touching flowlib.is_touching = is_touching
local is_water = function(pos) local function is_water(pos)
return (minetest.get_item_group(minetest.get_node( return get_item_group(get_node(pos).name, "water") ~= 0
{x=pos.x,y=pos.y,z=pos.z}).name
, "water") ~= 0)
end end
flowlib.is_water = is_water flowlib.is_water = is_water
local node_is_water = function(node) local function node_is_water(node)
return (minetest.get_item_group(node.name, "water") ~= 0) return get_item_group(node.name, "water") ~= 0
end end
flowlib.node_is_water = node_is_water flowlib.node_is_water = node_is_water
local is_lava = function(pos) local function is_lava(pos)
return (minetest.get_item_group(minetest.get_node( return get_item_group(get_node(pos).name, "lava") ~= 0
{x=pos.x,y=pos.y,z=pos.z}).name
, "lava") ~= 0)
end end
flowlib.is_lava = is_lava flowlib.is_lava = is_lava
local node_is_lava = function(node) local function node_is_lava(node)
return (minetest.get_item_group(node.name, "lava") ~= 0) return get_item_group(node.name, "lava") ~= 0
end end
flowlib.node_is_lava = node_is_lava flowlib.node_is_lava = node_is_lava
local is_liquid = function(pos) local function is_liquid(pos)
return (minetest.get_item_group(minetest.get_node( return get_item_group(get_node(pos).name, "liquid") ~= 0
{x=pos.x,y=pos.y,z=pos.z}).name
, "liquid") ~= 0)
end end
flowlib.is_liquid = is_liquid flowlib.is_liquid = is_liquid
local node_is_liquid = function(node) local function node_is_liquid(node)
return (minetest.get_item_group(node.name, "liquid") ~= 0) return minetest.get_item_group(node.name, "liquid") ~= 0
end end
flowlib.node_is_liquid = node_is_liquid flowlib.node_is_liquid = node_is_liquid
--This code is more efficient --This code is more efficient
local function quick_flow_logic(node,pos_testing,direction) local function quick_flow_logic(node, pos_testing, direction)
local name = node.name local name = node.name
if not minetest.registered_nodes[name] then if not registered_nodes[name] then
return 0 return 0
end end
if minetest.registered_nodes[name].liquidtype == "source" then if registered_nodes[name].liquidtype == "source" then
local node_testing = minetest.get_node(pos_testing) local node_testing = get_node(pos_testing)
local param2_testing = node_testing.param2 if not registered_nodes[node_testing.name] then
if not minetest.registered_nodes[node_testing.name] then
return 0 return 0
end end
if minetest.registered_nodes[node_testing.name].liquidtype if registered_nodes[node_testing.name].liquidtype ~= "flowing" then
~= "flowing" then
return 0 return 0
else else
return direction return direction
end end
elseif minetest.registered_nodes[name].liquidtype == "flowing" then elseif registered_nodes[name].liquidtype == "flowing" then
local node_testing = minetest.get_node(pos_testing) local node_testing = get_node(pos_testing)
local param2_testing = node_testing.param2 local param2_testing = node_testing.param2
if not minetest.registered_nodes[node_testing.name] then if not registered_nodes[node_testing.name] then
return 0 return 0
end end
if minetest.registered_nodes[node_testing.name].liquidtype if registered_nodes[node_testing.name].liquidtype == "source" then
== "source" then
return -direction return -direction
elseif minetest.registered_nodes[node_testing.name].liquidtype elseif registered_nodes[node_testing.name].liquidtype == "flowing" then
== "flowing" then
if param2_testing < node.param2 then if param2_testing < node.param2 then
if (node.param2 - param2_testing) > 6 then if (node.param2 - param2_testing) > 6 then
return -direction return -direction
@ -108,48 +113,41 @@ local function quick_flow_logic(node,pos_testing,direction)
return 0 return 0
end end
local quick_flow = function(pos,node) local function quick_flow(pos, node)
local x = 0
local z = 0
if not node_is_liquid(node) then if not node_is_liquid(node) then
return {x=0,y=0,z=0} return {x = 0, y = 0, z = 0}
end end
local x = quick_flow_logic(node,{x = pos.x-1, y = pos.y, z = pos.z},-1) + quick_flow_logic(node,{x = pos.x+1, y = pos.y, z = pos.z}, 1)
x = x + quick_flow_logic(node,{x=pos.x-1,y=pos.y,z=pos.z},-1) local z = quick_flow_logic(node,{x = pos.x, y = pos.y, z = pos.z-1},-1) + quick_flow_logic(node,{x = pos.x, y = pos.y, z = pos.z+1}, 1)
x = x + quick_flow_logic(node,{x=pos.x+1,y=pos.y,z=pos.z}, 1) return to_unit_vector({x = x, y = 0, z = z})
z = z + quick_flow_logic(node,{x=pos.x,y=pos.y,z=pos.z-1},-1)
z = z + quick_flow_logic(node,{x=pos.x,y=pos.y,z=pos.z+1}, 1)
return to_unit_vector({x=x,y=0,z=z})
end end
flowlib.quick_flow = quick_flow flowlib.quick_flow = quick_flow
--if not in water but touching, move centre to touching block
--x has higher precedence than z
--if pos changes with x, it affects z
--if not in water but touching, move centre to touching block local function move_centre(pos, realpos, node, radius)
--x has higher precedence than z if is_touching(realpos.x, pos.x, radius) then
--if pos changes with x, it affects z if is_liquid({x = pos.x-1, y = pos.y, z = pos.z}) then
local move_centre = function(pos,realpos,node,radius) node = get_node({x=pos.x-1, y = pos.y, z = pos.z})
if is_touching(realpos.x,pos.x,radius) then pos = {x = pos.x-1, y = pos.y, z = pos.z}
if is_liquid({x=pos.x-1,y=pos.y,z=pos.z}) then elseif is_liquid({x = pos.x+1, y = pos.y, z = pos.z}) then
node = minetest.get_node({x=pos.x-1,y=pos.y,z=pos.z}) node = get_node({x = pos.x+1, y = pos.y, z = pos.z})
pos = {x=pos.x-1,y=pos.y,z=pos.z} pos = {x = pos.x+1, y = pos.y, z = pos.z}
elseif is_liquid({x=pos.x+1,y=pos.y,z=pos.z}) then
node = minetest.get_node({x=pos.x+1,y=pos.y,z=pos.z})
pos = {x=pos.x+1,y=pos.y,z=pos.z}
end end
end end
if is_touching(realpos.z,pos.z,radius) then if is_touching(realpos.z, pos.z, radius) then
if is_liquid({x=pos.x,y=pos.y,z=pos.z-1}) then if is_liquid({x = pos.x, y = pos.y, z = pos.z - 1}) then
node = minetest.get_node({x=pos.x,y=pos.y,z=pos.z-1}) node = get_node({x = pos.x, y = pos.y, z = pos.z - 1})
pos = {x=pos.x,y=pos.y,z=pos.z-1} pos = {x = pos.x, y = pos.y, z = pos.z - 1}
elseif is_liquid({x=pos.x,y=pos.y,z=pos.z+1}) then elseif is_liquid({x = pos.x, y = pos.y, z = pos.z + 1}) then
node = minetest.get_node({x=pos.x,y=pos.y,z=pos.z+1}) node = get_node({x = pos.x, y = pos.y, z = pos.z + 1})
pos = {x=pos.x,y=pos.y,z=pos.z+1} pos = {x = pos.x, y = pos.y, z = pos.z + 1}
end end
end end
return pos,node return pos, node
end end
flowlib.move_centre = move_centre flowlib.move_centre = move_centre

View File

@ -1,17 +1,21 @@
local vector = vector
local facedir_to_dir = minetest.facedir_to_dir
local get_item_group = minetest.get_item_group
local remove_node = minetest.remove_node
local get_node = minetest.get_node
local original_function = minetest.check_single_for_falling local original_function = minetest.check_single_for_falling
minetest.check_single_for_falling = function(pos) function minetest.check_single_for_falling(pos)
local ret_o = original_function(pos) local ret_o = original_function(pos)
local ret = false local ret = false
local node = minetest.get_node(pos) local node = minetest.get_node(pos)
if minetest.get_item_group(node.name, "attached_node_facedir") ~= 0 then if get_item_group(node.name, "attached_node_facedir") ~= 0 then
local dir = minetest.facedir_to_dir(node.param2) local dir = facedir_to_dir(node.param2)
if dir then if dir then
local cpos = vector.add(pos, dir) if get_item_group(get_node(vector.add(pos, dir)).name, "solid") == 0 then
local cnode = minetest.get_node(cpos) remove_node(pos)
if minetest.get_item_group(cnode.name, "solid") == 0 then
minetest.remove_node(pos)
local drops = minetest.get_node_drops(node.name, "") local drops = minetest.get_node_drops(node.name, "")
for dr=1, #drops do for dr=1, #drops do
minetest.add_item(pos, drops[dr]) minetest.add_item(pos, drops[dr])
@ -20,7 +24,6 @@ minetest.check_single_for_falling = function(pos)
end end
end end
end end
return ret_o or ret return ret_o or ret
end end

View File

@ -13,9 +13,7 @@ under the LGPLv2.1 license.
mcl_explosions = {} mcl_explosions = {}
local mod_fire = minetest.get_modpath("mcl_fire") ~= nil local mod_fire = minetest.get_modpath("mcl_fire") ~= nil
local CONTENT_FIRE = minetest.get_content_id("mcl_fire:fire") --local CONTENT_FIRE = minetest.get_content_id("mcl_fire:fire")
local S = minetest.get_translator("mcl_explosions")
local hash_node_position = minetest.hash_node_position local hash_node_position = minetest.hash_node_position
local get_objects_inside_radius = minetest.get_objects_inside_radius local get_objects_inside_radius = minetest.get_objects_inside_radius
@ -174,14 +172,11 @@ local function trace_explode(pos, strength, raydirs, radius, info, direct, sourc
local ystride = (emax.x - emin_x + 1) local ystride = (emax.x - emin_x + 1)
local zstride = ystride * (emax.y - emin_y + 1) local zstride = ystride * (emax.y - emin_y + 1)
local pos_x = pos.x
local pos_y = pos.y
local pos_z = pos.z
local area = VoxelArea:new { --[[local area = VoxelArea:new {
MinEdge = emin, MinEdge = emin,
MaxEdge = emax MaxEdge = emax
} }]]
local data = vm:get_data() local data = vm:get_data()
local destroy = {} local destroy = {}

View File

@ -1,2 +0,0 @@
# textdomain:mcl_explosions
@1 was caught in an explosion.=@1 wurde Opfer einer Explosion.

View File

@ -1,2 +0,0 @@
# textdomain:mcl_explosions
@1 was caught in an explosion.=@1 a été pris dans une explosion.

View File

@ -1,2 +0,0 @@
# textdomain:mcl_explosions
@1 was caught in an explosion.=@1 не удалось пережить взрыва.

View File

@ -1,2 +0,0 @@
# textdomain:mcl_explosions
@1 was caught in an explosion.=

View File

@ -40,10 +40,9 @@ function mcl_loot.get_loot(loot_definitions, pr)
total_weight = total_weight + (loot_definitions.items[i].weight or 1) total_weight = total_weight + (loot_definitions.items[i].weight or 1)
end end
local stacks_min = loot_definitions.stacks_min --local stacks_min = loot_definitions.stacks_min or 1
local stacks_max = loot_definitions.stacks_max --local stacks_max = loot_definitions.stacks_max or 1
if not stacks_min then stacks_min = 1 end
if not stacks_max then stacks_max = 1 end
local stacks = pr:next(loot_definitions.stacks_min, loot_definitions.stacks_max) local stacks = pr:next(loot_definitions.stacks_min, loot_definitions.stacks_max)
for s=1, stacks do for s=1, stacks do
local r = pr:next(1, total_weight) local r = pr:next(1, total_weight)

View File

@ -1,3 +1,12 @@
local vector = vector
local table = table
local hash_node_position = minetest.hash_node_position
local add_particlespawner = minetest.add_particlespawner
local delete_particlespawner = minetest.delete_particlespawner
local ipairs = ipairs
mcl_particles = {} mcl_particles = {}
-- Table of particlespawner IDs on a per-node hash basis -- Table of particlespawner IDs on a per-node hash basis
@ -32,11 +41,11 @@ function mcl_particles.add_node_particlespawner(pos, particlespawner_definition,
if allowed_level == 0 or levels[level] > allowed_level then if allowed_level == 0 or levels[level] > allowed_level then
return return
end end
local poshash = minetest.hash_node_position(pos) local poshash = hash_node_position(pos)
if not poshash then if not poshash then
return return
end end
local id = minetest.add_particlespawner(particlespawner_definition) local id = add_particlespawner(particlespawner_definition)
if id == -1 then if id == -1 then
return return
end end
@ -47,6 +56,8 @@ function mcl_particles.add_node_particlespawner(pos, particlespawner_definition,
return id return id
end end
local add_node_particlespawner = mcl_particles.add_node_particlespawner
-- Deletes all particlespawners that are assigned to a node position. -- Deletes all particlespawners that are assigned to a node position.
-- If no particlespawners exist for this position, nothing happens. -- If no particlespawners exist for this position, nothing happens.
-- pos: Node positon. MUST use integer values! -- pos: Node positon. MUST use integer values!
@ -55,11 +66,11 @@ function mcl_particles.delete_node_particlespawners(pos)
if allowed_level == 0 then if allowed_level == 0 then
return false return false
end end
local poshash = minetest.hash_node_position(pos) local poshash = hash_node_position(pos)
local ids = particle_nodes[poshash] local ids = particle_nodes[poshash]
if ids then if ids then
for i=1, #ids do for i=1, #ids do
minetest.delete_particlespawner(ids[i]) delete_particlespawner(ids[i])
end end
particle_nodes[poshash] = nil particle_nodes[poshash] = nil
return true return true
@ -72,7 +83,6 @@ end
local smoke_pdef_cached = {} local smoke_pdef_cached = {}
function mcl_particles.spawn_smoke(pos, name, smoke_pdef_base) function mcl_particles.spawn_smoke(pos, name, smoke_pdef_base)
local min = math.min
local new_minpos = vector.add(pos, smoke_pdef_base.minrelpos) local new_minpos = vector.add(pos, smoke_pdef_base.minrelpos)
local new_maxpos = vector.add(pos, smoke_pdef_base.maxrelpos) local new_maxpos = vector.add(pos, smoke_pdef_base.maxrelpos)
@ -81,7 +91,7 @@ function mcl_particles.spawn_smoke(pos, name, smoke_pdef_base)
for i, smoke_pdef in ipairs(smoke_pdef_cached[name]) do for i, smoke_pdef in ipairs(smoke_pdef_cached[name]) do
smoke_pdef.minpos = new_minpos smoke_pdef.minpos = new_minpos
smoke_pdef.maxpos = new_maxpos smoke_pdef.maxpos = new_maxpos
mcl_particles.add_node_particlespawner(pos, smoke_pdef, "high") add_node_particlespawner(pos, smoke_pdef, "high")
end end
-- cache already populated -- cache already populated
else else
@ -111,13 +121,11 @@ function mcl_particles.spawn_smoke(pos, name, smoke_pdef_base)
smoke_pdef.animation.length = exptime + 0.1 smoke_pdef.animation.length = exptime + 0.1
-- minexptime must be set such that the last frame is actully rendered, -- minexptime must be set such that the last frame is actully rendered,
-- even if its very short. Larger exptime -> larger range -- even if its very short. Larger exptime -> larger range
smoke_pdef.minexptime = min(exptime, (7.0/8.0 * (exptime + 0.1) + 0.1)) smoke_pdef.minexptime = math.min(exptime, (7.0/8.0 * (exptime + 0.1) + 0.1))
smoke_pdef.texture = "mcl_particles_smoke_anim.png^[colorize:#000000:" ..colorize smoke_pdef.texture = "mcl_particles_smoke_anim.png^[colorize:#000000:" ..colorize
add_node_particlespawner(pos, smoke_pdef, "high")
mcl_particles.add_node_particlespawner(pos, smoke_pdef, "high")
table.insert(smoke_pdef_cached[name], table.copy(smoke_pdef)) table.insert(smoke_pdef_cached[name], table.copy(smoke_pdef))
end end
end end
end end
end end

View File

@ -150,7 +150,7 @@ function mcl_util.get_eligible_transfer_item_slot(src_inventory, src_list, dst_i
end end
-- Returns true if itemstack is a shulker box -- Returns true if itemstack is a shulker box
local is_not_shulker_box = function(itemstack) local function is_not_shulker_box(itemstack)
local g = minetest.get_item_group(itemstack:get_name(), "shulker_box") local g = minetest.get_item_group(itemstack:get_name(), "shulker_box")
return g == 0 or g == nil return g == 0 or g == nil
end end
@ -212,7 +212,7 @@ function mcl_util.move_item_container(source_pos, destination_pos, source_list,
end end
-- Normalize double container by forcing to always use the left segment first -- Normalize double container by forcing to always use the left segment first
local normalize_double_container = function(pos, node, ctype) local function normalize_double_container(pos, node, ctype)
if ctype == 6 then if ctype == 6 then
pos = mcl_util.get_double_container_neighbor_pos(pos, node.param2, "right") pos = mcl_util.get_double_container_neighbor_pos(pos, node.param2, "right")
if not pos then if not pos then
@ -456,14 +456,7 @@ function mcl_util.calculate_durability(itemstack)
end end
end end
end end
if not uses then uses = uses or (next(itemstack:get_tool_capabilities().groupcaps) or {}).uses
local toolcaps = itemstack:get_tool_capabilities()
local groupcaps = toolcaps.groupcaps
for _, v in pairs(groupcaps) do
uses = v.uses
break
end
end
end end
return uses or 0 return uses or 0

View File

@ -33,15 +33,15 @@ end
-- If the Y coordinate is not located in any dimension, it will return: -- If the Y coordinate is not located in any dimension, it will return:
-- nil, "void" -- nil, "void"
function mcl_worlds.y_to_layer(y) function mcl_worlds.y_to_layer(y)
if y >= mcl_vars.mg_overworld_min then if y >= mcl_vars.mg_overworld_min then
return y - mcl_vars.mg_overworld_min, "overworld" return y - mcl_vars.mg_overworld_min, "overworld"
elseif y >= mcl_vars.mg_nether_min and y <= mcl_vars.mg_nether_max+128 then elseif y >= mcl_vars.mg_nether_min and y <= mcl_vars.mg_nether_max+128 then
return y - mcl_vars.mg_nether_min, "nether" return y - mcl_vars.mg_nether_min, "nether"
elseif y >= mcl_vars.mg_end_min and y <= mcl_vars.mg_end_max then elseif y >= mcl_vars.mg_end_min and y <= mcl_vars.mg_end_max then
return y - mcl_vars.mg_end_min, "end" return y - mcl_vars.mg_end_min, "end"
else else
return nil, "void" return nil, "void"
end end
end end
-- Takes a pos and returns the dimension it belongs to (same as above) -- Takes a pos and returns the dimension it belongs to (same as above)
@ -55,38 +55,38 @@ end
-- MineClone 2. -- MineClone 2.
-- mc_dimension is one of "overworld", "nether", "end" (default: "overworld"). -- mc_dimension is one of "overworld", "nether", "end" (default: "overworld").
function mcl_worlds.layer_to_y(layer, mc_dimension) function mcl_worlds.layer_to_y(layer, mc_dimension)
if mc_dimension == "overworld" or mc_dimension == nil then if mc_dimension == "overworld" or mc_dimension == nil then
return layer + mcl_vars.mg_overworld_min return layer + mcl_vars.mg_overworld_min
elseif mc_dimension == "nether" then elseif mc_dimension == "nether" then
return layer + mcl_vars.mg_nether_min return layer + mcl_vars.mg_nether_min
elseif mc_dimension == "end" then elseif mc_dimension == "end" then
return layer + mcl_vars.mg_end_min return layer + mcl_vars.mg_end_min
end end
end end
-- Takes a position and returns true if this position can have weather -- Takes a position and returns true if this position can have weather
function mcl_worlds.has_weather(pos) function mcl_worlds.has_weather(pos)
-- Weather in the Overworld and the high part of the void below -- Weather in the Overworld and the high part of the void below
return pos.y <= mcl_vars.mg_overworld_max and pos.y >= mcl_vars.mg_overworld_min - 64 return pos.y <= mcl_vars.mg_overworld_max and pos.y >= mcl_vars.mg_overworld_min - 64
end end
-- Takes a position and returns true if this position can have Nether dust -- Takes a position and returns true if this position can have Nether dust
function mcl_worlds.has_dust(pos) function mcl_worlds.has_dust(pos)
-- Weather in the Overworld and the high part of the void below -- Weather in the Overworld and the high part of the void below
return pos.y <= mcl_vars.mg_nether_max + 138 and pos.y >= mcl_vars.mg_nether_min - 10 return pos.y <= mcl_vars.mg_nether_max + 138 and pos.y >= mcl_vars.mg_nether_min - 10
end end
-- Takes a position (pos) and returns true if compasses are working here -- Takes a position (pos) and returns true if compasses are working here
function mcl_worlds.compass_works(pos) function mcl_worlds.compass_works(pos)
-- It doesn't work in Nether and the End, but it works in the Overworld and in the high part of the void below -- It doesn't work in Nether and the End, but it works in the Overworld and in the high part of the void below
local _, dim = mcl_worlds.y_to_layer(pos.y) local _, dim = mcl_worlds.y_to_layer(pos.y)
if dim == "nether" or dim == "end" then if dim == "nether" or dim == "end" then
return false return false
elseif dim == "void" then elseif dim == "void" then
return pos.y <= mcl_vars.mg_overworld_max and pos.y >= mcl_vars.mg_overworld_min - 64 return pos.y <= mcl_vars.mg_overworld_max and pos.y >= mcl_vars.mg_overworld_min - 64
else else
return true return true
end end
end end
-- Takes a position (pos) and returns true if clocks are working here -- Takes a position (pos) and returns true if clocks are working here
@ -112,11 +112,11 @@ local last_dimension = {}
-- * player: Player who changed the dimension -- * player: Player who changed the dimension
-- * dimension: New dimension ("overworld", "nether", "end", "void") -- * dimension: New dimension ("overworld", "nether", "end", "void")
function mcl_worlds.dimension_change(player, dimension) function mcl_worlds.dimension_change(player, dimension)
local playername = player:get_player_name() local playername = player:get_player_name()
for i=1, #mcl_worlds.registered_on_dimension_change do for i=1, #mcl_worlds.registered_on_dimension_change do
mcl_worlds.registered_on_dimension_change[i](player, dimension, last_dimension[playername]) mcl_worlds.registered_on_dimension_change[i](player, dimension, last_dimension[playername])
end end
last_dimension[playername] = dimension last_dimension[playername] = dimension
end end
----------------------- INTERNAL STUFF ---------------------- ----------------------- INTERNAL STUFF ----------------------

View File

@ -31,24 +31,21 @@ minetest.register_globalstep(function(dtime)
timer = timer + dtime; timer = timer + dtime;
if timer >= 0.3 then if timer >= 0.3 then
for _,player in pairs(get_connected_players()) do for _,player in pairs(get_connected_players()) do
local pp = player:get_pos() local pp = player:get_pos()
pp.y = ceil(pp.y) pp.y = ceil(pp.y)
local loc = vector_add(pp, {x=0,y=-1,z=0}) local loc = vector_add(pp, {x=0,y=-1,z=0})
if loc ~= nil then if loc ~= nil then
local nodeiamon = get_node(loc)
local nodeiamon = get_node(loc) if nodeiamon ~= nil then
if on_walk[nodeiamon.name] then
if nodeiamon ~= nil then on_walk[nodeiamon.name](loc, nodeiamon, player)
if on_walk[nodeiamon.name] then end
on_walk[nodeiamon.name](loc, nodeiamon, player) for i = 1, #registered_globals do
end
for i = 1, #registered_globals do
registered_globals[i](loc, nodeiamon, player) registered_globals[i](loc, nodeiamon, player)
end end
end end
end end
end end
timer = 0 timer = 0
end end
end) end)

View File

@ -1,6 +1,8 @@
--Dripping Water Mod --Dripping Water Mod
--by kddekadenz --by kddekadenz
local math = math
-- License of code, textures & sounds: CC0 -- License of code, textures & sounds: CC0
--Drop entities --Drop entities
@ -20,26 +22,21 @@ minetest.register_entity("drippingwater:drop_water", {
spritediv = {x=1, y=1}, spritediv = {x=1, y=1},
initial_sprite_basepos = {x=0, y=0}, initial_sprite_basepos = {x=0, y=0},
static_save = false, static_save = false,
on_activate = function(self, staticdata) on_activate = function(self, staticdata)
self.object:set_sprite({x=0,y=0}, 1, 1, true) self.object:set_sprite({x=0,y=0}, 1, 1, true)
end, end,
on_step = function(self, dtime) on_step = function(self, dtime)
local k = math.random(1,222) local k = math.random(1,222)
local ownpos = self.object:get_pos() local ownpos = self.object:get_pos()
if k==1 then
if k==1 then self.object:set_acceleration({x=0, y=-5, z=0})
self.object:set_acceleration({x=0, y=-5, z=0}) end
end if minetest.get_node({x=ownpos.x, y=ownpos.y +0.5, z=ownpos.z}).name == "air" then
self.object:set_acceleration({x=0, y=-5, z=0})
if minetest.get_node({x=ownpos.x, y=ownpos.y +0.5, z=ownpos.z}).name == "air" then end
self.object:set_acceleration({x=0, y=-5, z=0})
end
if minetest.get_node({x=ownpos.x, y=ownpos.y -0.5, z=ownpos.z}).name ~= "air" then if minetest.get_node({x=ownpos.x, y=ownpos.y -0.5, z=ownpos.z}).name ~= "air" then
self.object:remove() self.object:remove()
minetest.sound_play({name="drippingwater_drip"}, {pos = ownpos, gain = 0.5, max_hear_distance = 8}, true) minetest.sound_play({name="drippingwater_drip"}, {pos = ownpos, gain = 0.5, max_hear_distance = 8}, true)
end end
end, end,
}) })
@ -61,27 +58,21 @@ minetest.register_entity("drippingwater:drop_lava", {
spritediv = {x=1, y=1}, spritediv = {x=1, y=1},
initial_sprite_basepos = {x=0, y=0}, initial_sprite_basepos = {x=0, y=0},
static_save = false, static_save = false,
on_activate = function(self, staticdata) on_activate = function(self, staticdata)
self.object:set_sprite({x=0,y=0}, 1, 0, true) self.object:set_sprite({x=0,y=0}, 1, 0, true)
end, end,
on_step = function(self, dtime) on_step = function(self, dtime)
local k = math.random(1,222) local k = math.random(1,222)
local ownpos = self.object:get_pos() local ownpos = self.object:get_pos()
if k == 1 then
if k==1 then self.object:set_acceleration({x=0, y=-5, z=0})
self.object:set_acceleration({x=0, y=-5, z=0}) end
end if minetest.get_node({x=ownpos.x, y=ownpos.y +0.5, z=ownpos.z}).name == "air" then
self.object:set_acceleration({x=0, y=-5, z=0})
if minetest.get_node({x=ownpos.x, y=ownpos.y +0.5, z=ownpos.z}).name == "air" then end
self.object:set_acceleration({x=0, y=-5, z=0})
end
if minetest.get_node({x=ownpos.x, y=ownpos.y -0.5, z=ownpos.z}).name ~= "air" then if minetest.get_node({x=ownpos.x, y=ownpos.y -0.5, z=ownpos.z}).name ~= "air" then
self.object:remove() self.object:remove()
minetest.sound_play({name="drippingwater_lavadrip"}, {pos = ownpos, gain = 0.5, max_hear_distance = 8}, true) minetest.sound_play({name="drippingwater_lavadrip"}, {pos = ownpos, gain = 0.5, max_hear_distance = 8}, true)
end end
end, end,
}) })
@ -90,36 +81,34 @@ minetest.register_entity("drippingwater:drop_lava", {
--Create drop --Create drop
minetest.register_abm( minetest.register_abm({
{
label = "Create water drops", label = "Create water drops",
nodenames = {"group:opaque", "group:leaves"}, nodenames = {"group:opaque", "group:leaves"},
neighbors = {"group:water"}, neighbors = {"group:water"},
interval = 2, interval = 2,
chance = 22, chance = 22,
action = function(pos) action = function(pos)
if minetest.get_item_group(minetest.get_node({x=pos.x, y=pos.y+1, z=pos.z}).name, "water") ~= 0 and if minetest.get_item_group(minetest.get_node({x=pos.x, y=pos.y+1, z=pos.z}).name, "water") ~= 0
minetest.get_node({x=pos.x, y=pos.y-1, z=pos.z}).name == "air" then and minetest.get_node({x=pos.x, y=pos.y-1, z=pos.z}).name == "air" then
local i = math.random(-45,45) / 100 local i = math.random(-45,45) / 100
minetest.add_entity({x=pos.x + i, y=pos.y - 0.501, z=pos.z + i}, "drippingwater:drop_water") minetest.add_entity({x=pos.x + i, y=pos.y - 0.501, z=pos.z + i}, "drippingwater:drop_water")
end end
end, end,
}) })
--Create lava drop --Create lava drop
minetest.register_abm( minetest.register_abm({
{
label = "Create lava drops", label = "Create lava drops",
nodenames = {"group:opaque"}, nodenames = {"group:opaque"},
neighbors = {"group:lava"}, neighbors = {"group:lava"},
interval = 2, interval = 2,
chance = 22, chance = 22,
action = function(pos) action = function(pos)
if minetest.get_item_group(minetest.get_node({x=pos.x, y=pos.y+1, z=pos.z}).name, "lava") ~= 0 and if minetest.get_item_group(minetest.get_node({x=pos.x, y=pos.y+1, z=pos.z}).name, "lava") ~= 0
minetest.get_node({x=pos.x, y=pos.y-1, z=pos.z}).name == "air" then and minetest.get_node({x=pos.x, y=pos.y-1, z=pos.z}).name == "air" then
local i = math.random(-45,45) / 100 local i = math.random(-45,45) / 100
minetest.add_entity({x=pos.x + i, y=pos.y - 0.501, z=pos.z + i}, "drippingwater:drop_lava") minetest.add_entity({x=pos.x + i, y=pos.y - 0.501, z=pos.z + i}, "drippingwater:drop_lava")
end end
end, end,
}) })

View File

@ -328,10 +328,10 @@ function boat.on_step(self, dtime, moveresult)
p.y = p.y - boat_y_offset p.y = p.y - boat_y_offset
local new_velo local new_velo
local new_acce = {x = 0, y = 0, z = 0} local new_acce
if not is_water(p) and not on_ice then if not is_water(p) and not on_ice then
-- Not on water or inside water: Free fall -- Not on water or inside water: Free fall
local nodedef = minetest.registered_nodes[minetest.get_node(p).name] --local nodedef = minetest.registered_nodes[minetest.get_node(p).name]
new_acce = {x = 0, y = -9.8, z = 0} new_acce = {x = 0, y = -9.8, z = 0}
new_velo = get_velocity(self._v, self.object:get_yaw(), new_velo = get_velocity(self._v, self.object:get_yaw(),
self.object:get_velocity().y) self.object:get_velocity().y)

View File

@ -1,5 +1,3 @@
local S = minetest.get_translator("mcl_burning")
function mcl_burning.get_storage(obj) function mcl_burning.get_storage(obj)
return obj:is_player() and mcl_burning.storage[obj] or obj:get_luaentity() return obj:is_player() and mcl_burning.storage[obj] or obj:get_luaentity()
end end
@ -145,4 +143,4 @@ function mcl_burning.tick(obj, dtime, storage)
end end
end end
end end
end end

View File

@ -1,5 +1,4 @@
local S = minetest.get_translator("mcl_burning") local modpath = minetest.get_modpath(minetest.get_current_modname())
local modpath = minetest.get_modpath("mcl_burning")
mcl_burning = { mcl_burning = {
storage = {}, storage = {},
@ -56,7 +55,6 @@ minetest.register_on_leaveplayer(function(player)
local storage = mcl_burning.storage[player] local storage = mcl_burning.storage[player]
storage.fire_hud_id = nil storage.fire_hud_id = nil
player:get_meta():set_string("mcl_burning:data", minetest.serialize(storage)) player:get_meta():set_string("mcl_burning:data", minetest.serialize(storage))
mcl_burning.storage[player] = nil mcl_burning.storage[player] = nil
end) end)
@ -68,11 +66,10 @@ minetest.register_entity("mcl_burning:fire", {
visual = "cube", visual = "cube",
pointable = false, pointable = false,
glow = -1, glow = -1,
backface_culling = false,
}, },
animation_frame = 0, animation_frame = 0,
animation_timer = 0, animation_timer = 0,
on_step = function(self, dtime) on_step = function(self, dtime)
local parent, storage = self:sanity_check() local parent, storage = self:sanity_check()

View File

@ -1,7 +1,4 @@
local S = minetest.get_translator("mcl_falling_nodes") local function get_falling_depth(self)
local has_mcl_armor = minetest.get_modpath("mcl_armor")
local get_falling_depth = function(self)
if not self._startpos then if not self._startpos then
-- Fallback -- Fallback
self._startpos = self.object:get_pos() self._startpos = self.object:get_pos()
@ -9,7 +6,7 @@ local get_falling_depth = function(self)
return self._startpos.y - vector.round(self.object:get_pos()).y return self._startpos.y - vector.round(self.object:get_pos()).y
end end
local deal_falling_damage = function(self, dtime) local function deal_falling_damage(self, dtime)
if minetest.get_item_group(self.node.name, "falling_node_damage") == 0 then if minetest.get_item_group(self.node.name, "falling_node_damage") == 0 then
return return
end end
@ -38,7 +35,7 @@ local deal_falling_damage = function(self, dtime)
inv:set_stack("armor", 2, helmet) inv:set_stack("armor", 2, helmet)
end end
end end
local deathmsg, dmg_type local dmg_type
if minetest.get_item_group(self.node.name, "anvil") ~= 0 then if minetest.get_item_group(self.node.name, "anvil") ~= 0 then
dmg_type = "anvil" dmg_type = "anvil"
else else
@ -60,10 +57,8 @@ minetest.register_entity(":__builtin:falling_node", {
collide_with_objects = false, collide_with_objects = false,
collisionbox = {-0.5, -0.5, -0.5, 0.5, 0.5, 0.5}, collisionbox = {-0.5, -0.5, -0.5, 0.5, 0.5, 0.5},
}, },
node = {}, node = {},
meta = {}, meta = {},
set_node = function(self, node, meta) set_node = function(self, node, meta)
local def = minetest.registered_nodes[node.name] local def = minetest.registered_nodes[node.name]
-- Change falling node if definition tells us to -- Change falling node if definition tells us to
@ -90,7 +85,6 @@ minetest.register_entity(":__builtin:falling_node", {
glow = glow, glow = glow,
}) })
end, end,
get_staticdata = function(self) get_staticdata = function(self)
local meta = self.meta local meta = self.meta
-- Workaround: Save inventory seperately from metadata. -- Workaround: Save inventory seperately from metadata.
@ -111,7 +105,6 @@ minetest.register_entity(":__builtin:falling_node", {
} }
return minetest.serialize(ds) return minetest.serialize(ds)
end, end,
on_activate = function(self, staticdata) on_activate = function(self, staticdata)
self.object:set_armor_groups({immortal = 1}) self.object:set_armor_groups({immortal = 1})
@ -134,7 +127,6 @@ minetest.register_entity(":__builtin:falling_node", {
end end
self._startpos = vector.round(self._startpos) self._startpos = vector.round(self._startpos)
end, end,
on_step = function(self, dtime) on_step = function(self, dtime)
-- Set gravity -- Set gravity
local acceleration = self.object:get_acceleration() local acceleration = self.object:get_acceleration()
@ -186,10 +178,9 @@ minetest.register_entity(":__builtin:falling_node", {
return return
end end
local nd = minetest.registered_nodes[n2.name] local nd = minetest.registered_nodes[n2.name]
if n2.name == "mcl_portals:portal_end" then --if n2.name == "mcl_portals:portal_end" then
-- TODO: Teleport falling node. -- TODO: Teleport falling node.
if (nd and nd.buildable_to == true) or minetest.get_item_group(self.node.name, "crush_after_fall") ~= 0 then
elseif (nd and nd.buildable_to == true) or minetest.get_item_group(self.node.name, "crush_after_fall") ~= 0 then
-- Replace destination node if it's buildable to -- Replace destination node if it's buildable to
minetest.remove_node(np) minetest.remove_node(np)
-- Run script hook -- Run script hook
@ -256,7 +247,6 @@ minetest.register_entity(":__builtin:falling_node", {
self.object:set_pos(npos) self.object:set_pos(npos)
end end
end end
deal_falling_damage(self, dtime) deal_falling_damage(self, dtime)
end end
}) })

View File

@ -1,3 +0,0 @@
# textdomain: mcl_falling_nodes
@1 was smashed by a falling anvil.=@1 wurde von einem fallenden Amboss zerschmettert.
@1 was smashed by a falling block.=@1 wurde von einem fallenden Block zerschmettert.

View File

@ -1,3 +0,0 @@
# textdomain: mcl_falling_nodes
@1 was smashed by a falling anvil.=@1 fue aplastado por la caída de un yunque.
@1 was smashed by a falling block.=@1 fue aplastado por la caída de un bloque.

View File

@ -1,3 +0,0 @@
# textdomain: mcl_falling_nodes
@1 was smashed by a falling anvil.=@1 a été écrasé par une enclume qui tombait.
@1 was smashed by a falling block.=@1 a été écrasé par un bloc qui tombait.

View File

@ -1,3 +0,0 @@
# textdomain: mcl_falling_nodes
@1 was smashed by a falling anvil.=@1 придавило падающей наковальней.
@1 was smashed by a falling block.=@1 раздавило падающим блоком.

View File

@ -1,3 +0,0 @@
# textdomain: mcl_falling_nodes
@1 was smashed by a falling anvil.=
@1 was smashed by a falling block.=

View File

@ -1,5 +1,5 @@
--these are lua locals, used for higher performance --these are lua locals, used for higher performance
local minetest,math,vector,ipairs = minetest,math,vector,ipairs local minetest, math, vector, ipairs = minetest, math, vector, ipairs
--this is used for the player pool in the sound buffer --this is used for the player pool in the sound buffer
local pool = {} local pool = {}
@ -38,7 +38,7 @@ item_drop_settings.drop_single_item = false --if true, the drop control dro
item_drop_settings.magnet_time = 0.75 -- how many seconds an item follows the player before giving up item_drop_settings.magnet_time = 0.75 -- how many seconds an item follows the player before giving up
local get_gravity = function() local function get_gravity()
return tonumber(minetest.settings:get("movement_gravity")) or 9.81 return tonumber(minetest.settings:get("movement_gravity")) or 9.81
end end
@ -60,7 +60,7 @@ mcl_item_entity.register_pickup_achievement("mcl_mobitems:blaze_rod", "mcl:blaze
mcl_item_entity.register_pickup_achievement("mcl_mobitems:leather", "mcl:killCow") mcl_item_entity.register_pickup_achievement("mcl_mobitems:leather", "mcl:killCow")
mcl_item_entity.register_pickup_achievement("mcl_core:diamond", "mcl:diamonds") mcl_item_entity.register_pickup_achievement("mcl_core:diamond", "mcl:diamonds")
local check_pickup_achievements = function(object, player) local function check_pickup_achievements(object, player)
if has_awards then if has_awards then
local itemname = ItemStack(object:get_luaentity().itemstring):get_name() local itemname = ItemStack(object:get_luaentity().itemstring):get_name()
local playername = player:get_player_name() local playername = player:get_player_name()
@ -72,7 +72,7 @@ local check_pickup_achievements = function(object, player)
end end
end end
local enable_physics = function(object, luaentity, ignore_check) local function enable_physics(object, luaentity, ignore_check)
if luaentity.physical_state == false or ignore_check == true then if luaentity.physical_state == false or ignore_check == true then
luaentity.physical_state = true luaentity.physical_state = true
object:set_properties({ object:set_properties({
@ -83,7 +83,7 @@ local enable_physics = function(object, luaentity, ignore_check)
end end
end end
local disable_physics = function(object, luaentity, ignore_check, reset_movement) local function disable_physics(object, luaentity, ignore_check, reset_movement)
if luaentity.physical_state == true or ignore_check == true then if luaentity.physical_state == true or ignore_check == true then
luaentity.physical_state = false luaentity.physical_state = false
object:set_properties({ object:set_properties({
@ -98,13 +98,11 @@ end
minetest.register_globalstep(function(dtime) minetest.register_globalstep(function(dtime)
tick = not tick tick = not tick
for _,player in pairs(minetest.get_connected_players()) do for _,player in pairs(minetest.get_connected_players()) do
if player:get_hp() > 0 or not minetest.settings:get_bool("enable_damage") then if player:get_hp() > 0 or not minetest.settings:get_bool("enable_damage") then
local name = player:get_player_name() local name = player:get_player_name()
local pos = player:get_pos() local pos = player:get_pos()
@ -426,13 +424,9 @@ minetest.register_entity(":__builtin:item", {
if itemtable then if itemtable then
itemname = stack:to_table().name itemname = stack:to_table().name
end end
local item_texture = nil
local item_type = ""
local glow local glow
local def = minetest.registered_items[itemname] local def = minetest.registered_items[itemname]
if def then if def then
item_texture = def.inventory_image
item_type = def.type
description = def.description description = def.description
glow = def.light_source glow = def.light_source
end end

View File

@ -1,3 +1,5 @@
local vector = vector
function mcl_minecarts:get_sign(z) function mcl_minecarts:get_sign(z)
if z == 0 then if z == 0 then
return 0 return 0
@ -38,11 +40,9 @@ end
function mcl_minecarts:check_front_up_down(pos, dir_, check_down, railtype) function mcl_minecarts:check_front_up_down(pos, dir_, check_down, railtype)
local dir = vector.new(dir_) local dir = vector.new(dir_)
local cur = nil
-- Front -- Front
dir.y = 0 dir.y = 0
cur = vector.add(pos, dir) local cur = vector.add(pos, dir)
if mcl_minecarts:is_rail(cur, railtype) then if mcl_minecarts:is_rail(cur, railtype) then
return dir return dir
end end
@ -65,9 +65,9 @@ end
function mcl_minecarts:get_rail_direction(pos_, dir, ctrl, old_switch, railtype) function mcl_minecarts:get_rail_direction(pos_, dir, ctrl, old_switch, railtype)
local pos = vector.round(pos_) local pos = vector.round(pos_)
local cur = nil local cur
local left_check, right_check = true, true local left_check, right_check = true, true
-- Check left and right -- Check left and right
local left = {x=0, y=0, z=0} local left = {x=0, y=0, z=0}
local right = {x=0, y=0, z=0} local right = {x=0, y=0, z=0}
@ -78,7 +78,7 @@ function mcl_minecarts:get_rail_direction(pos_, dir, ctrl, old_switch, railtype)
left.z = dir.x left.z = dir.x
right.z = -dir.x right.z = -dir.x
end end
if ctrl then if ctrl then
if old_switch == 1 then if old_switch == 1 then
left_check = false left_check = false
@ -100,13 +100,13 @@ function mcl_minecarts:get_rail_direction(pos_, dir, ctrl, old_switch, railtype)
right_check = true right_check = true
end end
end end
-- Normal -- Normal
cur = mcl_minecarts:check_front_up_down(pos, dir, true, railtype) cur = mcl_minecarts:check_front_up_down(pos, dir, true, railtype)
if cur then if cur then
return cur return cur
end end
-- Left, if not already checked -- Left, if not already checked
if left_check then if left_check then
cur = mcl_minecarts:check_front_up_down(pos, left, false, railtype) cur = mcl_minecarts:check_front_up_down(pos, left, false, railtype)
@ -114,7 +114,7 @@ function mcl_minecarts:get_rail_direction(pos_, dir, ctrl, old_switch, railtype)
return cur return cur
end end
end end
-- Right, if not already checked -- Right, if not already checked
if right_check then if right_check then
cur = mcl_minecarts:check_front_up_down(pos, right, false, railtype) cur = mcl_minecarts:check_front_up_down(pos, right, false, railtype)
@ -122,7 +122,6 @@ function mcl_minecarts:get_rail_direction(pos_, dir, ctrl, old_switch, railtype)
return cur return cur
end end
end end
-- Backwards -- Backwards
if not old_switch then if not old_switch then
cur = mcl_minecarts:check_front_up_down(pos, { cur = mcl_minecarts:check_front_up_down(pos, {
@ -134,7 +133,5 @@ function mcl_minecarts:get_rail_direction(pos_, dir, ctrl, old_switch, railtype)
return cur return cur
end end
end end
return {x=0, y=0, z=0} return {x=0, y=0, z=0}
end end

View File

@ -486,7 +486,6 @@ local function register_entity(entity_id, mesh, textures, drop, on_rightclick, o
if update.pos then if update.pos then
self.object:set_pos(pos) self.object:set_pos(pos)
end end
update = nil
end end
function cart:get_staticdata() function cart:get_staticdata()
@ -497,7 +496,7 @@ local function register_entity(entity_id, mesh, textures, drop, on_rightclick, o
end end
-- Place a minecart at pointed_thing -- Place a minecart at pointed_thing
mcl_minecarts.place_minecart = function(itemstack, pointed_thing, placer) function mcl_minecarts.place_minecart(itemstack, pointed_thing, placer)
if not pointed_thing.type == "node" then if not pointed_thing.type == "node" then
return return
end end
@ -541,7 +540,7 @@ mcl_minecarts.place_minecart = function(itemstack, pointed_thing, placer)
end end
local register_craftitem = function(itemstring, entity_id, description, tt_help, longdesc, usagehelp, icon, creative) local function register_craftitem(itemstring, entity_id, description, tt_help, longdesc, usagehelp, icon, creative)
entity_mapping[itemstring] = entity_id entity_mapping[itemstring] = entity_id
local groups = { minecart = 1, transport = 1 } local groups = { minecart = 1, transport = 1 }
@ -817,31 +816,30 @@ minetest.register_craft({
}) })
-- TODO: Re-enable crafting of special minecarts when they have been implemented -- TODO: Re-enable crafting of special minecarts when they have been implemented
if false then --[[minetest.register_craft({
minetest.register_craft({ output = "mcl_minecarts:furnace_minecart",
output = "mcl_minecarts:furnace_minecart", recipe = {
recipe = { {"mcl_furnaces:furnace"},
{"mcl_furnaces:furnace"}, {"mcl_minecarts:minecart"},
{"mcl_minecarts:minecart"}, },
}, })
})
minetest.register_craft({ minetest.register_craft({
output = "mcl_minecarts:hopper_minecart", output = "mcl_minecarts:hopper_minecart",
recipe = { recipe = {
{"mcl_hoppers:hopper"}, {"mcl_hoppers:hopper"},
{"mcl_minecarts:minecart"}, {"mcl_minecarts:minecart"},
}, },
}) })
minetest.register_craft({
output = "mcl_minecarts:chest_minecart",
recipe = {
{"mcl_chests:chest"},
{"mcl_minecarts:minecart"},
},
})]]
minetest.register_craft({
output = "mcl_minecarts:chest_minecart",
recipe = {
{"mcl_chests:chest"},
{"mcl_minecarts:minecart"},
},
})
end
if has_mcl_wip then if has_mcl_wip then
mcl_wip.register_wip_item("mcl_minecarts:chest_minecart") mcl_wip.register_wip_item("mcl_minecarts:chest_minecart")

View File

@ -1,7 +1,7 @@
local S = minetest.get_translator("mcl_minecarts") local S = minetest.get_translator("mcl_minecarts")
-- Template rail function -- Template rail function
local register_rail = function(itemstring, tiles, def_extras, creative) local function register_rail(itemstring, tiles, def_extras, creative)
local groups = {handy=1,pickaxey=1, attached_node=1,rail=1,connect_to_raillike=minetest.raillike_group("rail"),dig_by_water=1,destroy_by_lava_flow=1, transport=1} local groups = {handy=1,pickaxey=1, attached_node=1,rail=1,connect_to_raillike=minetest.raillike_group("rail"),dig_by_water=1,destroy_by_lava_flow=1, transport=1}
if creative == false then if creative == false then
groups.not_in_creative_inventory = 1 groups.not_in_creative_inventory = 1

View File

@ -11,133 +11,111 @@ local minetest_get_objects_inside_radius = minetest.get_objects_inside_radius
local minetest_get_modpath = minetest.get_modpath local minetest_get_modpath = minetest.get_modpath
local minetest_registered_nodes = minetest.registered_nodes local minetest_registered_nodes = minetest.registered_nodes
local minetest_get_node = minetest.get_node local minetest_get_node = minetest.get_node
local minetest_get_item_group = minetest.get_item_group --local minetest_get_item_group = minetest.get_item_group
local minetest_registered_entities = minetest.registered_entities local minetest_registered_entities = minetest.registered_entities
local minetest_line_of_sight = minetest.line_of_sight --local minetest_line_of_sight = minetest.line_of_sight
local minetest_after = minetest.after --local minetest_after = minetest.after
local minetest_sound_play = minetest.sound_play --local minetest_sound_play = minetest.sound_play
local minetest_add_particlespawner = minetest.add_particlespawner --local minetest_add_particlespawner = minetest.add_particlespawner
local minetest_registered_items = minetest.registered_items --local minetest_registered_items = minetest.registered_items
local minetest_set_node = minetest.set_node --local minetest_set_node = minetest.set_node
local minetest_add_item = minetest.add_item local minetest_add_item = minetest.add_item
local minetest_get_craft_result = minetest.get_craft_result --local minetest_get_craft_result = minetest.get_craft_result
local minetest_find_path = minetest.find_path --local minetest_find_path = minetest.find_path
local minetest_is_protected = minetest.is_protected
local minetest_is_creative_enabled = minetest.is_creative_enabled local minetest_is_creative_enabled = minetest.is_creative_enabled
local minetest_find_node_near = minetest.find_node_near --local minetest_find_node_near = minetest.find_node_near
local minetest_find_nodes_in_area_under_air = minetest.find_nodes_in_area_under_air --local minetest_find_nodes_in_area_under_air = minetest.find_nodes_in_area_under_air
local minetest_raycast = minetest.raycast --local minetest_raycast = minetest.raycast
local minetest_get_us_time = minetest.get_us_time --local minetest_get_us_time = minetest.get_us_time
local minetest_add_entity = minetest.add_entity local minetest_add_entity = minetest.add_entity
local minetest_get_natural_light = minetest.get_natural_light --local minetest_get_natural_light = minetest.get_natural_light
local minetest_get_node_or_nil = minetest.get_node_or_nil --local minetest_get_node_or_nil = minetest.get_node_or_nil
-- localize math functions -- localize math functions
local math_pi = math.pi local math = math
local math_sin = math.sin
local math_cos = math.cos
local math_abs = math.abs
local math_min = math.min
local math_max = math.max
local math_atan = math.atan
local math_random = math.random
local math_floor = math.floor
-- localize vector functions -- localize vector functions
local vector_new = vector.new local vector = vector
local vector_add = vector.add
local vector_length = vector.length local string = string
local vector_direction = vector.direction
local vector_normalize = vector.normalize
local vector_multiply = vector.multiply
local vector_divide = vector.divide
-- mob constants -- mob constants
local BREED_TIME = 30 --local BREED_TIME = 30
local BREED_TIME_AGAIN = 300 --local BREED_TIME_AGAIN = 300
local CHILD_GROW_TIME = 60*20 --local CHILD_GROW_TIME = 60*20
local DEATH_DELAY = 0.5 --local DEATH_DELAY = 0.5
local DEFAULT_FALL_SPEED = -10 local DEFAULT_FALL_SPEED = -10
local FLOP_HEIGHT = 5.0 --local FLOP_HEIGHT = 5.0
local FLOP_HOR_SPEED = 1.5 --local FLOP_HOR_SPEED = 1.5
local GRAVITY = minetest_settings:get("movement_gravity")-- + 9.81 local GRAVITY = minetest_settings:get("movement_gravity")-- + 9.81
local MAX_MOB_NAME_LENGTH = 30
local MOB_CAP = {}
--[[local MOB_CAP = {}
MOB_CAP.hostile = 70 MOB_CAP.hostile = 70
MOB_CAP.passive = 10 MOB_CAP.passive = 10
MOB_CAP.ambient = 15 MOB_CAP.ambient = 15
MOB_CAP.water = 15 MOB_CAP.water = 15
]]
-- Load main settings -- Load main settings
local damage_enabled = minetest_settings:get_bool("enable_damage") --local damage_enabled = minetest_settings:get_bool("enable_damage")
local disable_blood = minetest_settings:get_bool("mobs_disable_blood") --local disable_blood = minetest_settings:get_bool("mobs_disable_blood")
local mobs_drop_items = minetest_settings:get_bool("mobs_drop_items") ~= false --local mobs_drop_items = minetest_settings:get_bool("mobs_drop_items") ~= false
local mobs_griefing = minetest_settings:get_bool("mobs_griefing") ~= false --local mobs_griefing = minetest_settings:get_bool("mobs_griefing") ~= false
local spawn_protected = minetest_settings:get_bool("mobs_spawn_protected") ~= false --local spawn_protected = minetest_settings:get_bool("mobs_spawn_protected") ~= false
local remove_far = true --local remove_far = true
local difficulty = tonumber(minetest_settings:get("mob_difficulty")) or 1.0 local difficulty = tonumber(minetest_settings:get("mob_difficulty")) or 1.0
local show_health = false --local show_health = false
local max_per_block = tonumber(minetest_settings:get("max_objects_per_block") or 64) --local max_per_block = tonumber(minetest_settings:get("max_objects_per_block") or 64)
local mobs_spawn_chance = tonumber(minetest_settings:get("mobs_spawn_chance") or 2.5) ---local mobs_spawn_chance = tonumber(minetest_settings:get("mobs_spawn_chance") or 2.5)
-- pathfinding settings -- pathfinding settings
local enable_pathfinding = true --local enable_pathfinding = true
local stuck_timeout = 3 -- how long before mob gets stuck in place and starts searching --local stuck_timeout = 3 -- how long before mob gets stuck in place and starts searching
local stuck_path_timeout = 10 -- how long will mob follow path before giving up --local stuck_path_timeout = 10 -- how long will mob follow path before giving up
-- default nodes -- default nodes
local node_ice = "mcl_core:ice" --local node_ice = "mcl_core:ice"
local node_snowblock = "mcl_core:snowblock" --local node_snowblock = "mcl_core:snowblock"
local node_snow = "mcl_core:snow" --local node_snow = "mcl_core:snow"
mobs.fallback_node = minetest.registered_aliases["mapgen_dirt"] or "mcl_core:dirt" mobs.fallback_node = minetest.registered_aliases["mapgen_dirt"] or "mcl_core:dirt"
local mod_weather = minetest_get_modpath("mcl_weather") ~= nil --local mod_weather = minetest_get_modpath("mcl_weather")
local mod_explosions = minetest_get_modpath("mcl_explosions") ~= nil --local mod_explosions = minetest_get_modpath("mcl_explosions")
local mod_mobspawners = minetest_get_modpath("mcl_mobspawners") ~= nil local mod_mobspawners = minetest_get_modpath("mcl_mobspawners")
local mod_hunger = minetest_get_modpath("mcl_hunger") ~= nil --local mod_hunger = minetest_get_modpath("mcl_hunger")
local mod_worlds = minetest_get_modpath("mcl_worlds") ~= nil --local mod_worlds = minetest_get_modpath("mcl_worlds")
local mod_armor = minetest_get_modpath("mcl_armor") ~= nil --local mod_armor = minetest_get_modpath("mcl_armor")
local mod_experience = minetest_get_modpath("mcl_experience") ~= nil --local mod_experience = minetest_get_modpath("mcl_experience")
-- random locals I found -- random locals I found
local los_switcher = false --local los_switcher = false
local height_switcher = false --local height_switcher = false
-- Get translator -- Get translator
local S = minetest.get_translator("mcl_mobs") local S = minetest.get_translator("mcl_mobs")
-- CMI support check -- CMI support check
local use_cmi = minetest.global_exists("cmi") --local use_cmi = minetest.global_exists("cmi")
-- Invisibility mod check
mobs.invis = {}
if minetest.global_exists("invisibility") then
mobs.invis = invisibility
end
-- creative check -- creative check
function mobs.is_creative(name) function mobs.is_creative(name)
return minetest_is_creative_enabled(name) return minetest_is_creative_enabled(name)
end end
--[[local function atan(x)
local atan = function(x)
if not x or x ~= x then if not x or x ~= x then
return 0 return 0
else else
return math_atan(x) return math.atan(x)
end end
end end]]
-- Shows helpful debug info above each mob -- Shows helpful debug info above each mob
local mobs_debug = minetest_settings:get_bool("mobs_debug", false) --local mobs_debug = minetest_settings:get_bool("mobs_debug", false)
-- Peaceful mode message so players will know there are no monsters -- Peaceful mode message so players will know there are no monsters
if minetest_settings:get_bool("only_peaceful_mobs", false) then if minetest_settings:get_bool("only_peaceful_mobs", false) then
@ -191,7 +169,7 @@ function mobs:register_mob(name, def)
if (not value) or (value == default) or (value == special) then if (not value) or (value == default) or (value == special) then
return default return default
else else
return math_max(min, value * difficulty) return math.max(min, value * difficulty)
end end
end end
@ -366,15 +344,11 @@ function mobs:register_mob(name, def)
random_sound_timer_min = 3, random_sound_timer_min = 3,
random_sound_timer_max = 10, random_sound_timer_max = 10,
--head code variables --head code variables
--defaults are for the cow's default --defaults are for the cow's default
--because I don't know what else to set them --because I don't know what else to set them
--to :P --to :P
has_head = def.has_head or false,
head_bone = def.head_bone,
--you must use these to adjust the mob's head positions --you must use these to adjust the mob's head positions
--has_head is used as a logic gate (quick easy check) --has_head is used as a logic gate (quick easy check)
@ -444,7 +418,7 @@ function mobs:register_mob(name, def)
--on_detach_child = mob_detach_child, --on_detach_child = mob_detach_child,
on_activate = function(self, staticdata, dtime) on_activate = function(self, staticdata, dtime)
self.object:set_acceleration(vector_new(0,-GRAVITY, 0)) self.object:set_acceleration(vector.new(0,-GRAVITY, 0))
return mobs.mob_activate(self, staticdata, def, dtime) return mobs.mob_activate(self, staticdata, def, dtime)
end, end,
@ -556,10 +530,10 @@ function mobs:register_arrow(name, def)
and def.tail_texture then and def.tail_texture then
--do this to prevent clipping through main entity sprite --do this to prevent clipping through main entity sprite
local pos_adjustment = vector_multiply(vector_normalize(vel), -1) local pos_adjustment = vector.multiply(vector.normalize(vel), -1)
local divider = def.tail_distance_divider or 1 local divider = def.tail_distance_divider or 1
pos_adjustment = vector_divide(pos_adjustment, divider) pos_adjustment = vector.divide(pos_adjustment, divider)
local new_pos = vector_add(pos, pos_adjustment) local new_pos = vector.add(pos, pos_adjustment)
minetest.add_particle({ minetest.add_particle({
pos = new_pos, pos = new_pos,
velocity = {x = 0, y = 0, z = 0}, velocity = {x = 0, y = 0, z = 0},
@ -693,12 +667,12 @@ function mobs:register_egg(mob, desc, background, addegg, no_creative)
if pos if pos
--and within_limits(pos, 0) --and within_limits(pos, 0)
and not minetest_is_protected(pos, placer:get_player_name()) then and not minetest.is_protected(pos, placer:get_player_name()) then
local name = placer:get_player_name() local name = placer:get_player_name()
local privs = minetest.get_player_privs(name) local privs = minetest.get_player_privs(name)
if mod_mobspawners and under.name == "mcl_mobspawners:spawner" then if mod_mobspawners and under.name == "mcl_mobspawners:spawner" then
if minetest_is_protected(pointed_thing.under, name) then if minetest.is_protected(pointed_thing.under, name) then
minetest.record_protection_violation(pointed_thing.under, name) minetest.record_protection_violation(pointed_thing.under, name)
return itemstack return itemstack
end end
@ -743,7 +717,7 @@ function mobs:register_egg(mob, desc, background, addegg, no_creative)
nametag = string.sub(nametag, 1, MAX_MOB_NAME_LENGTH) nametag = string.sub(nametag, 1, MAX_MOB_NAME_LENGTH)
end end
ent.nametag = nametag ent.nametag = nametag
update_tag(ent) --update_tag(ent)
end end
-- if not in creative then take item -- if not in creative then take item

View File

@ -1,12 +1,8 @@
local math_random = math.random local math = math
local math_pi = math.pi local vector = vector
local math_floor = math.floor local string = string
local math_round = math.round
local vector_multiply = vector.multiply local tonumber = tonumber
local vector_add = vector.add
local vector_new = vector.new
local vector_distance = vector.distance
local minetest_yaw_to_dir = minetest.yaw_to_dir local minetest_yaw_to_dir = minetest.yaw_to_dir
local minetest_get_item_group = minetest.get_item_group local minetest_get_item_group = minetest.get_item_group
@ -17,9 +13,8 @@ local minetest_get_node_light = minetest.get_node_light
local DOUBLE_PI = math.pi * 2 local DOUBLE_PI = math.pi * 2
local THIRTY_SECONDTH_PI = DOUBLE_PI * 0.03125 local THIRTY_SECONDTH_PI = DOUBLE_PI * 0.03125
--a simple helper function which is too small to move into movement.lua --a simple helper function which is too small to move into movement.lua
local quick_rotate = function(self,dtime) local function quick_rotate(self,dtime)
self.yaw = self.yaw + THIRTY_SECONDTH_PI self.yaw = self.yaw + THIRTY_SECONDTH_PI
if self.yaw > DOUBLE_PI then if self.yaw > DOUBLE_PI then
self.yaw = self.yaw - DOUBLE_PI self.yaw = self.yaw - DOUBLE_PI
@ -28,46 +23,45 @@ end
--a simple helper function for rounding --a simple helper function for rounding
--http://lua-users.org/wiki/SimpleRound --http://lua-users.org/wiki/SimpleRound
function round2(num, numDecimalPlaces) local function round2(num, numDecimalPlaces)
return tonumber(string.format("%." .. (numDecimalPlaces or 0) .. "f", num)) return tonumber(string.format("%." .. (numDecimalPlaces or 0) .. "f", num))
end end
--[[ --[[
_ _ _ _
| | | | | | | |
| | __ _ _ __ __| | | | __ _ _ __ __| |
| | / _` | '_ \ / _` | | | / _` | '_ \ / _` |
| |___| (_| | | | | (_| | | |___| (_| | | | | (_| |
\_____/\__,_|_| |_|\__,_| \_____/\__,_|_| |_|\__,_|
]]-- ]]--
--this is basically reverse jump_check --this is basically reverse jump_check
local cliff_check = function(self,dtime) local function cliff_check(self,dtime)
--mobs will flip out if they are falling without this --mobs will flip out if they are falling without this
if self.object:get_velocity().y ~= 0 then if self.object:get_velocity().y ~= 0 then
return false return false
end end
local pos = self.object:get_pos() local pos = self.object:get_pos()
local dir = minetest_yaw_to_dir(self.yaw) local dir = minetest_yaw_to_dir(self.yaw)
local collisionbox = self.object:get_properties().collisionbox local collisionbox = self.object:get_properties().collisionbox
local radius = collisionbox[4] + 0.5 local radius = collisionbox[4] + 0.5
dir = vector_multiply(dir,radius) dir = vector.multiply(dir,radius)
local free_fall, blocker = minetest_line_of_sight( local free_fall = minetest_line_of_sight(
{x = pos.x + dir.x, y = pos.y, z = pos.z + dir.z}, {x = pos.x + dir.x, y = pos.y, z = pos.z + dir.z},
{x = pos.x + dir.x, y = pos.y - self.fear_height, z = pos.z + dir.z}) {x = pos.x + dir.x, y = pos.y - self.fear_height, z = pos.z + dir.z})
return free_fall return free_fall
end end
-- state switching logic (stand, walk, run, attacks) -- state switching logic (stand, walk, run, attacks)
local land_state_list_wandering = {"stand", "walk"} local land_state_list_wandering = {"stand", "walk"}
local land_state_switch = function(self, dtime) local function land_state_switch(self, dtime)
--do math before sure not attacking, following, or running away so continue --do math before sure not attacking, following, or running away so continue
--doing random walking for mobs if all states are not met --doing random walking for mobs if all states are not met
@ -93,8 +87,8 @@ local land_state_switch = function(self, dtime)
end end
--ignore everything else if following --ignore everything else if following
if mobs.check_following(self) and if mobs.check_following(self) and
(not self.breed_lookout_timer or (self.breed_lookout_timer and self.breed_lookout_timer == 0)) and (not self.breed_lookout_timer or (self.breed_lookout_timer and self.breed_lookout_timer == 0)) and
(not self.breed_timer or (self.breed_timer and self.breed_timer == 0)) then (not self.breed_timer or (self.breed_timer and self.breed_timer == 0)) then
self.state = "follow" self.state = "follow"
return return
@ -120,7 +114,7 @@ local land_state_switch = function(self, dtime)
end end
-- states are executed here -- states are executed here
local land_state_execution = function(self,dtime) local function land_state_execution(self, dtime)
--[[ -- this is a debug which shows the timer and makes mobs breed 100 times faster --[[ -- this is a debug which shows the timer and makes mobs breed 100 times faster
print(self.breed_timer) print(self.breed_timer)
@ -136,7 +130,6 @@ local land_state_execution = function(self,dtime)
if not self.object:get_properties() then if not self.object:get_properties() then
return return
end end
--timer to time out looking for mate --timer to time out looking for mate
if self.breed_lookout_timer and self.breed_lookout_timer > 0 then if self.breed_lookout_timer and self.breed_lookout_timer > 0 then
@ -176,12 +169,12 @@ local land_state_execution = function(self,dtime)
if velocity.y < 0 then if velocity.y < 0 then
--lua is acting really weird so we have to help it --lua is acting really weird so we have to help it
if round2(self.object:get_acceleration().y, 1) == -self.gravity then if round2(self.object:get_acceleration().y, 1) == -self.gravity then
self.object:set_acceleration(vector_new(0,0,0)) self.object:set_acceleration(vector.new(0,0,0))
mobs.mob_fall_slow(self) mobs.mob_fall_slow(self)
end end
else else
if round2(self.object:get_acceleration().y, 1) == 0 then if round2(self.object:get_acceleration().y, 1) == 0 then
self.object:set_acceleration(vector_new(0,-self.gravity,0)) self.object:set_acceleration(vector.new(0,-self.gravity,0))
end end
end end
end end
@ -206,15 +199,13 @@ local land_state_execution = function(self,dtime)
end end
mobs.lock_yaw(self) mobs.lock_yaw(self)
elseif self.state == "follow" then elseif self.state == "follow" then
--always look at players --always look at players
mobs.set_yaw_while_following(self) mobs.set_yaw_while_following(self)
--check distance --check distance
local distance_from_follow_person = vector_distance(self.object:get_pos(), self.following_person:get_pos()) local distance_from_follow_person = vector.distance(self.object:get_pos(), self.following_person:get_pos())
local distance_2d = mobs.get_2d_distance(self.object:get_pos(), self.following_person:get_pos()) local distance_2d = mobs.get_2d_distance(self.object:get_pos(), self.following_person:get_pos())
--don't push the player if too close --don't push the player if too close
--don't spin around randomly --don't spin around randomly
if self.follow_distance < distance_from_follow_person and self.minimum_follow_distance < distance_2d then if self.follow_distance < distance_from_follow_person and self.minimum_follow_distance < distance_2d then
@ -240,7 +231,7 @@ local land_state_execution = function(self,dtime)
self.walk_timer = math.random(1,6) + math.random() self.walk_timer = math.random(1,6) + math.random()
--set the mob into a random direction --set the mob into a random direction
self.yaw = (math_random() * (math.pi * 2)) self.yaw = (math.random() * (math.pi * 2))
end end
--do animation --do animation
@ -253,15 +244,13 @@ local land_state_execution = function(self,dtime)
local node_in_front_of = mobs.jump_check(self) local node_in_front_of = mobs.jump_check(self)
if node_in_front_of == 1 then if node_in_front_of == 1 then
mobs.jump(self) mobs.jump(self)
--turn if on the edge of cliff
--turn if on the edge of cliff --(this is written like this because unlike
--(this is written like this because unlike --jump_check which simply tells the mob to jump
--jump_check which simply tells the mob to jump --this requires a mob to turn, removing the
--this requires a mob to turn, removing the --ease of a full implementation for it in a single
--ease of a full implementation for it in a single --function)
--function)
elseif node_in_front_of == 2 or (self.fear_height ~= 0 and cliff_check(self,dtime)) then elseif node_in_front_of == 2 or (self.fear_height ~= 0 and cliff_check(self,dtime)) then
--turn 45 degrees if so --turn 45 degrees if so
quick_rotate(self,dtime) quick_rotate(self,dtime)
@ -292,9 +281,7 @@ local land_state_execution = function(self,dtime)
local node_in_front_of = mobs.jump_check(self) local node_in_front_of = mobs.jump_check(self)
if node_in_front_of == 1 then if node_in_front_of == 1 then
mobs.jump(self) mobs.jump(self)
--turn if on the edge of cliff --turn if on the edge of cliff
--(this is written like this because unlike --(this is written like this because unlike
--jump_check which simply tells the mob to jump --jump_check which simply tells the mob to jump
@ -342,7 +329,7 @@ local land_state_execution = function(self,dtime)
mobs.set_velocity(self, self.walk_velocity) mobs.set_velocity(self, self.walk_velocity)
--smoosh together basically --smoosh together basically
if vector_distance(self.object:get_pos(), mate:get_pos()) <= self.breed_distance then if vector.distance(self.object:get_pos(), mate:get_pos()) <= self.breed_distance then
mobs.set_mob_animation(self, "stand") mobs.set_mob_animation(self, "stand")
if self.special_breed_timer == 0 then if self.special_breed_timer == 0 then
self.special_breed_timer = 2 --breeding takes 2 seconds self.special_breed_timer = 2 --breeding takes 2 seconds
@ -353,7 +340,7 @@ local land_state_execution = function(self,dtime)
--pop a baby out, it's a miracle! --pop a baby out, it's a miracle!
local baby_pos = vector.divide(vector.add(self.object:get_pos(), mate:get_pos()), 2) local baby_pos = vector.divide(vector.add(self.object:get_pos(), mate:get_pos()), 2)
local baby_mob = minetest.add_entity(pos, self.name, minetest.serialize({baby = true, grow_up_timer = self.grow_up_goal, bred = true})) minetest.add_entity(baby_pos, self.name, minetest.serialize({baby = true, grow_up_timer = self.grow_up_goal, bred = true}))
mobs.play_sound_specific(self,"item_drop_pickup") mobs.play_sound_specific(self,"item_drop_pickup")
@ -375,14 +362,13 @@ local land_state_execution = function(self,dtime)
mobs.set_velocity(self,0) mobs.set_velocity(self,0)
end end
end end
if float_now then if float_now then
mobs.float(self) mobs.float(self)
else else
local acceleration = self.object:get_acceleration() local acceleration = self.object:get_acceleration()
if acceleration and acceleration.y == 0 then if acceleration and acceleration.y == 0 then
self.object:set_acceleration(vector_new(0,-self.gravity,0)) self.object:set_acceleration(vector.new(0,-self.gravity,0))
end end
end end
end end
@ -391,10 +377,10 @@ end
--[[ --[[
_____ _ _____ _
/ ___| (_) / ___| (_)
\ `--.__ ___ _ __ ___ \ `--.__ ___ _ __ ___
`--. \ \ /\ / / | '_ ` _ \ `--. \ \ /\ / / | '_ ` _ \
/\__/ /\ V V /| | | | | | | /\__/ /\ V V /| | | | | | |
\____/ \_/\_/ |_|_| |_| |_| \____/ \_/\_/ |_|_| |_| |_|
]]-- ]]--
@ -404,7 +390,7 @@ end
-- state switching logic (stand, walk, run, attacks) -- state switching logic (stand, walk, run, attacks)
local swim_state_list_wandering = {"stand", "swim"} local swim_state_list_wandering = {"stand", "swim"}
local swim_state_switch = function(self, dtime) local function swim_state_switch(self, dtime)
self.state_timer = self.state_timer - dtime self.state_timer = self.state_timer - dtime
if self.state_timer <= 0 then if self.state_timer <= 0 then
self.state_timer = math.random(4,10) + math.random() self.state_timer = math.random(4,10) + math.random()
@ -414,41 +400,40 @@ end
--check if a mob needs to turn while swimming --check if a mob needs to turn while swimming
local swim_turn_check = function(self,dtime) local function swim_turn_check(self,dtime)
local pos = self.object:get_pos() local pos = self.object:get_pos()
pos.y = pos.y + 0.1 pos.y = pos.y + 0.1
local dir = minetest_yaw_to_dir(self.yaw) local dir = minetest_yaw_to_dir(self.yaw)
local collisionbox = self.object:get_properties().collisionbox local collisionbox = self.object:get_properties().collisionbox
local radius = collisionbox[4] + 0.5 local radius = collisionbox[4] + 0.5
vector_multiply(dir, radius) vector.multiply(dir, radius)
local test_dir = vector.add(pos,dir) local test_dir = vector.add(pos,dir)
local green_flag_1 = minetest_get_item_group(minetest_get_node(test_dir).name, "solid") ~= 0 local green_flag_1 = minetest_get_item_group(minetest_get_node(test_dir).name, "solid") ~= 0
return(green_flag_1) return green_flag_1
end end
--this is to swap the built in engine acceleration modifier --this is to swap the built in engine acceleration modifier
local swim_physics_swapper = function(self,inside_swim_node) local function swim_physics_swapper(self, inside_swim_node)
--should be swimming, gravity is applied, switch to floating --should be swimming, gravity is applied, switch to floating
if inside_swim_node and self.object:get_acceleration().y ~= 0 then if inside_swim_node and self.object:get_acceleration().y ~= 0 then
self.object:set_acceleration(vector_new(0,0,0)) self.object:set_acceleration(vector.new(0,0,0))
--not be swim, gravity isn't applied, switch to falling --not be swim, gravity isn't applied, switch to falling
elseif not inside_swim_node and self.object:get_acceleration().y == 0 then elseif not inside_swim_node and self.object:get_acceleration().y == 0 then
self.pitch = 0 self.pitch = 0
self.object:set_acceleration(vector_new(0,-self.gravity,0)) self.object:set_acceleration(vector.new(0,-self.gravity,0))
end end
end end
local random_pitch_multiplier = {-1,1} local random_pitch_multiplier = {-1,1}
-- states are executed here -- states are executed here
local swim_state_execution = function(self,dtime) local function swim_state_execution(self, dtime)
local pos = self.object:get_pos() local pos = self.object:get_pos()
@ -465,7 +450,7 @@ local swim_state_execution = function(self,dtime)
end end
--turn gravity on or off --turn gravity on or off
swim_physics_swapper(self,inside_swim_node) swim_physics_swapper(self, inside_swim_node)
--swim properly if inside swim node --swim properly if inside swim node
if inside_swim_node then if inside_swim_node then
@ -482,22 +467,17 @@ local swim_state_execution = function(self,dtime)
end end
mobs.lock_yaw(self) mobs.lock_yaw(self)
elseif self.state == "swim" then elseif self.state == "swim" then
self.walk_timer = self.walk_timer - dtime self.walk_timer = self.walk_timer - dtime
--reset the walk timer --reset the walk timer
if self.walk_timer <= 0 then if self.walk_timer <= 0 then
--re-randomize the walk timer --re-randomize the walk timer
self.walk_timer = math.random(1,6) + math.random() self.walk_timer = math.random(1,6) + math.random()
--set the mob into a random direction --set the mob into a random direction
self.yaw = (math_random() * (math.pi * 2)) self.yaw = (math.random() * (math.pi * 2))
--create a truly random pitch, since there is no easy access to pitch math that I can find --create a truly random pitch, since there is no easy access to pitch math that I can find
self.pitch = math_random() * math.random(1,3) * random_pitch_multiplier[math_random(1,2)] self.pitch = math.random() * math.random(1,3) * random_pitch_multiplier[math.random(1,2)]
end end
--do animation --do animation
@ -535,20 +515,20 @@ end
--[[ --[[
______ _ ______ _
| ___| | | ___| |
| |_ | |_ _ | |_ | |_ _
| _| | | | | | | _| | | | | |
| | | | |_| | | | | | |_| |
\_| |_|\__, | \_| |_|\__, |
__/ | __/ |
|___/ |___/
]]-- ]]--
-- state switching logic (stand, walk, run, attacks) -- state switching logic (stand, walk, run, attacks)
local fly_state_list_wandering = {"stand", "fly"} local fly_state_list_wandering = {"stand", "fly"}
local fly_state_switch = function(self, dtime) local function fly_state_switch(self, dtime)
if self.hostile and self.attacking then if self.hostile and self.attacking then
self.state = "attack" self.state = "attack"
@ -564,41 +544,41 @@ end
--check if a mob needs to turn while flying --check if a mob needs to turn while flying
local fly_turn_check = function(self,dtime) local function fly_turn_check(self, dtime)
local pos = self.object:get_pos() local pos = self.object:get_pos()
pos.y = pos.y + 0.1 pos.y = pos.y + 0.1
local dir = minetest_yaw_to_dir(self.yaw) local dir = minetest_yaw_to_dir(self.yaw)
local collisionbox = self.object:get_properties().collisionbox local collisionbox = self.object:get_properties().collisionbox
local radius = collisionbox[4] + 0.5 local radius = collisionbox[4] + 0.5
vector_multiply(dir, radius) vector.multiply(dir, radius)
local test_dir = vector.add(pos,dir) local test_dir = vector.add(pos,dir)
local green_flag_1 = minetest_get_item_group(minetest_get_node(test_dir).name, "solid") ~= 0 local green_flag_1 = minetest_get_item_group(minetest_get_node(test_dir).name, "solid") ~= 0
return(green_flag_1) return green_flag_1
end end
--this is to swap the built in engine acceleration modifier --this is to swap the built in engine acceleration modifier
local fly_physics_swapper = function(self,inside_fly_node) local function fly_physics_swapper(self, inside_fly_node)
--should be flyming, gravity is applied, switch to floating --should be flyming, gravity is applied, switch to floating
if inside_fly_node and self.object:get_acceleration().y ~= 0 then if inside_fly_node and self.object:get_acceleration().y ~= 0 then
self.object:set_acceleration(vector_new(0,0,0)) self.object:set_acceleration(vector.new(0,0,0))
--not be fly, gravity isn't applied, switch to falling --not be fly, gravity isn't applied, switch to falling
elseif not inside_fly_node and self.object:get_acceleration().y == 0 then elseif not inside_fly_node and self.object:get_acceleration().y == 0 then
self.pitch = 0 self.pitch = 0
self.object:set_acceleration(vector_new(0,-self.gravity,0)) self.object:set_acceleration(vector.new(0,-self.gravity,0))
end end
end end
local random_pitch_multiplier = {-1,1} local random_pitch_multiplier = {-1,1}
-- states are executed here -- states are executed here
local fly_state_execution = function(self,dtime) local function fly_state_execution(self, dtime)
local pos = self.object:get_pos() local pos = self.object:get_pos()
pos.y = pos.y + 0.1 pos.y = pos.y + 0.1
local current_node = minetest_get_node(pos).name local current_node = minetest_get_node(pos).name
@ -635,15 +615,13 @@ local fly_state_execution = function(self,dtime)
--reset the walk timer --reset the walk timer
if self.walk_timer <= 0 then if self.walk_timer <= 0 then
--re-randomize the walk timer --re-randomize the walk timer
self.walk_timer = math.random(1,6) + math.random() self.walk_timer = math.random(1,6) + math.random()
--set the mob into a random direction --set the mob into a random direction
self.yaw = (math_random() * (math.pi * 2)) self.yaw = (math.random() * (math.pi * 2))
--create a truly random pitch, since there is no easy access to pitch math that I can find --create a truly random pitch, since there is no easy access to pitch math that I can find
self.pitch = math_random() * math.random(1,3) * random_pitch_multiplier[math_random(1,2)] self.pitch = math.random() * math.random(1,3) * random_pitch_multiplier[math.random(1,2)]
end end
--do animation --do animation
@ -663,9 +641,7 @@ local fly_state_execution = function(self,dtime)
--enable rotation locking --enable rotation locking
mobs.movement_rotation_lock(self) mobs.movement_rotation_lock(self)
elseif self.state == "attack" then elseif self.state == "attack" then
--execute mob attack type --execute mob attack type
--if self.attack_type == "explode" then --if self.attack_type == "explode" then
@ -697,40 +673,39 @@ end
--[[ --[[
___ ___
|_ | |_ |
| |_ _ _ __ ___ _ __ | |_ _ _ __ ___ _ __
| | | | | '_ ` _ \| '_ \ | | | | | '_ ` _ \| '_ \
/\__/ / |_| | | | | | | |_) | /\__/ / |_| | | | | | | |_) |
\____/ \__,_|_| |_| |_| .__/ \____/ \__,_|_| |_| |_| .__/
| | | |
|_| |_|
]]-- ]]--
--check if a mob needs to turn while jumping --check if a mob needs to turn while jumping
local jump_turn_check = function(self,dtime) --[[local function jump_turn_check(self, dtime)
local pos = self.object:get_pos()
pos.y = pos.y + 0.1
local dir = minetest_yaw_to_dir(self.yaw)
local pos = self.object:get_pos() local collisionbox = self.object:get_properties().collisionbox
pos.y = pos.y + 0.1
local dir = minetest_yaw_to_dir(self.yaw)
local collisionbox = self.object:get_properties().collisionbox
local radius = collisionbox[4] + 0.5 local radius = collisionbox[4] + 0.5
vector_multiply(dir, radius) vector.multiply(dir, radius)
local test_dir = vector.add(pos,dir) local test_dir = vector.add(pos,dir)
local green_flag_1 = minetest_get_item_group(minetest_get_node(test_dir).name, "solid") ~= 0 local green_flag_1 = minetest_get_item_group(minetest_get_node(test_dir).name, "solid") ~= 0
return(green_flag_1) return green_flag_1
end end]]
-- state switching logic (stand, jump, run, attacks) -- state switching logic (stand, jump, run, attacks)
local jump_state_list_wandering = {"stand", "jump"} local jump_state_list_wandering = {"stand", "jump"}
local jump_state_switch = function(self, dtime) local function jump_state_switch(self, dtime)
self.state_timer = self.state_timer - dtime self.state_timer = self.state_timer - dtime
if self.state_timer <= 0 then if self.state_timer <= 0 then
self.state_timer = math.random(4,10) + math.random() self.state_timer = math.random(4,10) + math.random()
@ -739,8 +714,8 @@ local jump_state_switch = function(self, dtime)
end end
-- states are executed here -- states are executed here
local jump_state_execution = function(self,dtime) local function jump_state_execution(self, dtime)
local node_in_front_of = mobs.jump_check(self)
local pos = self.object:get_pos() local pos = self.object:get_pos()
local collisionbox = self.object:get_properties().collisionbox local collisionbox = self.object:get_properties().collisionbox
--get the center of the mob --get the center of the mob
@ -775,7 +750,7 @@ local jump_state_execution = function(self,dtime)
self.walk_timer = math.random(1,6) + math.random() self.walk_timer = math.random(1,6) + math.random()
--set the mob into a random direction --set the mob into a random direction
self.yaw = (math_random() * (math.pi * 2)) self.yaw = (math.random() * (math.pi * 2))
end end
--do animation --do animation
@ -793,15 +768,10 @@ local jump_state_execution = function(self,dtime)
mobs.jump_move(self,self.walk_velocity) mobs.jump_move(self,self.walk_velocity)
elseif self.state == "run" then elseif self.state == "run" then
print("run") print("run")
elseif self.state == "attack" then elseif self.state == "attack" then
print("attack") print("attack")
end
end
if float_now then if float_now then
mobs.float(self) mobs.float(self)
end end
@ -811,18 +781,18 @@ end
--[[ --[[
___ ___ _ _ _ ___ ___ _ _ _
| \/ | (_) | | (_) | \/ | (_) | | (_)
| . . | __ _ _ _ __ | | ___ __ _ _ ___ | . . | __ _ _ _ __ | | ___ __ _ _ ___
| |\/| |/ _` | | '_ \ | | / _ \ / _` | |/ __| | |\/| |/ _` | | '_ \ | | / _ \ / _` | |/ __|
| | | | (_| | | | | | | |___| (_) | (_| | | (__ | | | | (_| | | | | | | |___| (_) | (_| | | (__
\_| |_/\__,_|_|_| |_| \_____/\___/ \__, |_|\___| \_| |_/\__,_|_|_| |_| \_____/\___/ \__, |_|\___|
__/ | __/ |
|___/ |___/
]]-- ]]--
--the main loop --the main loop
mobs.mob_step = function(self, dtime) function mobs.mob_step(self, dtime)
--do not continue if non-existent --do not continue if non-existent
if not self or not self.object or not self.object:get_luaentity() then if not self or not self.object or not self.object:get_luaentity() then
@ -859,13 +829,13 @@ mobs.mob_step = function(self, dtime)
end end
--color modifier which coincides with the pause_timer --color modifier which coincides with the pause_timer
if self.old_health and self.health < self.old_health then if self.old_health and self.health < self.old_health then
self.object:set_texture_mod("^[colorize:red:120") self.object:set_texture_mod("^[colorize:red:120")
--fix double death sound --fix double death sound
if self.health > 0 then if self.health > 0 then
mobs.play_sound(self,"damage") mobs.play_sound(self,"damage")
end end
end end
self.old_health = self.health self.old_health = self.health
--do death logic (animation, poof, explosion, etc) --do death logic (animation, poof, explosion, etc)
@ -916,7 +886,6 @@ mobs.mob_step = function(self, dtime)
elseif self.breath < self.breath_max then elseif self.breath < self.breath_max then
self.breath = self.breath + dtime self.breath = self.breath + dtime
--clean timer reset --clean timer reset
if self.breath > self.breath_max then if self.breath > self.breath_max then
self.breath = self.breath_max self.breath = self.breath_max
@ -948,10 +917,6 @@ mobs.mob_step = function(self, dtime)
end end
end end
--baby grows up --baby grows up
if self.baby then if self.baby then
--print(self.grow_up_timer) --print(self.grow_up_timer)
@ -968,8 +933,6 @@ mobs.mob_step = function(self, dtime)
mobs.baby_grow_up(self) mobs.baby_grow_up(self)
end end
end end
--do custom mob instructions --do custom mob instructions
if self.do_custom then if self.do_custom then
@ -1015,7 +978,7 @@ mobs.mob_step = function(self, dtime)
self.memory = self.memory - dtime self.memory = self.memory - dtime
--get if memory player is within viewing range --get if memory player is within viewing range
if self.attacking and self.attacking:is_player() then if self.attacking and self.attacking:is_player() then
local distance = vector_distance(self.object:get_pos(), self.attacking:get_pos()) local distance = vector.distance(self.object:get_pos(), self.attacking:get_pos())
if distance > self.view_range then if distance > self.view_range then
self.memory = 0 self.memory = 0
end end
@ -1090,7 +1053,7 @@ mobs.mob_step = function(self, dtime)
--jump only (like slimes) --jump only (like slimes)
if self.jump_only then if self.jump_only then
jump_state_switch(self, dtime) jump_state_switch(self, dtime)
jump_state_execution(self, dtime) jump_state_execution(self, dtime)
--swimming --swimming
elseif self.swim then elseif self.swim then
swim_state_switch(self, dtime) swim_state_switch(self, dtime)
@ -1124,28 +1087,22 @@ mobs.mob_step = function(self, dtime)
--overrides absolutely everything --overrides absolutely everything
--mobs get stuck in cobwebs like players --mobs get stuck in cobwebs like players
if not self.ignores_cobwebs then if not self.ignores_cobwebs then
local pos = self.object:get_pos() local pos = self.object:get_pos()
local node = pos and minetest_get_node(pos).name local node = pos and minetest_get_node(pos).name
if node == "mcl_core:cobweb" then if node == "mcl_core:cobweb" then
--fight the rest of the api --fight the rest of the api
if self.object:get_acceleration().y ~= 0 then if self.object:get_acceleration().y ~= 0 then
self.object:set_acceleration(vector_new(0,0,0)) self.object:set_acceleration(vector.new(0,0,0))
end end
mobs.stick_in_cobweb(self) mobs.stick_in_cobweb(self)
self.was_stuck_in_cobweb = true self.was_stuck_in_cobweb = true
else else
--do not override other functions --do not override other functions
if self.was_stuck_in_cobweb == true then if self.was_stuck_in_cobweb == true then
--return the mob back to normal --return the mob back to normal
self.was_stuck_in_cobweb = nil self.was_stuck_in_cobweb = nil
if self.object:get_acceleration().y == 0 and not self.swim and not self.fly then if self.object:get_acceleration().y == 0 and not self.swim and not self.fly then
self.object:set_acceleration(vector_new(0,-self.gravity,0)) self.object:set_acceleration(vector.new(0,-self.gravity,0))
end end
end end
end end

View File

@ -1,7 +1,7 @@
local math_pi = math.pi local math = math
local math_floor = math.floor local vector = vector
local math_random = math.random
local HALF_PI = math_pi/2 local HALF_PI = math.pi/2
local vector_direction = vector.direction local vector_direction = vector.direction
@ -48,8 +48,7 @@ mobs.set_mob_animation = function(self, anim, fixed_frame)
self.animation[anim .. "_speed"] or self.animation.speed_normal or 15, self.animation[anim .. "_speed"] or self.animation.speed_normal or 15,
0, self.animation[anim .. "_loop"] ~= false) 0, self.animation[anim .. "_loop"] ~= false)
self.current_animation = anim
self.current_animation = anim
end end
@ -65,14 +64,14 @@ mobs.death_effect = function(pos, yaw, collisionbox, rotate)
max = { x = 0.5, y = 0.5, z = 0.5 } max = { x = 0.5, y = 0.5, z = 0.5 }
end end
if rotate then if rotate then
min = vector.rotate(min, {x=0, y=yaw, z=math_pi/2}) min = vector.rotate(min, {x=0, y=yaw, z=math.pi/2})
max = vector.rotate(max, {x=0, y=yaw, z=math_pi/2}) max = vector.rotate(max, {x=0, y=yaw, z=math.pi/2})
min, max = vector.sort(min, max) min, max = vector.sort(min, max)
min = vector.multiply(min, 0.5) min = vector.multiply(min, 0.5)
max = vector.multiply(max, 0.5) max = vector.multiply(max, 0.5)
end end
minetest_add_particlespawner({ minetest.add_particlespawner({
amount = 50, amount = 50,
time = 0.001, time = 0.001,
minpos = vector.add(pos, min), minpos = vector.add(pos, min),
@ -88,7 +87,7 @@ mobs.death_effect = function(pos, yaw, collisionbox, rotate)
texture = "mcl_particles_mob_death.png^[colorize:#000000:255", texture = "mcl_particles_mob_death.png^[colorize:#000000:255",
}) })
minetest_sound_play("mcl_mobs_mob_poof", { minetest.sound_play("mcl_mobs_mob_poof", {
pos = pos, pos = pos,
gain = 1.0, gain = 1.0,
max_hear_distance = 8, max_hear_distance = 8,
@ -99,7 +98,6 @@ end
--this allows auto facedir rotation while making it so mobs --this allows auto facedir rotation while making it so mobs
--don't look like wet noodles flopping around --don't look like wet noodles flopping around
mobs.movement_rotation_lock = function(self) mobs.movement_rotation_lock = function(self)
local current_engine_yaw = self.object:get_yaw() local current_engine_yaw = self.object:get_yaw()
local current_lua_yaw = self.yaw local current_lua_yaw = self.yaw
@ -159,7 +157,7 @@ local calculate_pitch = function(self)
return false return false
end end
return(minetest_dir_to_yaw(vector_new(vector_distance(vector_new(pos.x,0,pos.z),vector_new(pos2.x,0,pos2.z)),0,pos.y - pos2.y)) + HALF_PI) return minetest_dir_to_yaw(vector_new(vector_distance(vector_new(pos.x,0,pos.z),vector_new(pos2.x,0,pos2.z)),0,pos.y - pos2.y)) + HALF_PI
end end
--this is a helper function used to make mobs pitch rotation dynamically flow when flying/swimming --this is a helper function used to make mobs pitch rotation dynamically flow when flying/swimming

View File

@ -1,11 +1,11 @@
local vector_direction = vector.direction local vector_direction = vector.direction
local minetest_dir_to_yaw = minetest.dir_to_yaw --local minetest_dir_to_yaw = minetest.dir_to_yaw
local vector_distance = vector.distance local vector_distance = vector.distance
local vector_multiply = vector.multiply local vector_multiply = vector.multiply
local math_random = math.random local math_random = math.random
--[[ --[[
_ _ _ _ _ _ _ _
| | | | | | | | | | | | | | | |
| | | | __ _ _ __ __| | | | | | | | __ _ _ __ __| | | |
| | | | / _` | '_ \ / _` | | | | | | | / _` | '_ \ / _` | | |
@ -16,14 +16,14 @@ local math_random = math.random
--[[ --[[
_____ _ _ _____ _ _
| ___| | | | | | ___| | | | |
| |____ ___ __ | | ___ __| | ___ | |____ ___ __ | | ___ __| | ___
| __\ \/ / '_ \| |/ _ \ / _` |/ _ \ | __\ \/ / '_ \| |/ _ \ / _` |/ _ \
| |___> <| |_) | | (_) | (_| | __/ | |___> <| |_) | | (_) | (_| | __/
\____/_/\_\ .__/|_|\___/ \__,_|\___| \____/_/\_\ .__/|_|\___/ \__,_|\___|
| | | |
|_| |_|
]]-- ]]--
mobs.explode_attack_walk = function(self,dtime) mobs.explode_attack_walk = function(self,dtime)
@ -74,7 +74,6 @@ mobs.explode_attack_walk = function(self,dtime)
if node_in_front_of == 1 then if node_in_front_of == 1 then
mobs.jump(self) mobs.jump(self)
end end
--do biggening explosion thing --do biggening explosion thing
if self.explosion_animation and self.explosion_animation > self.explosion_timer then if self.explosion_animation and self.explosion_animation > self.explosion_timer then
@ -102,10 +101,10 @@ end
--[[ --[[
______ _ ______ _
| ___ \ | | | ___ \ | |
| |_/ / _ _ __ ___| |__ | |_/ / _ _ __ ___| |__
| __/ | | | '_ \ / __| '_ \ | __/ | | | '_ \ / __| '_ \
| | | |_| | | | | (__| | | | | | | |_| | | | | (__| | | |
\_| \__,_|_| |_|\___|_| |_| \_| \__,_|_| |_|\___|_| |_|
]]-- ]]--
@ -113,7 +112,6 @@ ______ _
mobs.punch_attack_walk = function(self,dtime) mobs.punch_attack_walk = function(self,dtime)
--this needs an exception --this needs an exception
if self.attacking == nil or not self.attacking:is_player() then if self.attacking == nil or not self.attacking:is_player() then
self.attacking = nil self.attacking = nil
@ -187,14 +185,14 @@ end
--[[ --[[
______ _ _ _ _ ______ _ _ _ _
| ___ \ (_) | | (_) | | ___ \ (_) | | (_) |
| |_/ / __ ___ _ ___ ___| |_ _| | ___ | |_/ / __ ___ _ ___ ___| |_ _| | ___
| __/ '__/ _ \| |/ _ \/ __| __| | |/ _ \ | __/ '__/ _ \| |/ _ \/ __| __| | |/ _ \
| | | | | (_) | | __/ (__| |_| | | __/ | | | | | (_) | | __/ (__| |_| | | __/
\_| |_| \___/| |\___|\___|\__|_|_|\___| \_| |_| \___/| |\___|\___|\__|_|_|\___|
_/ | _/ |
|__/ |__/
]]-- ]]--
@ -255,40 +253,39 @@ end
--[[ --[[
_ ______ _ _ _ ______ _ _
| | | ___| | | | | | | ___| | | |
| | | |_ | |_ _ | | | | | |_ | |_ _ | |
| | | _| | | | | | | | | | | _| | | | | | | |
|_| | | | | |_| | |_| |_| | | | | |_| | |_|
(_) \_| |_|\__, | (_) (_) \_| |_|\__, | (_)
__/ | __/ |
|___/ |___/
]]-- ]]--
--[[ --[[
______ _ _ _ _ ______ _ _ _ _
| ___ \ (_) | | (_) | | ___ \ (_) | | (_) |
| |_/ / __ ___ _ ___ ___| |_ _| | ___ | |_/ / __ ___ _ ___ ___| |_ _| | ___
| __/ '__/ _ \| |/ _ \/ __| __| | |/ _ \ | __/ '__/ _ \| |/ _ \/ __| __| | |/ _ \
| | | | | (_) | | __/ (__| |_| | | __/ | | | | | (_) | | __/ (__| |_| | | __/
\_| |_| \___/| |\___|\___|\__|_|_|\___| \_| |_| \___/| |\___|\___|\__|_|_|\___|
_/ | _/ |
|__/ |__/
]]-- ]]--
local random_pitch_multiplier = {-1,1} local random_pitch_multiplier = {-1,1}
mobs.projectile_attack_fly = function(self, dtime) mobs.projectile_attack_fly = function(self, dtime)
--this needs an exception --this needs an exception
if self.attacking == nil or not self.attacking:is_player() then if self.attacking == nil or not self.attacking:is_player() then
self.attacking = nil self.attacking = nil
return return
end end
--this is specifically for random ghast movement --this is specifically for random ghast movement
if self.fly_random_while_attack then if self.fly_random_while_attack then
@ -315,7 +312,7 @@ mobs.projectile_attack_fly = function(self, dtime)
local distance_from_attacking = vector_distance(self.object:get_pos(), self.attacking:get_pos()) local distance_from_attacking = vector_distance(self.object:get_pos(), self.attacking:get_pos())
if distance_from_attacking >= self.reach then if distance_from_attacking >= self.reach then
mobs.set_pitch_while_attacking(self) mobs.set_pitch_while_attacking(self)
mobs.set_fly_velocity(self, self.run_velocity) mobs.set_fly_velocity(self, self.run_velocity)
mobs.set_mob_animation(self,"run") mobs.set_mob_animation(self,"run")

View File

@ -1,4 +1,7 @@
local disable_physics = function(object, luaentity, ignore_check, reset_movement) local math = math
local vector = vector
local function disable_physics(object, luaentity, ignore_check, reset_movement)
if luaentity.physical_state == true or ignore_check == true then if luaentity.physical_state == true or ignore_check == true then
luaentity.physical_state = false luaentity.physical_state = false
object:set_properties({ object:set_properties({
@ -12,7 +15,7 @@ local disable_physics = function(object, luaentity, ignore_check, reset_movement
end end
----For Water Flowing: ----For Water Flowing:
local enable_physics = function(object, luaentity, ignore_check) local function enable_physics(object, luaentity, ignore_check)
if luaentity.physical_state == false or ignore_check == true then if luaentity.physical_state == false or ignore_check == true then
luaentity.physical_state = true luaentity.physical_state = true
object:set_properties({ object:set_properties({
@ -272,7 +275,7 @@ local falling = function(self, pos)
self.object:set_acceleration({ self.object:set_acceleration({
x = 0, x = 0,
y = -self.fall_speed / (math_max(1, v.y) ^ 2), y = -self.fall_speed / (math.max(1, v.y) ^ 2),
z = 0 z = 0
}) })
end end
@ -503,9 +506,9 @@ local follow_flop = function(self)
if sdef and sdef.walkable then if sdef and sdef.walkable then
mob_sound(self, "flop") mob_sound(self, "flop")
self.object:set_velocity({ self.object:set_velocity({
x = math_random(-FLOP_HOR_SPEED, FLOP_HOR_SPEED), x = math.random(-FLOP_HOR_SPEED, FLOP_HOR_SPEED),
y = FLOP_HEIGHT, y = FLOP_HEIGHT,
z = math_random(-FLOP_HOR_SPEED, FLOP_HOR_SPEED), z = math.random(-FLOP_HOR_SPEED, FLOP_HOR_SPEED),
}) })
end end
@ -987,7 +990,7 @@ local check_for_death = function(self, cause, cmi_cause)
item_drop(self, cooked, looting) item_drop(self, cooked, looting)
if mod_experience and ((not self.child) or self.type ~= "animal") and (minetest_get_us_time() - self.xp_timestamp <= 5000000) then if mod_experience and ((not self.child) or self.type ~= "animal") and (minetest_get_us_time() - self.xp_timestamp <= 5000000) then
mcl_experience.throw_experience(self.object:get_pos(), math_random(self.xp_min, self.xp_max)) mcl_experience.throw_experience(self.object:get_pos(), math.random(self.xp_min, self.xp_max))
end end
end end
end end
@ -1361,7 +1364,7 @@ local do_attack = function(self, player)
self.state = "attack" self.state = "attack"
-- TODO: Implement war_cry sound without being annoying -- TODO: Implement war_cry sound without being annoying
--if math_random(0, 100) < 90 then --if math.random(0, 100) < 90 then
--mob_sound(self, "war_cry", true) --mob_sound(self, "war_cry", true)
--end --end
end end
@ -1396,7 +1399,7 @@ local mob_sound = function(self, soundname, is_opinion, fixed_pitch)
pitch = base_pitch pitch = base_pitch
end end
-- randomize the pitch a bit -- randomize the pitch a bit
pitch = pitch + math_random(-10, 10) * 0.005 pitch = pitch + math.random(-10, 10) * 0.005
end end
minetest_sound_play(sound, { minetest_sound_play(sound, {
object = self.object, object = self.object,
@ -1699,7 +1702,7 @@ local do_env_damage = function(self)
end end
if drowning then if drowning then
self.breath = math_max(0, self.breath - 1) self.breath = math.max(0, self.breath - 1)
effect(pos, 2, "bubble.png", nil, nil, 1, nil) effect(pos, 2, "bubble.png", nil, nil, 1, nil)
if self.breath <= 0 then if self.breath <= 0 then
@ -2044,7 +2047,7 @@ local breed = function(self)
-- Give XP -- Give XP
if mod_experience then if mod_experience then
mcl_experience.throw_experience(pos, math_random(1, 7)) mcl_experience.throw_experience(pos, math.random(1, 7))
end end
-- custom breed function -- custom breed function
@ -2061,7 +2064,7 @@ local breed = function(self)
-- Use texture of one of the parents -- Use texture of one of the parents
local p = math_random(1, 2) local p = math.random(1, 2)
if p == 1 then if p == 1 then
ent_c.base_texture = parent1.base_texture ent_c.base_texture = parent1.base_texture
else else
@ -2091,7 +2094,7 @@ local replace = function(self, pos)
or not self.replace_what or not self.replace_what
or self.child == true or self.child == true
or self.object:get_velocity().y ~= 0 or self.object:get_velocity().y ~= 0
or math_random(1, self.replace_rate) > 1 then or math.random(1, self.replace_rate) > 1 then
return return
end end
@ -2099,7 +2102,7 @@ local replace = function(self, pos)
if type(self.replace_what[1]) == "table" then if type(self.replace_what[1]) == "table" then
local num = math_random(#self.replace_what) local num = math.random(#self.replace_what)
what = self.replace_what[num][1] or "" what = self.replace_what[num][1] or ""
with = self.replace_what[num][2] or "" with = self.replace_what[num][2] or ""
@ -2163,7 +2166,7 @@ function do_states(self)
if self.state == "stand" then if self.state == "stand" then
if math_random(1, 4) == 1 then if math.random(1, 4) == 1 then
local lp = nil local lp = nil
local s = self.object:get_pos() local s = self.object:get_pos()
@ -2189,7 +2192,7 @@ function do_states(self)
if lp.x > s.x then yaw = yaw + math_pi end if lp.x > s.x then yaw = yaw + math_pi end
else else
yaw = yaw + math_random(-0.5, 0.5) yaw = yaw + math.random(-0.5, 0.5)
end end
yaw = set_yaw(self, yaw, 8) yaw = set_yaw(self, yaw, 8)
@ -2204,7 +2207,7 @@ function do_states(self)
if self.walk_chance ~= 0 if self.walk_chance ~= 0
and self.facing_fence ~= true and self.facing_fence ~= true
and math_random(1, 100) <= self.walk_chance and math.random(1, 100) <= self.walk_chance
and is_at_cliff_or_danger(self) == false then and is_at_cliff_or_danger(self) == false then
set_velocity(self, self.walk_velocity) set_velocity(self, self.walk_velocity)
@ -2254,7 +2257,7 @@ function do_states(self)
{x = s.x + 5, y = s.y + 1, z = s.z + 5}, {x = s.x + 5, y = s.y + 1, z = s.z + 5},
{"group:solid"}) {"group:solid"})
lp = #lp > 0 and lp[math_random(#lp)] lp = #lp > 0 and lp[math.random(#lp)]
-- did we find land? -- did we find land?
if lp then if lp then
@ -2280,8 +2283,8 @@ function do_states(self)
else else
-- Randomly turn -- Randomly turn
if math_random(1, 100) <= 30 then if math.random(1, 100) <= 30 then
yaw = yaw + math_random(-0.5, 0.5) yaw = yaw + math.random(-0.5, 0.5)
yaw = set_yaw(self, yaw, 8) yaw = set_yaw(self, yaw, 8)
end end
end end
@ -2289,9 +2292,9 @@ function do_states(self)
yaw = set_yaw(self, yaw, 8) yaw = set_yaw(self, yaw, 8)
-- otherwise randomly turn -- otherwise randomly turn
elseif math_random(1, 100) <= 30 then elseif math.random(1, 100) <= 30 then
yaw = yaw + math_random(-0.5, 0.5) yaw = yaw + math.random(-0.5, 0.5)
yaw = set_yaw(self, yaw, 8) yaw = set_yaw(self, yaw, 8)
end end
@ -2302,7 +2305,7 @@ function do_states(self)
end end
if self.facing_fence == true if self.facing_fence == true
or cliff_or_danger or cliff_or_danger
or math_random(1, 100) <= 30 then or math.random(1, 100) <= 30 then
set_velocity(self, 0) set_velocity(self, 0)
self.state = "stand" self.state = "stand"
@ -2602,7 +2605,7 @@ function do_states(self)
self.timer = 0 self.timer = 0
if self.double_melee_attack if self.double_melee_attack
and math_random(1, 2) == 1 then and math.random(1, 2) == 1 then
set_animation(self, "punch2") set_animation(self, "punch2")
else else
set_animation(self, "punch") set_animation(self, "punch")
@ -2669,7 +2672,7 @@ function do_states(self)
if self.shoot_interval if self.shoot_interval
and self.timer > self.shoot_interval and self.timer > self.shoot_interval
and not minetest_raycast(p, self.attack:get_pos(), false, false):next() and not minetest_raycast(p, self.attack:get_pos(), false, false):next()
and math_random(1, 100) <= 60 then and math.random(1, 100) <= 60 then
self.timer = 0 self.timer = 0
set_animation(self, "shoot") set_animation(self, "shoot")
@ -2759,7 +2762,7 @@ end
-- Code to execute before custom on_rightclick handling -- Code to execute before custom on_rightclick handling
local on_rightclick_prefix = function(self, clicker) local function on_rightclick_prefix(self, clicker)
local item = clicker:get_wielded_item() local item = clicker:get_wielded_item()
-- Name mob with nametag -- Name mob with nametag
@ -2785,17 +2788,17 @@ local on_rightclick_prefix = function(self, clicker)
return false return false
end end
local create_mob_on_rightclick = function(on_rightclick) --[[local function create_mob_on_rightclick(on_rightclick)
return function(self, clicker) return function(self, clicker)
local stop = on_rightclick_prefix(self, clicker) local stop = on_rightclick_prefix(self, clicker)
if (not stop) and (on_rightclick) then if (not stop) and (on_rightclick) then
on_rightclick(self, clicker) on_rightclick(self, clicker)
end end
end end
end end]]
-- set and return valid yaw -- set and return valid yaw
local set_yaw = function(self, yaw, delay, dtime) local function set_yaw(self, yaw, delay, dtime)
if not yaw or yaw ~= yaw then if not yaw or yaw ~= yaw then
yaw = 0 yaw = 0
@ -2805,7 +2808,7 @@ local set_yaw = function(self, yaw, delay, dtime)
if delay == 0 then if delay == 0 then
if self.shaking and dtime then if self.shaking and dtime then
yaw = yaw + (math_random() * 2 - 1) * 5 * dtime yaw = yaw + (math.random() * 2 - 1) * 5 * dtime
end end
self.yaw(yaw) self.yaw(yaw)
update_roll(self) update_roll(self)
@ -2825,8 +2828,7 @@ function mobs:yaw(self, yaw, delay, dtime)
end end
mob_step = function() --mob_step = function()
--if self.state == "die" then --if self.state == "die" then
-- print("need custom die stop moving thing") -- print("need custom die stop moving thing")
-- return -- return
@ -2901,7 +2903,7 @@ mob_step = function()
--end --end
-- mob plays random sound at times -- mob plays random sound at times
--if math_random(1, 70) == 1 then --if math.random(1, 70) == 1 then
-- mob_sound(self, "random", true) -- mob_sound(self, "random", true)
--end --end
@ -2934,11 +2936,11 @@ mob_step = function()
--if is_at_water_danger(self) and self.state ~= "attack" then --if is_at_water_danger(self) and self.state ~= "attack" then
-- if math_random(1, 10) <= 6 then -- if math.random(1, 10) <= 6 then
-- set_velocity(self, 0) -- set_velocity(self, 0)
-- self.state = "stand" -- self.state = "stand"
-- set_animation(self, "stand") -- set_animation(self, "stand")
-- yaw = yaw + math_random(-0.5, 0.5) -- yaw = yaw + math.random(-0.5, 0.5)
-- yaw = set_yaw(self, yaw, 8) -- yaw = set_yaw(self, yaw, 8)
-- end -- end
--end --end
@ -2982,7 +2984,7 @@ mob_step = function()
mcl_burning.extinguish(self.object) mcl_burning.extinguish(self.object)
self.object:remove() self.object:remove()
elseif self.lifetimer <= 10 then elseif self.lifetimer <= 10 then
if math_random(10) < 4 then if math.random(10) < 4 then
self.despawn_immediately = true self.despawn_immediately = true
else else
self.lifetimer = 20 self.lifetimer = 20
@ -2991,4 +2993,4 @@ mob_step = function()
end end
]]-- ]]--
end --end

View File

@ -1,14 +1,13 @@
local minetest_get_objects_inside_radius = minetest.get_objects_inside_radius local minetest_get_objects_inside_radius = minetest.get_objects_inside_radius
local vector_distance = vector.distance local vector = vector
--check to see if someone nearby has some tasty food --check to see if someone nearby has some tasty food
mobs.check_following = function(self) -- returns true or false mobs.check_following = function(self) -- returns true or false
--ignore --ignore
if not self.follow then if not self.follow then
self.following_person = nil self.following_person = nil
return(false) return false
end end
--hey look, this thing works for passive mobs too! --hey look, this thing works for passive mobs too!
@ -20,20 +19,20 @@ mobs.check_following = function(self) -- returns true or false
--safety check --safety check
if not stack then if not stack then
self.following_person = nil self.following_person = nil
return(false) return false
end end
local item_name = stack:get_name() local item_name = stack:get_name()
--all checks have passed, that guy has some good looking food --all checks have passed, that guy has some good looking food
if item_name == self.follow then if item_name == self.follow then
self.following_person = follower self.following_person = follower
return(true) return true
end end
end end
--everything failed --everything failed
self.following_person = nil self.following_person = nil
return(false) return false
end end
--a function which attempts to make mobs enter --a function which attempts to make mobs enter
@ -42,30 +41,30 @@ mobs.enter_breed_state = function(self,clicker)
--do not breed if baby --do not breed if baby
if self.baby then if self.baby then
return(false) return false
end end
--do not do anything if looking for mate or --do not do anything if looking for mate or
--if cooling off from breeding --if cooling off from breeding
if self.breed_lookout_timer > 0 or self.breed_timer > 0 then if self.breed_lookout_timer > 0 or self.breed_timer > 0 then
return(false) return false
end end
--if this is caught, that means something has gone --if this is caught, that means something has gone
--seriously wrong --seriously wrong
if not clicker or not clicker:is_player() then if not clicker or not clicker:is_player() then
return(false) return false
end end
local stack = clicker:get_wielded_item() local stack = clicker:get_wielded_item()
--safety check --safety check
if not stack then if not stack then
return(false) return false
end end
local item_name = stack:get_name() local item_name = stack:get_name()
--all checks have passed, that guy has some good looking food --all checks have passed, that guy has some good looking food
if item_name == self.follow then if item_name == self.follow then
if not minetest.is_creative_enabled(clicker:get_player_name()) then if not minetest.is_creative_enabled(clicker:get_player_name()) then
stack:take_item() stack:take_item()
clicker:set_wielded_item(stack) clicker:set_wielded_item(stack)
@ -73,11 +72,11 @@ mobs.enter_breed_state = function(self,clicker)
self.breed_lookout_timer = self.breed_lookout_timer_goal self.breed_lookout_timer = self.breed_lookout_timer_goal
self.bred = true self.bred = true
mobs.play_sound_specific(self,"mobs_mc_animal_eat_generic") mobs.play_sound_specific(self,"mobs_mc_animal_eat_generic")
return(true) return true
end end
--everything failed --everything failed
return(false) return false
end end
@ -96,23 +95,23 @@ mobs.look_for_mate = function(self)
for _,mate in pairs(minetest_get_objects_inside_radius(pos1, radius)) do for _,mate in pairs(minetest_get_objects_inside_radius(pos1, radius)) do
--look for a breeding mate --look for a breeding mate
if mate and mate:get_luaentity() if mate and mate:get_luaentity()
and mate:get_luaentity()._cmi_is_mob and mate:get_luaentity()._cmi_is_mob
and mate:get_luaentity().name == self.name and mate:get_luaentity().name == self.name
and mate:get_luaentity().breed_lookout_timer > 0 and mate:get_luaentity().breed_lookout_timer > 0
and mate:get_luaentity() ~= self then and mate:get_luaentity() ~= self then
local pos2 = mate:get_pos() local pos2 = mate:get_pos()
local distance = vector_distance(pos1,pos2) local distance = vector.distance(pos1,pos2)
if distance <= radius then if distance <= radius then
if line_of_sight then if minetest.line_of_sight then
--must add eye height or stuff breaks randomly because of --must add eye height or stuff breaks randomly because of
--seethrough nodes being a blocker (like grass) --seethrough nodes being a blocker (like grass)
if minetest_line_of_sight( if minetest.line_of_sight(
vector_new(pos1.x, pos1.y, pos1.z), vector.new(pos1.x, pos1.y, pos1.z),
vector_new(pos2.x, pos2.y + mate:get_properties().eye_height, pos2.z) vector.new(pos2.x, pos2.y + mate:get_properties().eye_height, pos2.z)
) then ) then
mates_detected = mates_detected + 1 mates_detected = mates_detected + 1
mates_in_area[mate] = distance mates_in_area[mate] = distance
@ -141,9 +140,7 @@ mobs.look_for_mate = function(self)
winner_mate = mate winner_mate = mate
end end
end end
return winner_mate
return(winner_mate)
end end
--make the baby grow up --make the baby grow up
@ -160,14 +157,14 @@ mobs.make_baby_grow_faster = function(self,clicker)
if clicker and clicker:is_player() then if clicker and clicker:is_player() then
local stack = clicker:get_wielded_item() local stack = clicker:get_wielded_item()
--safety check --safety check
if not stack then if not stack then
return(false) return false
end end
local item_name = stack:get_name() local item_name = stack:get_name()
--all checks have passed, that guy has some good looking food --all checks have passed, that guy has some good looking food
if item_name == self.follow then if item_name == self.follow then
self.grow_up_timer = self.grow_up_timer - (self.grow_up_timer * 0.10) --take 10 percent off - diminishing returns self.grow_up_timer = self.grow_up_timer - (self.grow_up_timer * 0.10) --take 10 percent off - diminishing returns
if not minetest.is_creative_enabled(clicker:get_player_name()) then if not minetest.is_creative_enabled(clicker:get_player_name()) then
stack:take_item() stack:take_item()
@ -175,10 +172,8 @@ mobs.make_baby_grow_faster = function(self,clicker)
end end
mobs.play_sound_specific(self,"mobs_mc_animal_eat_generic") mobs.play_sound_specific(self,"mobs_mc_animal_eat_generic")
return true
return(true)
end end
end end
return false
return(false)
end end

View File

@ -8,10 +8,8 @@ local vector_direction = vector.direction
local integer_test = {-1,1} local integer_test = {-1,1}
mobs.collision = function(self) mobs.collision = function(self)
local pos = self.object:get_pos() local pos = self.object:get_pos()
if not self or not self.object or not self.object:get_luaentity() then if not self or not self.object or not self.object:get_luaentity() then
return return
end end
@ -20,7 +18,7 @@ mobs.collision = function(self)
local collisionbox = self.object:get_properties().collisionbox local collisionbox = self.object:get_properties().collisionbox
pos.y = pos.y + collisionbox[2] pos.y = pos.y + collisionbox[2]
local collision_boundary = collisionbox[4] local collision_boundary = collisionbox[4]
local radius = collision_boundary local radius = collision_boundary
@ -41,7 +39,7 @@ mobs.collision = function(self)
for _,object in ipairs(minetest_get_objects_inside_radius(pos, radius*1.25)) do for _,object in ipairs(minetest_get_objects_inside_radius(pos, radius*1.25)) do
if object and object ~= self.object and (object:is_player() or (object:get_luaentity() and object:get_luaentity()._cmi_is_mob == true and object:get_luaentity().health > 0)) and if object and object ~= self.object and (object:is_player() or (object:get_luaentity() and object:get_luaentity()._cmi_is_mob == true and object:get_luaentity().health > 0)) and
--don't collide with rider, rider don't collide with thing --don't collide with rider, rider don't collide with thing
(not object:get_attach() or (object:get_attach() and object:get_attach() ~= self.object)) and (not object:get_attach() or (object:get_attach() and object:get_attach() ~= self.object)) and
(not self.object:get_attach() or (self.object:get_attach() and self.object:get_attach() ~= object)) then (not self.object:get_attach() or (self.object:get_attach() and self.object:get_attach() ~= object)) then
--stop infinite loop --stop infinite loop
collision_count = collision_count + 1 collision_count = collision_count + 1
@ -52,7 +50,7 @@ mobs.collision = function(self)
end end
local pos2 = object:get_pos() local pos2 = object:get_pos()
local object_collisionbox = object:get_properties().collisionbox local object_collisionbox = object:get_properties().collisionbox
pos2.y = pos2.y + object_collisionbox[2] pos2.y = pos2.y + object_collisionbox[2]
@ -74,7 +72,7 @@ mobs.collision = function(self)
local dir = vector.direction(pos,pos2) local dir = vector.direction(pos,pos2)
dir.y = 0 dir.y = 0
--eliminate mob being stuck in corners --eliminate mob being stuck in corners
if dir.x == 0 and dir.z == 0 then if dir.x == 0 and dir.z == 0 then
--slightly adjust mob position to prevent equal length --slightly adjust mob position to prevent equal length
@ -84,7 +82,7 @@ mobs.collision = function(self)
end end
local velocity = dir local velocity = dir
--0.5 is the max force multiplier --0.5 is the max force multiplier
local force = 0.5 - (0.5 * distance / (collision_boundary + object_collision_boundary)) local force = 0.5 - (0.5 * distance / (collision_boundary + object_collision_boundary))
@ -104,11 +102,9 @@ mobs.collision = function(self)
end end
end end
end end
self.object:add_velocity(vel1) self.object:add_velocity(vel1)
object:add_velocity(vel2) object:add_velocity(vel2)
end end
end end
end end
end end
@ -116,7 +112,6 @@ end
--this is used for arrow collisions --this is used for arrow collisions
mobs.arrow_hit = function(self, player) mobs.arrow_hit = function(self, player)
player:punch(self.object, 1.0, { player:punch(self.object, 1.0, {
full_punch_interval = 1.0, full_punch_interval = 1.0,
damage_groups = {fleshy = self._damage} damage_groups = {fleshy = self._damage}

View File

@ -1,5 +1,5 @@
local minetest_add_item = minetest.add_item local minetest_add_item = minetest.add_item
local minetest_sound_play = minetest.sound_play --local minetest_sound_play = minetest.sound_play
local math_pi = math.pi local math_pi = math.pi
local math_random = math.random local math_random = math.random
@ -19,7 +19,7 @@ local item_drop = function(self, cooked, looting_level)
return return
end end
local obj, item, num local obj, item
local pos = self.object:get_pos() local pos = self.object:get_pos()
self.drops = self.drops or {} -- nil check self.drops = self.drops or {} -- nil check
@ -56,8 +56,11 @@ local item_drop = function(self, cooked, looting_level)
-- cook items when true -- cook items when true
if cooked then if cooked then
local output = minetest_get_craft_result({ local output = minetest.get_craft_result({
method = "cooking", width = 1, items = {item}}) method = "cooking",
width = 1,
items = {item},
})
if output and output.item and not output.item:is_empty() then if output and output.item and not output.item:is_empty() then
item = output.item:get_name() item = output.item:get_name()
@ -117,15 +120,10 @@ mobs.death_logic = function(self, dtime)
--the final POOF of a mob despawning --the final POOF of a mob despawning
if self.death_animation_timer >= 1.25 then if self.death_animation_timer >= 1.25 then
item_drop(self,false,1) item_drop(self,false,1)
mobs.death_effect(self) mobs.death_effect(self)
mcl_experience.throw_experience(self.object:get_pos(), math_random(self.xp_min, self.xp_max)) mcl_experience.throw_experience(self.object:get_pos(), math_random(self.xp_min, self.xp_max))
self.object:remove() self.object:remove()
return return
end end

View File

@ -1,5 +1,5 @@
local minetest_line_of_sight = minetest.line_of_sight local minetest_line_of_sight = minetest.line_of_sight
local minetest_dir_to_yaw = minetest.dir_to_yaw --local minetest_dir_to_yaw = minetest.dir_to_yaw
local minetest_yaw_to_dir = minetest.yaw_to_dir local minetest_yaw_to_dir = minetest.yaw_to_dir
local minetest_get_node = minetest.get_node local minetest_get_node = minetest.get_node
local minetest_get_item_group = minetest.get_item_group local minetest_get_item_group = minetest.get_item_group
@ -18,19 +18,16 @@ local table_copy = table.copy
local math_abs = math.abs local math_abs = math.abs
-- default function when mobs are blown up with TNT -- default function when mobs are blown up with TNT
local do_tnt = function(obj, damage) --[[local function do_tnt(obj, damage)
obj.object:punch(obj.object, 1.0, { obj.object:punch(obj.object, 1.0, {
full_punch_interval = 1.0, full_punch_interval = 1.0,
damage_groups = {fleshy = damage}, damage_groups = {fleshy = damage},
}, nil) }, nil)
return false, true, {} return false, true, {}
end end]]
--a fast function to be able to detect only players without using objects_in_radius --a fast function to be able to detect only players without using objects_in_radius
mobs.detect_closest_player_within_radius = function(self, line_of_sight, radius, object_height_adder) mobs.detect_closest_player_within_radius = function(self, line_of_sight, radius, object_height_adder)
local pos1 = self.object:get_pos() local pos1 = self.object:get_pos()
local players_in_area = {} local players_in_area = {}
local winner_player = nil local winner_player = nil
@ -49,7 +46,7 @@ mobs.detect_closest_player_within_radius = function(self, line_of_sight, radius,
--must add eye height or stuff breaks randomly because of --must add eye height or stuff breaks randomly because of
--seethrough nodes being a blocker (like grass) --seethrough nodes being a blocker (like grass)
if minetest_line_of_sight( if minetest_line_of_sight(
vector_new(pos1.x, pos1.y + object_height_adder, pos1.z), vector_new(pos1.x, pos1.y + object_height_adder, pos1.z),
vector_new(pos2.x, pos2.y + player:get_properties().eye_height, pos2.z) vector_new(pos2.x, pos2.y + player:get_properties().eye_height, pos2.z)
) then ) then
players_detected = players_detected + 1 players_detected = players_detected + 1
@ -79,8 +76,7 @@ mobs.detect_closest_player_within_radius = function(self, line_of_sight, radius,
winner_player = player winner_player = player
end end
end end
return winner_player
return(winner_player)
end end
@ -107,14 +103,13 @@ mobs.jump_check = function(self,dtime)
if green_flag_1 and green_flag_2 then if green_flag_1 and green_flag_2 then
--can jump over node --can jump over node
return(1) return 1
elseif green_flag_1 and not green_flag_2 then elseif green_flag_1 and not green_flag_2 then
--wall in front of mob --wall in front of mob
return(2) return 2
end end
--nothing to jump over --nothing to jump over
return(0) return 0
end end
-- a helper function to quickly turn neutral passive mobs hostile -- a helper function to quickly turn neutral passive mobs hostile
@ -180,15 +175,10 @@ end
-- check if within physical map limits (-30911 to 30927) -- check if within physical map limits (-30911 to 30927)
-- within_limits, wmin, wmax = nil, -30913, 30928 -- within_limits, wmin, wmax = nil, -30913, 30928
mobs.within_limits = function(pos, radius) mobs.within_limits = function(pos, radius)
local wmin, wmax
if mcl_vars then if mcl_vars then
if mcl_vars.mapgen_edge_min and mcl_vars.mapgen_edge_max then if mcl_vars.mapgen_edge_min and mcl_vars.mapgen_edge_max then
wmin, wmax = mcl_vars.mapgen_edge_min, mcl_vars.mapgen_edge_max wmin, wmax = mcl_vars.mapgen_edge_min, mcl_vars.mapgen_edge_max
within_limits = function(pos, radius)
return pos
and (pos.x - radius) > wmin and (pos.x + radius) < wmax
and (pos.y - radius) > wmin and (pos.y + radius) < wmax
and (pos.z - radius) > wmin and (pos.z + radius) < wmax
end
end end
end end
return pos return pos
@ -231,12 +221,12 @@ mobs.check_for_player_within_area = function(self, radius)
local distance = vector_distance(pos1,pos2) local distance = vector_distance(pos1,pos2)
if distance < radius then if distance < radius then
--found a player --found a player
return(true) return true
end end
end end
end end
--did not find a player --did not find a player
return(false) return false
end end
@ -244,7 +234,7 @@ end
mobs.get_2d_distance = function(pos1,pos2) mobs.get_2d_distance = function(pos1,pos2)
pos1.y = 0 pos1.y = 0
pos2.y = 0 pos2.y = 0
return(vector_distance(pos1, pos2)) return vector_distance(pos1, pos2)
end end
-- fall damage onto solid ground -- fall damage onto solid ground

View File

@ -1,112 +1,98 @@
local vector_new = vector.new local math = math
local vector = vector
--converts yaw to degrees --converts yaw to degrees
local degrees = function(yaw) local degrees = function(yaw)
return(yaw*180.0/math.pi) return yaw*180.0/math.pi
end end
mobs.do_head_logic = function(self,dtime) mobs.do_head_logic = function(self,dtime)
local player = minetest.get_player_by_name("singleplayer") local player = minetest.get_player_by_name("singleplayer")
local look_at = player:get_pos() local look_at = player:get_pos()
look_at.y = look_at.y + player:get_properties().eye_height look_at.y = look_at.y + player:get_properties().eye_height
local pos = self.object:get_pos()
local body_yaw = self.object:get_yaw()
local body_dir = minetest.yaw_to_dir(body_yaw)
pos.y = pos.y + self.head_height_offset
local head_offset = vector.multiply(body_dir, self.head_direction_offset)
pos = vector.add(pos, head_offset)
minetest.add_particle({
pos = pos,
velocity = {x=0, y=0, z=0},
acceleration = {x=0, y=0, z=0},
expirationtime = 0.2,
size = 1,
texture = "default_dirt.png",
})
local bone_pos = vector.new(0,0,0)
--(horizontal)
bone_pos.y = self.head_bone_pos_y
--(vertical)
bone_pos.z = self.head_bone_pos_z
--print(yaw)
--local _, bone_rot = self.object:get_bone_position("head")
--bone_rot.x = bone_rot.x + (dtime * 10)
--bone_rot.z = bone_rot.z + (dtime * 10)
local head_yaw = minetest.dir_to_yaw(vector.direction(pos,look_at)) - body_yaw
if self.reverse_head_yaw then
head_yaw = head_yaw * -1
end
--over rotation protection
--stops radians from going out of spec
if head_yaw > math.pi then
head_yaw = head_yaw - (math.pi * 2)
elseif head_yaw < -math.pi then
head_yaw = head_yaw + (math.pi * 2)
end
local check_failed = false
--upper check + 90 degrees or upper math.radians (3.14/2)
if head_yaw > math.pi - (math.pi/2) then
head_yaw = 0
check_failed = true
--lower check - 90 degrees or lower negative math.radians (-3.14/2)
elseif head_yaw < -math.pi + (math.pi/2) then
head_yaw = 0
check_failed = true
end
local head_pitch = 0
local pos = self.object:get_pos() --DEBUG DEBUG DEBUG DEBUG DEBUG DEBUG DEBUG DEBUG DEBUG DEBUG DEBUG DEBUG DEBUG DEBUG DEBUG DEBUG DEBUG
--head_yaw = 0
--DEBUG DEBUG DEBUG DEBUG DEBUG DEBUG DEBUG DEBUG DEBUG DEBUG DEBUG DEBUG DEBUG DEBUG DEBUG DEBUG DEBUG
local body_yaw = self.object:get_yaw() if not check_failed then
head_pitch = minetest.dir_to_yaw(vector.new(vector.distance(vector.new(pos.x,0,pos.z),vector.new(look_at.x,0,look_at.z)),0,pos.y-look_at.y))+(math.pi/2)
end
local body_dir = minetest.yaw_to_dir(body_yaw) if self.head_pitch_modifier then
head_pitch = head_pitch + self.head_pitch_modifier
end
if self.swap_y_with_x then
pos.y = pos.y + self.head_height_offset self.object:set_bone_position(self.head_bone, bone_pos, vector.new(degrees(head_pitch),degrees(head_yaw),0))
else
local head_offset = vector.multiply(body_dir, self.head_direction_offset) self.object:set_bone_position(self.head_bone, bone_pos, vector.new(degrees(head_pitch),0,degrees(head_yaw)))
end
pos = vector.add(pos, head_offset) --set_bone_position([bone, position, rotation])
minetest.add_particle({
pos = pos,
velocity = {x=0, y=0, z=0},
acceleration = {x=0, y=0, z=0},
expirationtime = 0.2,
size = 1,
texture = "default_dirt.png",
})
local bone_pos = vector_new(0,0,0)
--(horizontal)
bone_pos.y = self.head_bone_pos_y
--(vertical)
bone_pos.z = self.head_bone_pos_z
--print(yaw)
--local _, bone_rot = self.object:get_bone_position("head")
--bone_rot.x = bone_rot.x + (dtime * 10)
--bone_rot.z = bone_rot.z + (dtime * 10)
local head_yaw
head_yaw = minetest.dir_to_yaw(vector.direction(pos,look_at)) - body_yaw
if self.reverse_head_yaw then
head_yaw = head_yaw * -1
end
--over rotation protection
--stops radians from going out of spec
if head_yaw > math.pi then
head_yaw = head_yaw - (math.pi * 2)
elseif head_yaw < -math.pi then
head_yaw = head_yaw + (math.pi * 2)
end
local check_failed = false
--upper check + 90 degrees or upper math.radians (3.14/2)
if head_yaw > math.pi - (math.pi/2) then
head_yaw = 0
check_failed = true
--lower check - 90 degrees or lower negative math.radians (-3.14/2)
elseif head_yaw < -math.pi + (math.pi/2) then
head_yaw = 0
check_failed = true
end
local head_pitch = 0
--DEBUG DEBUG DEBUG DEBUG DEBUG DEBUG DEBUG DEBUG DEBUG DEBUG DEBUG DEBUG DEBUG DEBUG DEBUG DEBUG DEBUG
--head_yaw = 0
--DEBUG DEBUG DEBUG DEBUG DEBUG DEBUG DEBUG DEBUG DEBUG DEBUG DEBUG DEBUG DEBUG DEBUG DEBUG DEBUG DEBUG
if not check_failed then
head_pitch = minetest.dir_to_yaw(vector.new(vector.distance(vector.new(pos.x,0,pos.z),vector.new(look_at.x,0,look_at.z)),0,pos.y-look_at.y))+(math.pi/2)
end
if self.head_pitch_modifier then
head_pitch = head_pitch + self.head_pitch_modifier
end
if self.swap_y_with_x then
self.object:set_bone_position(self.head_bone, bone_pos, vector_new(degrees(head_pitch),degrees(head_yaw),0))
else
self.object:set_bone_position(self.head_bone, bone_pos, vector_new(degrees(head_pitch),0,degrees(head_yaw)))
end
--set_bone_position([bone, position, rotation])
end end

View File

@ -2,22 +2,19 @@ local minetest_after = minetest.after
local minetest_sound_play = minetest.sound_play local minetest_sound_play = minetest.sound_play
local minetest_dir_to_yaw = minetest.dir_to_yaw local minetest_dir_to_yaw = minetest.dir_to_yaw
local math_floor = math.floor local math = math
local math_min = math.min local vector = vector
local math_random = math.random
local vector_direction = vector.direction
local vector_multiply = vector.multiply
local MAX_MOB_NAME_LENGTH = 30 local MAX_MOB_NAME_LENGTH = 30
local mod_hunger = minetest.get_modpath("mcl_hunger")
mobs.feed_tame = function(self) mobs.feed_tame = function(self)
return nil return nil
end end
-- Code to execute before custom on_rightclick handling -- Code to execute before custom on_rightclick handling
local on_rightclick_prefix = function(self, clicker) local function on_rightclick_prefix(self, clicker)
local item = clicker:get_wielded_item() local item = clicker:get_wielded_item()
-- Name mob with nametag -- Name mob with nametag
@ -60,7 +57,6 @@ end
-- deal damage and effects when mob punched -- deal damage and effects when mob punched
mobs.mob_punch = function(self, hitter, tflp, tool_capabilities, dir) mobs.mob_punch = function(self, hitter, tflp, tool_capabilities, dir)
--don't do anything if the mob is already dead --don't do anything if the mob is already dead
if self.health <= 0 then if self.health <= 0 then
return return
@ -94,14 +90,13 @@ mobs.mob_punch = function(self, hitter, tflp, tool_capabilities, dir)
pos2.y = 0 pos2.y = 0
local dir = vector_direction(pos2,pos1) local dir = vector.direction(pos2,pos1)
local yaw = minetest_dir_to_yaw(dir) local yaw = minetest_dir_to_yaw(dir)
self.yaw = yaw self.yaw = yaw
end end
-- custom punch function -- custom punch function
if self.do_punch then if self.do_punch then
-- when false skip going any further -- when false skip going any further
@ -113,23 +108,20 @@ mobs.mob_punch = function(self, hitter, tflp, tool_capabilities, dir)
--don't do damage until pause timer resets --don't do damage until pause timer resets
if self.pause_timer > 0 then if self.pause_timer > 0 then
return return
end end
-- error checking when mod profiling is enabled -- error checking when mod profiling is enabled
if not tool_capabilities then if not tool_capabilities then
minetest.log("warning", "[mobs_mc] Mod profiling enabled, damage not enabled") minetest.log("warning", "[mobs_mc] Mod profiling enabled, damage not enabled")
return return
end end
local is_player = hitter:is_player() local is_player = hitter:is_player()
-- punch interval -- punch interval
local weapon = hitter:get_wielded_item() local weapon = hitter:get_wielded_item()
local punch_interval = 1.4 --local punch_interval = 1.4
-- exhaust attacker -- exhaust attacker
if mod_hunger and is_player then if mod_hunger and is_player then
@ -139,7 +131,6 @@ mobs.mob_punch = function(self, hitter, tflp, tool_capabilities, dir)
-- calculate mob damage -- calculate mob damage
local damage = 0 local damage = 0
local armor = self.object:get_armor_groups() or {} local armor = self.object:get_armor_groups() or {}
local tmp
--calculate damage groups --calculate damage groups
for group,_ in pairs( (tool_capabilities.damage_groups or {}) ) do for group,_ in pairs( (tool_capabilities.damage_groups or {}) ) do
@ -163,13 +154,13 @@ mobs.mob_punch = function(self, hitter, tflp, tool_capabilities, dir)
-- healing -- healing
if damage <= -1 then if damage <= -1 then
self.health = self.health - math_floor(damage) self.health = self.health - math.floor(damage)
return return
end end
if tool_capabilities then --if tool_capabilities then
punch_interval = tool_capabilities.full_punch_interval or 1.4 -- punch_interval = tool_capabilities.full_punch_interval or 1.4
end --end
-- add weapon wear manually -- add weapon wear manually
-- Required because we have custom health handling ("health" property) -- Required because we have custom health handling ("health" property)
@ -183,7 +174,7 @@ mobs.mob_punch = function(self, hitter, tflp, tool_capabilities, dir)
local weapon = hitter:get_wielded_item(player) local weapon = hitter:get_wielded_item(player)
local def = weapon:get_definition() local def = weapon:get_definition()
if def.tool_capabilities and def.tool_capabilities.punch_attack_uses then if def.tool_capabilities and def.tool_capabilities.punch_attack_uses then
local wear = math_floor(65535/tool_capabilities.punch_attack_uses) local wear = math.floor(65535/tool_capabilities.punch_attack_uses)
weapon:add_wear(wear) weapon:add_wear(wear)
hitter:set_wielded_item(weapon) hitter:set_wielded_item(weapon)
end end
@ -224,7 +215,7 @@ mobs.mob_punch = function(self, hitter, tflp, tool_capabilities, dir)
-- knock back effect -- knock back effect
local velocity = self.object:get_velocity() local velocity = self.object:get_velocity()
--2d direction --2d direction
local pos1 = self.object:get_pos() local pos1 = self.object:get_pos()
pos1.y = 0 pos1.y = 0
@ -240,9 +231,8 @@ mobs.mob_punch = function(self, hitter, tflp, tool_capabilities, dir)
up = 0 up = 0
end end
--0.75 for perfect distance to not be too easy, and not be too hard --0.75 for perfect distance to not be too easy, and not be too hard
local multiplier = 0.75 local multiplier = 0.75
-- check if tool already has specific knockback value -- check if tool already has specific knockback value
local knockback_enchant = mcl_enchanting.get_enchantment(hitter:get_wielded_item(), "knockback") local knockback_enchant = mcl_enchanting.get_enchantment(hitter:get_wielded_item(), "knockback")
@ -254,21 +244,16 @@ mobs.mob_punch = function(self, hitter, tflp, tool_capabilities, dir)
--it's coming for you --it's coming for you
if self.hostile then if self.hostile then
multiplier = multiplier + 2 multiplier = multiplier + 2
end end
dir = vector.multiply(dir,multiplier)
dir = vector_multiply(dir,multiplier)
dir.y = up dir.y = up
--add the velocity --add the velocity
self.object:add_velocity(dir) self.object:add_velocity(dir)
end end
end end
--do internal per mob projectile calculations --do internal per mob projectile calculations
mobs.shoot_projectile = function(self) mobs.shoot_projectile = function(self)
local pos1 = self.object:get_pos() local pos1 = self.object:get_pos()
--add mob eye height --add mob eye height
pos1.y = pos1.y + self.eye_height pos1.y = pos1.y + self.eye_height
@ -278,7 +263,7 @@ mobs.shoot_projectile = function(self)
pos2.y = pos2.y + self.attacking:get_properties().eye_height pos2.y = pos2.y + self.attacking:get_properties().eye_height
--get direction --get direction
local dir = vector_direction(pos1,pos2) local dir = vector.direction(pos1,pos2)
--call internal shoot_arrow function --call internal shoot_arrow function
self.shoot_arrow(self,pos1,dir) self.shoot_arrow(self,pos1,dir)

View File

@ -1,9 +1,8 @@
local minetest_add_particlespawner = minetest.add_particlespawner local minetest_add_particlespawner = minetest.add_particlespawner
mobs.death_effect = function(self) mobs.death_effect = function(self)
local pos = self.object:get_pos() local pos = self.object:get_pos()
local yaw = self.object:get_yaw() --local yaw = self.object:get_yaw()
local collisionbox = self.object:get_properties().collisionbox local collisionbox = self.object:get_properties().collisionbox
local min, max local min, max
@ -33,7 +32,7 @@ end
mobs.critical_effect = function(self) mobs.critical_effect = function(self)
local pos = self.object:get_pos() local pos = self.object:get_pos()
local yaw = self.object:get_yaw() --local yaw = self.object:get_yaw()
local collisionbox = self.object:get_properties().collisionbox local collisionbox = self.object:get_properties().collisionbox
local min, max local min, max
@ -62,9 +61,8 @@ end
--when feeding a mob --when feeding a mob
mobs.feed_effect = function(self) mobs.feed_effect = function(self)
local pos = self.object:get_pos() local pos = self.object:get_pos()
local yaw = self.object:get_yaw() --local yaw = self.object:get_yaw()
local collisionbox = self.object:get_properties().collisionbox local collisionbox = self.object:get_properties().collisionbox
local min, max local min, max
@ -94,7 +92,7 @@ end
--hearts when tamed --hearts when tamed
mobs.tamed_effect = function(self) mobs.tamed_effect = function(self)
local pos = self.object:get_pos() local pos = self.object:get_pos()
local yaw = self.object:get_yaw() --local yaw = self.object:get_yaw()
local collisionbox = self.object:get_properties().collisionbox local collisionbox = self.object:get_properties().collisionbox
local min, max local min, max
@ -124,7 +122,7 @@ end
--hearts when breeding --hearts when breeding
mobs.breeding_effect = function(self) mobs.breeding_effect = function(self)
local pos = self.object:get_pos() local pos = self.object:get_pos()
local yaw = self.object:get_yaw() --local yaw = self.object:get_yaw()
local collisionbox = self.object:get_properties().collisionbox local collisionbox = self.object:get_properties().collisionbox
local min, max local min, max

View File

@ -1,16 +1,10 @@
local math_pi = math.pi -- localize math functions
local math_sin = math.sin local math = math
local math_cos = math.cos local HALF_PI = math.pi / 2
local math_random = math.random local DOUBLE_PI = math.pi * 2
local HALF_PI = math_pi / 2
local DOUBLE_PI = math_pi * 2
-- localize vector functions -- localize vector functions
local vector_new = vector.new local vector = vector
local vector_length = vector.length
local vector_multiply = vector.multiply
local vector_distance = vector.distance
local vector_normalize = vector.normalize
local minetest_yaw_to_dir = minetest.yaw_to_dir local minetest_yaw_to_dir = minetest.yaw_to_dir
local minetest_dir_to_yaw = minetest.dir_to_yaw local minetest_dir_to_yaw = minetest.dir_to_yaw
@ -19,18 +13,17 @@ local DEFAULT_JUMP_HEIGHT = 5
local DEFAULT_FLOAT_SPEED = 4 local DEFAULT_FLOAT_SPEED = 4
local DEFAULT_CLIMB_SPEED = 3 local DEFAULT_CLIMB_SPEED = 3
mobs.stick_in_cobweb = function(self) mobs.stick_in_cobweb = function(self)
local current_velocity = self.object:get_velocity() local current_velocity = self.object:get_velocity()
local goal_velocity = vector_multiply(vector_normalize(current_velocity), 0.4) local goal_velocity = vector.multiply(vector.normalize(current_velocity), 0.4)
goal_velocity.y = -0.5 goal_velocity.y = -0.5
local new_velocity_addition = vector.subtract(goal_velocity,current_velocity) local new_velocity_addition = vector.subtract(goal_velocity,current_velocity)
--smooths out mobs a bit --smooths out mobs a bit
if vector_length(new_velocity_addition) >= 0.0001 then if vector.length(new_velocity_addition) >= 0.0001 then
self.object:add_velocity(new_velocity_addition) self.object:add_velocity(new_velocity_addition)
end end
end end
@ -38,8 +31,11 @@ end
--this is a generic float function --this is a generic float function
mobs.float = function(self) mobs.float = function(self)
if self.object:get_acceleration().y ~= 0 then local acceleration = self.object:get_acceleration()
self.object:set_acceleration(vector_new(0,0,0)) if acceleration and acceleration.y ~= 0 then
self.object:set_acceleration(vector.new(0,0,0))
else
return
end end
local current_velocity = self.object:get_velocity() local current_velocity = self.object:get_velocity()
@ -56,7 +52,7 @@ mobs.float = function(self)
new_velocity_addition.z = 0 new_velocity_addition.z = 0
--smooths out mobs a bit --smooths out mobs a bit
if vector_length(new_velocity_addition) >= 0.0001 then if vector.length(new_velocity_addition) >= 0.0001 then
self.object:add_velocity(new_velocity_addition) self.object:add_velocity(new_velocity_addition)
end end
end end
@ -78,7 +74,7 @@ mobs.climb = function(self)
new_velocity_addition.z = 0 new_velocity_addition.z = 0
--smooths out mobs a bit --smooths out mobs a bit
if vector_length(new_velocity_addition) >= 0.0001 then if vector.length(new_velocity_addition) >= 0.0001 then
self.object:add_velocity(new_velocity_addition) self.object:add_velocity(new_velocity_addition)
end end
end end
@ -86,10 +82,10 @@ end
--[[ --[[
_ _ _ _
| | | | | | | |
| | __ _ _ __ __| | | | __ _ _ __ __| |
| | / _` | '_ \ / _` | | | / _` | '_ \ / _` |
| |___| (_| | | | | (_| | | |___| (_| | | | | (_| |
\_____/\__,_|_| |_|\__,_| \_____/\__,_|_| |_|\__,_|
]] ]]
@ -100,28 +96,28 @@ end
--internal = lua (self.yaw) --internal = lua (self.yaw)
--engine = c++ (self.object:get_yaw()) --engine = c++ (self.object:get_yaw())
mobs.set_velocity = function(self, v) mobs.set_velocity = function(self, v)
local yaw = (self.yaw or 0) local yaw = (self.yaw or 0)
local current_velocity = self.object:get_velocity() local current_velocity = self.object:get_velocity()
local goal_velocity = { local goal_velocity = {
x = (math_sin(yaw) * -v), x = (math.sin(yaw) * -v),
y = 0, y = 0,
z = (math_cos(yaw) * v), z = (math.cos(yaw) * v),
} }
local new_velocity_addition = vector.subtract(goal_velocity,current_velocity) local new_velocity_addition = vector.subtract(goal_velocity,current_velocity)
if vector_length(new_velocity_addition) > vector_length(goal_velocity) then if vector.length(new_velocity_addition) > vector.length(goal_velocity) then
vector.multiply(new_velocity_addition, (vector_length(goal_velocity) / vector_length(new_velocity_addition))) vector.multiply(new_velocity_addition, (vector.length(goal_velocity) / vector.length(new_velocity_addition)))
end end
new_velocity_addition.y = 0 new_velocity_addition.y = 0
--smooths out mobs a bit --smooths out mobs a bit
if vector_length(new_velocity_addition) >= 0.0001 then if vector.length(new_velocity_addition) >= 0.0001 then
self.object:add_velocity(new_velocity_addition) self.object:add_velocity(new_velocity_addition)
end end
end end
@ -136,7 +132,7 @@ mobs.get_velocity = function(self)
v.y = 0 v.y = 0
if v then if v then
return vector_length(v) return vector.length(v)
end end
return 0 return 0
@ -152,7 +148,7 @@ mobs.jump = function(self, velocity)
--fallback velocity to allow modularity --fallback velocity to allow modularity
velocity = velocity or DEFAULT_JUMP_HEIGHT velocity = velocity or DEFAULT_JUMP_HEIGHT
self.object:add_velocity(vector_new(0,velocity,0)) self.object:add_velocity(vector.new(0,velocity,0))
end end
--make mobs fall slowly --make mobs fall slowly
@ -172,15 +168,15 @@ mobs.mob_fall_slow = function(self)
new_velocity_addition.x = 0 new_velocity_addition.x = 0
new_velocity_addition.z = 0 new_velocity_addition.z = 0
if vector_length(new_velocity_addition) > vector_length(goal_velocity) then if vector.length(new_velocity_addition) > vector.length(goal_velocity) then
vector.multiply(new_velocity_addition, (vector_length(goal_velocity) / vector_length(new_velocity_addition))) vector.multiply(new_velocity_addition, (vector.length(goal_velocity) / vector.length(new_velocity_addition)))
end end
new_velocity_addition.x = 0 new_velocity_addition.x = 0
new_velocity_addition.z = 0 new_velocity_addition.z = 0
--smooths out mobs a bit --smooths out mobs a bit
if vector_length(new_velocity_addition) >= 0.0001 then if vector.length(new_velocity_addition) >= 0.0001 then
self.object:add_velocity(new_velocity_addition) self.object:add_velocity(new_velocity_addition)
end end
@ -188,10 +184,10 @@ end
--[[ --[[
_____ _ _____ _
/ ___| (_) / ___| (_)
\ `--.__ ___ _ __ ___ \ `--.__ ___ _ __ ___
`--. \ \ /\ / / | '_ ` _ \ `--. \ \ /\ / / | '_ ` _ \
/\__/ /\ V V /| | | | | | | /\__/ /\ V V /| | | | | | |
\____/ \_/\_/ |_|_| |_| |_| \____/ \_/\_/ |_|_| |_| |_|
]]-- ]]--
@ -212,16 +208,16 @@ mobs.flop = function(self, velocity)
velocity = velocity or DEFAULT_JUMP_HEIGHT velocity = velocity or DEFAULT_JUMP_HEIGHT
--create a random direction (2d yaw) --create a random direction (2d yaw)
local dir = DOUBLE_PI * math_random() local dir = DOUBLE_PI * math.random()
--create a random force value --create a random force value
local force = math_random(0,3) + math_random() local force = math.random(0,3) + math.random()
--convert the yaw to a direction vector then multiply it times the force --convert the yaw to a direction vector then multiply it times the force
local final_additional_force = vector_multiply(minetest_yaw_to_dir(dir), force) local final_additional_force = vector.multiply(minetest_yaw_to_dir(dir), force)
--place in the "flop" velocity to make the mob flop --place in the "flop" velocity to make the mob flop
final_additional_force.y = velocity final_additional_force.y = velocity
self.object:add_velocity(final_additional_force) self.object:add_velocity(final_additional_force)
@ -235,7 +231,7 @@ end
--internal = lua (self.yaw) --internal = lua (self.yaw)
--engine = c++ (self.object:get_yaw()) --engine = c++ (self.object:get_yaw())
mobs.set_swim_velocity = function(self, v) mobs.set_swim_velocity = function(self, v)
local yaw = (self.yaw or 0) local yaw = (self.yaw or 0)
local pitch = (self.pitch or 0) local pitch = (self.pitch or 0)
@ -246,33 +242,33 @@ mobs.set_swim_velocity = function(self, v)
local current_velocity = self.object:get_velocity() local current_velocity = self.object:get_velocity()
local goal_velocity = { local goal_velocity = {
x = (math_sin(yaw) * -v), x = (math.sin(yaw) * -v),
y = pitch, y = pitch,
z = (math_cos(yaw) * v), z = (math.cos(yaw) * v),
} }
local new_velocity_addition = vector.subtract(goal_velocity,current_velocity) local new_velocity_addition = vector.subtract(goal_velocity,current_velocity)
if vector_length(new_velocity_addition) > vector_length(goal_velocity) then if vector.length(new_velocity_addition) > vector.length(goal_velocity) then
vector.multiply(new_velocity_addition, (vector_length(goal_velocity) / vector_length(new_velocity_addition))) vector.multiply(new_velocity_addition, (vector.length(goal_velocity) / vector.length(new_velocity_addition)))
end end
--smooths out mobs a bit --smooths out mobs a bit
if vector_length(new_velocity_addition) >= 0.0001 then if vector.length(new_velocity_addition) >= 0.0001 then
self.object:add_velocity(new_velocity_addition) self.object:add_velocity(new_velocity_addition)
end end
end end
--[[ --[[
______ _ ______ _
| ___| | | ___| |
| |_ | |_ _ | |_ | |_ _
| _| | | | | | | _| | | | | |
| | | | |_| | | | | | |_| |
\_| |_|\__, | \_| |_|\__, |
__/ | __/ |
|___/ |___/
]]-- ]]--
-- move mob in facing direction -- move mob in facing direction
@ -280,7 +276,7 @@ ______ _
--internal = lua (self.yaw) --internal = lua (self.yaw)
--engine = c++ (self.object:get_yaw()) --engine = c++ (self.object:get_yaw())
mobs.set_fly_velocity = function(self, v) mobs.set_fly_velocity = function(self, v)
local yaw = (self.yaw or 0) local yaw = (self.yaw or 0)
local pitch = (self.pitch or 0) local pitch = (self.pitch or 0)
@ -291,20 +287,20 @@ mobs.set_fly_velocity = function(self, v)
local current_velocity = self.object:get_velocity() local current_velocity = self.object:get_velocity()
local goal_velocity = { local goal_velocity = {
x = (math_sin(yaw) * -v), x = (math.sin(yaw) * -v),
y = pitch, y = pitch,
z = (math_cos(yaw) * v), z = (math.cos(yaw) * v),
} }
local new_velocity_addition = vector.subtract(goal_velocity,current_velocity) local new_velocity_addition = vector.subtract(goal_velocity,current_velocity)
if vector_length(new_velocity_addition) > vector_length(goal_velocity) then if vector.length(new_velocity_addition) > vector.length(goal_velocity) then
vector.multiply(new_velocity_addition, (vector_length(goal_velocity) / vector_length(new_velocity_addition))) vector.multiply(new_velocity_addition, (vector.length(goal_velocity) / vector.length(new_velocity_addition)))
end end
--smooths out mobs a bit --smooths out mobs a bit
if vector_length(new_velocity_addition) >= 0.0001 then if vector.length(new_velocity_addition) >= 0.0001 then
self.object:add_velocity(new_velocity_addition) self.object:add_velocity(new_velocity_addition)
end end
end end
@ -316,7 +312,7 @@ mobs.calculate_pitch = function(pos1, pos2)
return false return false
end end
return(minetest_dir_to_yaw(vector_new(vector_distance(vector_new(pos1.x,0,pos1.z),vector_new(pos2.x,0,pos2.z)),0,pos1.y - pos2.y)) + HALF_PI) return minetest_dir_to_yaw(vector.new(vector.distance(vector.new(pos1.x,0,pos1.z),vector.new(pos2.x,0,pos2.z)),0,pos1.y - pos2.y)) + HALF_PI
end end
--make mobs fly up or down based on their y difference --make mobs fly up or down based on their y difference
@ -332,14 +328,14 @@ end
--[[ --[[
___ ___
|_ | |_ |
| |_ _ _ __ ___ _ __ | |_ _ _ __ ___ _ __
| | | | | '_ ` _ \| '_ \ | | | | | '_ ` _ \| '_ \
/\__/ / |_| | | | | | | |_) | /\__/ / |_| | | | | | | |_) |
\____/ \__,_|_| |_| |_| .__/ \____/ \__,_|_| |_| |_| .__/
| | | |
|_| |_|
]]-- ]]--
--special mob jump movement --special mob jump movement
@ -353,27 +349,27 @@ mobs.jump_move = function(self, velocity)
mobs.set_velocity(self,0) mobs.set_velocity(self,0)
--fallback velocity to allow modularity --fallback velocity to allow modularity
jump_height = DEFAULT_JUMP_HEIGHT local jump_height = DEFAULT_JUMP_HEIGHT
local yaw = (self.yaw or 0) local yaw = (self.yaw or 0)
local current_velocity = self.object:get_velocity() local current_velocity = self.object:get_velocity()
local goal_velocity = { local goal_velocity = {
x = (math_sin(yaw) * -velocity), x = (math.sin(yaw) * -velocity),
y = jump_height, y = jump_height,
z = (math_cos(yaw) * velocity), z = (math.cos(yaw) * velocity),
} }
local new_velocity_addition = vector.subtract(goal_velocity,current_velocity) local new_velocity_addition = vector.subtract(goal_velocity,current_velocity)
if vector_length(new_velocity_addition) > vector_length(goal_velocity) then if vector.length(new_velocity_addition) > vector.length(goal_velocity) then
vector.multiply(new_velocity_addition, (vector_length(goal_velocity) / vector_length(new_velocity_addition))) vector.multiply(new_velocity_addition, (vector.length(goal_velocity) / vector.length(new_velocity_addition)))
end end
--smooths out mobs a bit --smooths out mobs a bit
if vector_length(new_velocity_addition) >= 0.0001 then if vector.length(new_velocity_addition) >= 0.0001 then
self.object:add_velocity(new_velocity_addition) self.object:add_velocity(new_velocity_addition)
end end
end end
@ -388,4 +384,4 @@ mobs.swap_auto_step_height_adjust = function(self)
elseif y_vel ~= 0 and self.stepheight ~= 0 then elseif y_vel ~= 0 and self.stepheight ~= 0 then
self.stepheight = 0 self.stepheight = 0
end end
end end

View File

@ -1,10 +1,12 @@
local math_random = math.random local math_random = math.random
local minetest_settings = minetest.settings local minetest_settings = minetest.settings
-- CMI support check
local use_cmi = minetest.global_exists("cmi")
-- get entity staticdata -- get entity staticdata
mobs.mob_staticdata = function(self) mobs.mob_staticdata = function(self)
--despawn mechanism --despawn mechanism
--don't despawned tamed or bred mobs --don't despawned tamed or bred mobs
if not self.tamed and not self.bred then if not self.tamed and not self.bred then
@ -142,8 +144,6 @@ mobs.mob_activate = function(self, staticdata, def, dtime)
self.health = math_random (self.hp_min, self.hp_max) self.health = math_random (self.hp_min, self.hp_max)
end end
if not self.random_sound_timer then if not self.random_sound_timer then
self.random_sound_timer = math_random(self.random_sound_timer_min,self.random_sound_timer_max) self.random_sound_timer = math_random(self.random_sound_timer_min,self.random_sound_timer_max)
end end
@ -185,7 +185,6 @@ mobs.mob_activate = function(self, staticdata, def, dtime)
self.opinion_sound_cooloff = 0 -- used to prevent sound spam of particular sound types self.opinion_sound_cooloff = 0 -- used to prevent sound spam of particular sound types
self.texture_mods = {} self.texture_mods = {}
self.v_start = false self.v_start = false
self.timer = 0 self.timer = 0
@ -199,7 +198,6 @@ mobs.mob_activate = function(self, staticdata, def, dtime)
else else
self.object:set_texture_mod("") self.object:set_texture_mod("")
end end
-- set anything changed above -- set anything changed above
self.object:set_properties(self) self.object:set_properties(self)

View File

@ -1,8 +1,11 @@
-- lib_mount by Blert2112 (edited by TenPlus1) -- lib_mount by Blert2112 (edited by TenPlus1)
local enable_crash = false --local enable_crash = false
local crash_threshold = 6.5 -- ignored if enable_crash=false --local crash_threshold = 6.5 -- ignored if enable_crash=false
local math = math
local vector = vector
------------------------------------------------------------------------------ ------------------------------------------------------------------------------
@ -10,7 +13,7 @@ local crash_threshold = 6.5 -- ignored if enable_crash=false
-- Helper functions -- Helper functions
-- --
local node_ok = function(pos, fallback) --[[local function node_ok(pos, fallback)
fallback = fallback or mobs.fallback_node fallback = fallback or mobs.fallback_node
@ -21,10 +24,10 @@ local node_ok = function(pos, fallback)
end end
return {name = fallback} return {name = fallback}
end end]]
local function node_is(pos) --[[local function node_is(pos)
local node = node_ok(pos) local node = node_ok(pos)
@ -45,7 +48,7 @@ local function node_is(pos)
end end
return "other" return "other"
end end]]
local function get_sign(i) local function get_sign(i)
@ -60,13 +63,11 @@ local function get_sign(i)
end end
local function get_velocity(v, yaw, y) --[[local function get_velocity(v, yaw, y)
local x = -math.sin(yaw) * v local x = -math.sin(yaw) * v
local z = math.cos(yaw) * v local z = math.cos(yaw) * v
return {x = x, y = y, z = z} return {x = x, y = y, z = z}
end end]]
local function get_v(v) local function get_v(v)
@ -172,7 +173,7 @@ function mobs.detach(player, offset)
--pos = {x = pos.x + offset.x, y = pos.y + 0.2 + offset.y, z = pos.z + offset.z} --pos = {x = pos.x + offset.x, y = pos.y + 0.2 + offset.y, z = pos.z + offset.z}
player:add_velocity(vector.new(math.random(-6,6),math.random(5,8),math.random(-6,6))) --throw the rider off player:add_velocity(vector.new(math.random(-6,6), math.random(5,8), math.random(-6,6))) --throw the rider off
--[[ --[[
minetest.after(0.1, function(name, pos) minetest.after(0.1, function(name, pos)
@ -187,13 +188,13 @@ end
function mobs.drive(entity, moving_anim, stand_anim, can_fly, dtime) function mobs.drive(entity, moving_anim, stand_anim, can_fly, dtime)
local rot_view = 0 --local rot_view = 0
if entity.player_rotation.y == 90 then --if entity.player_rotation.y == 90 then
rot_view = math.pi/2 -- rot_view = math.pi/2
end --end
local acce_y = 0 --local acce_y = 0
local velo = entity.object:get_velocity() local velo = entity.object:get_velocity()
entity.v = get_v(velo) * get_sign(entity.v) entity.v = get_v(velo) * get_sign(entity.v)
@ -388,7 +389,6 @@ end
-- directional flying routine by D00Med (edited by TenPlus1) -- directional flying routine by D00Med (edited by TenPlus1)
function mobs.fly(entity, dtime, speed, shoots, arrow, moving_anim, stand_anim) function mobs.fly(entity, dtime, speed, shoots, arrow, moving_anim, stand_anim)
if true then if true then
print("succ") print("succ")
return return

View File

@ -9,9 +9,9 @@ local get_objects_inside_radius = minetest.get_objects_inside_radius
local math_random = math.random local math_random = math.random
local math_floor = math.floor local math_floor = math.floor
local max = math.max --local max = math.max
local vector_distance = vector.distance --local vector_distance = vector.distance
local vector_new = vector.new local vector_new = vector.new
local vector_floor = vector.floor local vector_floor = vector.floor
@ -167,7 +167,7 @@ Overworld regular:
-- count how many mobs are in an area -- count how many mobs are in an area
local count_mobs = function(pos) local function count_mobs(pos)
local num = 0 local num = 0
for _,object in pairs(get_objects_inside_radius(pos, aoc_range)) do for _,object in pairs(get_objects_inside_radius(pos, aoc_range)) do
if object and object:get_luaentity() and object:get_luaentity()._cmi_is_mob then if object and object:get_luaentity() and object:get_luaentity()._cmi_is_mob then
@ -242,8 +242,7 @@ function mobs:spawn_specific(name, dimension, type_of_spawning, biomes, min_ligh
end end
--[[ --[[
local spawn_action local function spawn_action(pos, node, active_object_count, active_object_count_wider, name)
spawn_action = function(pos, node, active_object_count, active_object_count_wider, name)
local orig_pos = table.copy(pos) local orig_pos = table.copy(pos)
-- is mob actually registered? -- is mob actually registered?
@ -486,7 +485,8 @@ local axis
local inner = 15 local inner = 15
local outer = 64 local outer = 64
local int = {-1,1} local int = {-1,1}
local position_calculation = function(pos)
local function position_calculation(pos)
pos = vector_floor(pos) pos = vector_floor(pos)
@ -501,7 +501,7 @@ local position_calculation = function(pos)
pos.z = pos.z + math_random(inner,outer)*int[math_random(1,2)] pos.z = pos.z + math_random(inner,outer)*int[math_random(1,2)]
pos.x = pos.x + math_random(-outer,outer) pos.x = pos.x + math_random(-outer,outer)
end end
return(pos) return pos
end end
--[[ --[[
@ -573,10 +573,10 @@ if mobs_spawn then
local spawning_position = spawning_position_list[math_random(1,#spawning_position_list)] local spawning_position = spawning_position_list[math_random(1,#spawning_position_list)]
--Prevent strange behavior --- this is commented out: /too close to player --fixed with inner circle --Prevent strange behavior --- this is commented out: /too close to player --fixed with inner circle
if not spawning_position then -- or vector_distance(player_pos, spawning_position) < 15 if not spawning_position then -- or vector_distance(player_pos, spawning_position) < 15
break break
end end
--hard code mob limit in area to 5 for now --hard code mob limit in area to 5 for now
if count_mobs(spawning_position) >= 5 then if count_mobs(spawning_position) >= 5 then
break break
@ -606,7 +606,7 @@ if mobs_spawn then
local is_lava = get_item_group(gotten_node, "lava") ~= 0 local is_lava = get_item_group(gotten_node, "lava") ~= 0
local mob_def = nil local mob_def = nil
--create a disconnected clone of the spawn dictionary --create a disconnected clone of the spawn dictionary
--prevents memory leak --prevents memory leak
local mob_library_worker_table = table_copy(spawn_dictionary) local mob_library_worker_table = table_copy(spawn_dictionary)

View File

@ -2,4 +2,4 @@ name = mcl_mobs
author = PilzAdam author = PilzAdam
description = Adds a mob API for mods to add animals or monsters, etc. description = Adds a mob API for mods to add animals or monsters, etc.
depends = mcl_particles depends = mcl_particles
optional_depends = mcl_weather, mcl_explosions, mcl_hunger, mcl_worlds, invisibility, cmi, doc_identifier, mcl_armor, mcl_portals, mcl_experience optional_depends = mcl_weather, mcl_explosions, mcl_hunger, mcl_worlds, cmi, doc_identifier, mcl_armor, mcl_portals, mcl_experience

View File

@ -4,9 +4,11 @@ dofile(minetest.get_modpath(minetest.get_current_modname()).."/paintings.lua")
local S = minetest.get_translator("mcl_paintings") local S = minetest.get_translator("mcl_paintings")
local math = math
local wood = "[combine:16x16:-192,0=mcl_paintings_paintings.png" local wood = "[combine:16x16:-192,0=mcl_paintings_paintings.png"
local is_protected = function(pos, name) local function is_protected(pos, name)
if minetest.is_protected(pos, name) then if minetest.is_protected(pos, name) then
minetest.record_protection_violation(pos, name) minetest.record_protection_violation(pos, name)
return true return true
@ -17,7 +19,7 @@ end
-- Check if there's a painting for provided painting size. -- Check if there's a painting for provided painting size.
-- If yes, returns the arguments. -- If yes, returns the arguments.
-- If not, returns the next smaller available painting. -- If not, returns the next smaller available painting.
local shrink_painting = function(x, y) local function shrink_painting(x, y)
if x > 4 or y > 4 then if x > 4 or y > 4 then
return nil return nil
end end
@ -43,7 +45,7 @@ local shrink_painting = function(x, y)
end end
end end
local get_painting = function(x, y, motive) local function get_painting(x, y, motive)
local painting = mcl_paintings.paintings[y] and mcl_paintings.paintings[y][x] and mcl_paintings.paintings[y][x][motive] local painting = mcl_paintings.paintings[y] and mcl_paintings.paintings[y][x] and mcl_paintings.paintings[y][x][motive]
if not painting then if not painting then
return nil return nil
@ -53,7 +55,7 @@ local get_painting = function(x, y, motive)
return "[combine:"..sx.."x"..sy..":"..px..","..py.."=mcl_paintings_paintings.png" return "[combine:"..sx.."x"..sy..":"..px..","..py.."=mcl_paintings_paintings.png"
end end
local get_random_painting = function(x, y) local function get_random_painting(x, y)
if not mcl_paintings.paintings[y] or not mcl_paintings.paintings[y][x] then if not mcl_paintings.paintings[y] or not mcl_paintings.paintings[y][x] then
return nil return nil
end end
@ -65,7 +67,7 @@ local get_random_painting = function(x, y)
return get_painting(x, y, r), r return get_painting(x, y, r), r
end end
local size_to_minmax = function(size) --[[local function size_to_minmax(size)
local min, max local min, max
if size == 2 then if size == 2 then
min = -0.5 min = -0.5
@ -81,13 +83,13 @@ local size_to_minmax = function(size)
max = 0.5 max = 0.5
end end
return min, max return min, max
end end]]
local size_to_minmax_entity = function(size) local function size_to_minmax_entity(size)
return -size/2, size/2 return -size/2, size/2
end end
local set_entity = function(object) local function set_entity(object)
local ent = object:get_luaentity() local ent = object:get_luaentity()
local wallm = ent._facing local wallm = ent._facing
local xsize = ent._xsize local xsize = ent._xsize
@ -169,7 +171,7 @@ minetest.register_entity("mcl_paintings:painting", {
on_punch = function(self, puncher, time_from_last_punch, tool_capabilities, dir, damage) on_punch = function(self, puncher, time_from_last_punch, tool_capabilities, dir, damage)
-- Drop as item on punch -- Drop as item on punch
if puncher and puncher:is_player() then if puncher and puncher:is_player() then
kname = puncher:get_player_name() local kname = puncher:get_player_name()
local pos = self._pos local pos = self._pos
if not pos then if not pos then
pos = self.object:get_pos() pos = self.object:get_pos()

View File

@ -3,7 +3,7 @@ local TS = 16 -- texture size
mcl_paintings.paintings = { mcl_paintings.paintings = {
[1] = { [1] = {
[1] = { [1] = {
{ cx = 0, cy = 0 }, { cx = 0, cy = 0 },
{ cx = TS, cy = 0 }, { cx = TS, cy = 0 },
{ cx = 2*TS, cy = 0 }, { cx = 2*TS, cy = 0 },
{ cx = 3*TS, cy = 0 }, { cx = 3*TS, cy = 0 },
@ -26,7 +26,7 @@ mcl_paintings.paintings = {
{ cx = 0, cy = 4*TS }, { cx = 0, cy = 4*TS },
{ cx = TS, cy = 4*TS }, { cx = TS, cy = 4*TS },
}, },
[2] = { [2] = {
{ cx = 0, cy = 8*TS }, { cx = 0, cy = 8*TS },
{ cx = 2*TS, cy = 8*TS }, { cx = 2*TS, cy = 8*TS },
{ cx = 4*TS, cy = 8*TS }, { cx = 4*TS, cy = 8*TS },
@ -35,7 +35,7 @@ mcl_paintings.paintings = {
{ cx = 10*TS, cy = 8*TS }, { cx = 10*TS, cy = 8*TS },
}, },
[3] = 2, [3] = 2,
[4] = { [4] = {
{ cx = 0, cy = 6*TS }, { cx = 0, cy = 6*TS },
}, },
}, },

View File

@ -83,7 +83,7 @@ mobs_mc.items = {
water_source = "default:water_source", water_source = "default:water_source",
water_flowing = "default:water_flowing", water_flowing = "default:water_flowing",
river_water_source = "default:river_water_source", river_water_source = "default:river_water_source",
water_flowing = "default:river_water_flowing", --water_flowing = "default:river_water_flowing",
black_dye = "dye:black", black_dye = "dye:black",
poppy = "flowers:rose", poppy = "flowers:rose",
dandelion = "flowers:dandelion_yellow", dandelion = "flowers:dandelion_yellow",
@ -128,7 +128,6 @@ mobs_mc.items = {
nether_portal = "nether:portal", nether_portal = "nether:portal",
netherrack = "nether:rack", netherrack = "nether:rack",
nether_brick_block = "nether:brick",
-- Wool (Minecraft color scheme) -- Wool (Minecraft color scheme)
wool_white = "wool:white", wool_white = "wool:white",

View File

@ -6,7 +6,7 @@
-- NOTE: Strings intentionally not marked for translation, other mods already have these items. -- NOTE: Strings intentionally not marked for translation, other mods already have these items.
-- TODO: Remove this file eventually, all items here are already outsourced in other mods. -- TODO: Remove this file eventually, all items here are already outsourced in other mods.
local S = minetest.get_translator("mobs_mc") --local S = minetest.get_translator("mobs_mc")
--maikerumines throwing code --maikerumines throwing code
--arrow (weapon) --arrow (weapon)

View File

@ -3,8 +3,9 @@
-- NOTE: Strings intentionally not marked for translation, other mods already have these items. -- NOTE: Strings intentionally not marked for translation, other mods already have these items.
-- TODO: Remove this file eventually, all items here are already outsourced in other mods. -- TODO: Remove this file eventually, all items here are already outsourced in other mods.
-- TODO: Add translation.
local S = minetest.get_translator("mobs_mc") --local S = minetest.get_translator("mobs_mc")
-- Heads system -- Heads system

View File

@ -20,7 +20,7 @@ mobs:register_mob("mobs_mc:blaze", {
xp_max = 10, xp_max = 10,
tilt_fly = false, tilt_fly = false,
hostile = true, hostile = true,
rotate = 270, --rotate = 270,
collisionbox = {-0.3, -0.01, -0.3, 0.3, 1.79, 0.3}, collisionbox = {-0.3, -0.01, -0.3, 0.3, 1.79, 0.3},
rotate = -180, rotate = -180,
visual = "mesh", visual = "mesh",

View File

@ -89,7 +89,7 @@ local cow_def = {
--head code --head code
has_head = true, has_head = true,
head_bone = "head", head_bone = "head",
swap_y_with_x = false, swap_y_with_x = false,
reverse_head_yaw = false, reverse_head_yaw = false,
@ -168,7 +168,7 @@ mooshroom_def.on_rightclick = function(self, clicker)
pos.y = pos.y + 0.5 pos.y = pos.y + 0.5
minetest.add_item(pos, {name = mobs_mc.items.mushroom_stew}) minetest.add_item(pos, {name = mobs_mc.items.mushroom_stew})
end end
end end
end end
mobs:register_mob("mobs_mc:mooshroom", mooshroom_def) mobs:register_mob("mobs_mc:mooshroom", mooshroom_def)

View File

@ -16,7 +16,7 @@ mobs:register_mob("mobs_mc:enderdragon", {
shoot_arrow = function(self, pos, dir) shoot_arrow = function(self, pos, dir)
-- 2-4 damage per arrow -- 2-4 damage per arrow
local dmg = math.random(2,4) local dmg = math.random(2,4)
mobs.shoot_projectile_handling("mobs_mc:dragon_fireball", pos, dir, self.object:get_yaw(), self.object, nil, dmg) mobs.shoot_projectile_handling("mobs_mc:dragon_fireball", pos, dir, self.object:get_yaw(), self.object, nil, dmg)
end, end,
hp_max = 200, hp_max = 200,
hp_min = 200, hp_min = 200,
@ -24,7 +24,6 @@ mobs:register_mob("mobs_mc:enderdragon", {
xp_max = 500, xp_max = 500,
collisionbox = {-2, 0, -2, 2, 2, 2}, collisionbox = {-2, 0, -2, 2, 2, 2},
eye_height = 1, eye_height = 1,
physical = false,
visual = "mesh", visual = "mesh",
mesh = "mobs_mc_dragon.b3d", mesh = "mobs_mc_dragon.b3d",
textures = { textures = {
@ -60,8 +59,6 @@ mobs:register_mob("mobs_mc:enderdragon", {
arrow = "mobs_mc:dragon_fireball", arrow = "mobs_mc:dragon_fireball",
shoot_interval = 0.5, shoot_interval = 0.5,
shoot_offset = -1.0, shoot_offset = -1.0,
xp_min = 500,
xp_max = 500,
animation = { animation = {
fly_speed = 8, stand_speed = 8, fly_speed = 8, stand_speed = 8,
stand_start = 0, stand_end = 20, stand_start = 0, stand_end = 20,
@ -114,8 +111,8 @@ mobs:register_mob("mobs_mc:enderdragon", {
fire_resistant = true, fire_resistant = true,
}) })
--TODO: replace this setting by a proper gamerules system
local mobs_griefing = minetest.settings:get_bool("mobs_griefing") ~= false local mobs_griefing = minetest.settings:get_bool("mobs_griefing", true)
-- dragon fireball (projectile) -- dragon fireball (projectile)
mobs:register_arrow("mobs_mc:dragon_fireball", { mobs:register_arrow("mobs_mc:dragon_fireball", {
@ -143,7 +140,9 @@ mobs:register_arrow("mobs_mc:dragon_fireball", {
-- node hit, explode -- node hit, explode
hit_node = function(self, pos, node) hit_node = function(self, pos, node)
--mobs:boom(self, pos, 2) --mobs:boom(self, pos, 2)
mcl_explosions.explode(self.object:get_pos(), 2,{ drop_chance = 1.0 }) if mobs_griefing then
mcl_explosions.explode(self.object:get_pos(), 2, { drop_chance = 1.0 })
end
end end
}) })

View File

@ -318,12 +318,12 @@ mobs:register_mob("mobs_mc:enderman", {
for n = 1, #objs do for n = 1, #objs do
local obj = objs[n] local obj = objs[n]
if obj then if obj then
if minetest.is_player(obj) then --if minetest.is_player(obj) then
-- Warp from players during day. -- Warp from players during day.
--if (minetest.get_timeofday() * 24000) > 5001 and (minetest.get_timeofday() * 24000) < 19000 then --if (minetest.get_timeofday() * 24000) > 5001 and (minetest.get_timeofday() * 24000) < 19000 then
-- self:teleport(nil) -- self:teleport(nil)
--end --end
else if not obj:is_player() then
local lua = obj:get_luaentity() local lua = obj:get_luaentity()
if lua then if lua then
if lua.name == "mcl_bows:arrow_entity" or lua.name == "mcl_throwing:snowball_entity" then if lua.name == "mcl_bows:arrow_entity" or lua.name == "mcl_throwing:snowball_entity" then

View File

@ -13,7 +13,7 @@ mobs:register_mob("mobs_mc:guardian", {
xp_min = 10, xp_min = 10,
xp_max = 10, xp_max = 10,
breath_max = -1, breath_max = -1,
passive = false, passive = false,
attack_type = "punch", attack_type = "punch",
pathfinding = 1, pathfinding = 1,
view_range = 16, view_range = 16,
@ -94,7 +94,6 @@ mobs:register_mob("mobs_mc:guardian", {
makes_footstep_sound = false, makes_footstep_sound = false,
fly_in = { mobs_mc.items.water_source, mobs_mc.items.river_water_source }, fly_in = { mobs_mc.items.water_source, mobs_mc.items.river_water_source },
jump = false, jump = false,
view_range = 16,
}) })
-- Spawning disabled due to size issues -- Spawning disabled due to size issues

View File

@ -104,7 +104,6 @@ mobs:register_mob("mobs_mc:guardian_elder", {
makes_footstep_sound = false, makes_footstep_sound = false,
fly_in = { mobs_mc.items.water_source, mobs_mc.items.river_water_source }, fly_in = { mobs_mc.items.water_source, mobs_mc.items.river_water_source },
jump = false, jump = false,
view_range = 16,
}) })
-- Spawning disabled due to size issues <- what do you mean? -j4i -- Spawning disabled due to size issues <- what do you mean? -j4i

View File

@ -38,9 +38,9 @@ end
local can_equip_horse_armor = function(entity_id) local can_equip_horse_armor = function(entity_id)
return entity_id == "mobs_mc:horse" or entity_id == "mobs_mc:skeleton_horse" or entity_id == "mobs_mc:zombie_horse" return entity_id == "mobs_mc:horse" or entity_id == "mobs_mc:skeleton_horse" or entity_id == "mobs_mc:zombie_horse"
end end
local can_equip_chest = function(entity_id) --[[local can_equip_chest = function(entity_id)
return entity_id == "mobs_mc:mule" or entity_id == "mobs_mc:donkey" return entity_id == "mobs_mc:mule" or entity_id == "mobs_mc:donkey"
end end]]
local can_breed = function(entity_id) local can_breed = function(entity_id)
return entity_id == "mobs_mc:horse" or "mobs_mc:mule" or entity_id == "mobs_mc:donkey" return entity_id == "mobs_mc:horse" or "mobs_mc:mule" or entity_id == "mobs_mc:donkey"
end end
@ -314,7 +314,7 @@ local horse = {
-- Make sure tamed horse is mature and being clicked by owner only -- Make sure tamed horse is mature and being clicked by owner only
if self.tamed and not self.child and self.owner == clicker:get_player_name() then if self.tamed and not self.child and self.owner == clicker:get_player_name() then
local inv = clicker:get_inventory() --local inv = clicker:get_inventory()
-- detatch player already riding horse -- detatch player already riding horse
if self.driver and clicker == self.driver then if self.driver and clicker == self.driver then

View File

@ -18,7 +18,7 @@ mobs:register_mob("mobs_mc:iron_golem", {
passive = true, passive = true,
rotate = 270, rotate = 270,
hp_min = 100, hp_min = 100,
hp_max = 100, hp_max = 100,
protect = true, protect = true,
neutral = true, neutral = true,
breath_max = -1, breath_max = -1,

View File

@ -35,7 +35,7 @@ mobs:register_mob("mobs_mc:llama", {
shoot_arrow = function(self, pos, dir) shoot_arrow = function(self, pos, dir)
-- 2-4 damage per arrow -- 2-4 damage per arrow
local dmg = 1 local dmg = 1
mobs.shoot_projectile_handling("mobs_mc:spit", pos, dir, self.object:get_yaw(), self.object, nil, dmg) mobs.shoot_projectile_handling("mobs_mc:spit", pos, dir, self.object:get_yaw(), self.object, nil, dmg)
end, end,
hp_min = 15, hp_min = 15,
hp_max = 30, hp_max = 30,
@ -146,7 +146,7 @@ mobs:register_mob("mobs_mc:llama", {
self.tamed = true self.tamed = true
self.owner = clicker:get_player_name() self.owner = clicker:get_player_name()
return return
end end
--ignore other logic --ignore other logic
--make baby grow faster --make baby grow faster
@ -307,19 +307,19 @@ mobs:register_arrow("mobs_mc:spit", {
tail_distance_divider = 4, tail_distance_divider = 4,
hit_player = function(self, player) hit_player = function(self, player)
if rawget(_G, "armor") and armor.last_damage_types then --[[if rawget(_G, "armor") and armor.last_damage_types then
armor.last_damage_types[player:get_player_name()] = "spit" armor.last_damage_types[player:get_player_name()] = "spit"
end end]]
player:punch(self.object, 1.0, { player:punch(self.object, 1.0, {
full_punch_interval = 1.0, full_punch_interval = 1.0,
damage_groups = {fleshy = self._damage}, damage_groups = {fleshy = self._damage},
}, nil) }, nil)
end, end,
hit_mob = function(self, mob) hit_mob = function(self, mob)
mob:punch(self.object, 1.0, { mob:punch(self.object, 1.0, {
full_punch_interval = 1.0, full_punch_interval = 1.0,
damage_groups = {fleshy = _damage}, damage_groups = {fleshy = self._damage},
}, nil) }, nil)
end, end,

View File

@ -151,7 +151,7 @@ end
mobs:register_mob("mobs_mc:cat", cat) mobs:register_mob("mobs_mc:cat", cat)
local base_spawn_chance = 5000 --local base_spawn_chance = 5000
-- Spawn ocelot -- Spawn ocelot
--they get the same as the llama because I'm trying to rework so much of this code right now -j4i --they get the same as the llama because I'm trying to rework so much of this code right now -j4i

View File

@ -44,7 +44,7 @@ mobs:register_mob("mobs_mc:parrot", {
max = 2, max = 2,
looting = "common",}, looting = "common",},
}, },
animation = { animation = {
stand_speed = 50, stand_speed = 50,
walk_speed = 50, walk_speed = 50,
fly_speed = 50, fly_speed = 50,

View File

@ -130,7 +130,7 @@ mobs:register_mob("mobs_mc:pig", {
-- Put saddle on pig -- Put saddle on pig
local item = clicker:get_wielded_item() local item = clicker:get_wielded_item()
local wielditem = item local wielditem = item
if item:get_name() == mobs_mc.items.saddle and self.saddle ~= "yes" then if item:get_name() == mobs_mc.items.saddle and self.saddle ~= "yes" then
self.base_texture = { self.base_texture = {
"blank.png", -- baby "blank.png", -- baby
@ -163,7 +163,7 @@ mobs:register_mob("mobs_mc:pig", {
end end
-- Mount or detach player -- Mount or detach player
local name = clicker:get_player_name() --local name = clicker:get_player_name()
if self.driver and clicker == self.driver then if self.driver and clicker == self.driver then
-- Detach if already attached -- Detach if already attached
mobs.detach(clicker, {x=1, y=0, z=0}) mobs.detach(clicker, {x=1, y=0, z=0})

View File

@ -79,11 +79,11 @@ mobs:register_mob("mobs_mc:sheep", {
makes_footstep_sound = true, makes_footstep_sound = true,
walk_velocity = 1, walk_velocity = 1,
run_velocity = 3, run_velocity = 3,
--head code --head code
has_head = true, has_head = true,
head_bone = "head", head_bone = "head",
swap_y_with_x = false, swap_y_with_x = false,
reverse_head_yaw = false, reverse_head_yaw = false,
@ -150,7 +150,6 @@ mobs:register_mob("mobs_mc:sheep", {
do_custom = function(self, dtime) do_custom = function(self, dtime)
if not self.initial_color_set then if not self.initial_color_set then
local r = math.random(0,100000) local r = math.random(0,100000)
local textures
if r <= 81836 then if r <= 81836 then
-- 81.836% -- 81.836%
self.color = "unicolor_white" self.color = "unicolor_white"

View File

@ -46,7 +46,6 @@ mobs:register_mob("mobs_mc:silverfish", {
view_range = 16, view_range = 16,
attack_type = "punch", attack_type = "punch",
damage = 1, damage = 1,
reach = 1,
}) })
mobs:register_egg("mobs_mc:silverfish", S("Silverfish"), "mobs_mc_spawn_icon_silverfish.png", 0) mobs:register_egg("mobs_mc:silverfish", S("Silverfish"), "mobs_mc_spawn_icon_silverfish.png", 0)

View File

@ -31,12 +31,8 @@ local skeleton = {
group_attack = true, group_attack = true,
visual = "mesh", visual = "mesh",
mesh = "mobs_mc_skeleton.b3d", mesh = "mobs_mc_skeleton.b3d",
textures = { {
"mcl_bows_bow_0.png", -- bow
"mobs_mc_skeleton.png", -- skeleton
} },
--head code --head code
has_head = false, has_head = false,
head_bone = "head", head_bone = "head",

View File

@ -15,7 +15,7 @@ mobs:register_mob("mobs_mc:vex", {
spawn_class = "hostile", spawn_class = "hostile",
pathfinding = 1, pathfinding = 1,
passive = false, passive = false,
attack_type = "punch", attack_type = "dogfight",
physical = false, physical = false,
hp_min = 14, hp_min = 14,
hp_max = 14, hp_max = 14,
@ -36,7 +36,6 @@ mobs:register_mob("mobs_mc:vex", {
view_range = 16, view_range = 16,
walk_velocity = 3.2, walk_velocity = 3.2,
run_velocity = 5.9, run_velocity = 5.9,
attack_type = "dogfight",
sounds = { sounds = {
-- TODO: random -- TODO: random
death = "mobs_mc_vex_death", death = "mobs_mc_vex_death",

View File

@ -26,7 +26,6 @@ mobs:register_mob("mobs_mc:wither", {
{"mobs_mc_wither.png"}, {"mobs_mc_wither.png"},
}, },
visual_size = {x=4, y=4}, visual_size = {x=4, y=4},
makes_footstep_sound = true,
view_range = 16, view_range = 16,
fear_height = 4, fear_height = 4,
walk_velocity = 2, walk_velocity = 2,
@ -81,7 +80,7 @@ mobs:register_mob("mobs_mc:wither", {
end, end,
}) })
local mobs_griefing = minetest.settings:get_bool("mobs_griefing") ~= false --local mobs_griefing = minetest.settings:get_bool("mobs_griefing") ~= false
mobs:register_arrow("mobs_mc:wither_skull", { mobs:register_arrow("mobs_mc:wither_skull", {
visual = "sprite", visual = "sprite",

View File

@ -35,7 +35,7 @@ local wolf = {
--head code --head code
has_head = false, has_head = false,
head_bone = "head", head_bone = "head",
swap_y_with_x = false, swap_y_with_x = false,
reverse_head_yaw = false, reverse_head_yaw = false,
@ -186,7 +186,7 @@ dog.on_rightclick = function(self, clicker)
if is_food(item:get_name()) then if is_food(item:get_name()) then
-- Feed to increase health -- Feed to increase health
local hp = self.health local hp = self.health
local hp_add = 0 local hp_add
-- Use eatable group to determine health boost -- Use eatable group to determine health boost
local eatable = minetest.get_item_group(item, "eatable") local eatable = minetest.get_item_group(item, "eatable")
if eatable > 0 then if eatable > 0 then

View File

@ -200,14 +200,14 @@ end
mobs_mc.override.enderman_block_texture_overrides = { mobs_mc.override.enderman_block_texture_overrides = {
["mcl_core:cactus"] = ctable, ["mcl_core:cactus"] = ctable,
-- FIXME: replace colorize colors with colors from palette -- FIXME: replace colorize colors with colors from palette
["mcl_core:dirt_with_grass"] = ["mcl_core:dirt_with_grass"] = {
{ "mcl_core_grass_block_top.png^[colorize:green:90",
"mcl_core_grass_block_top.png^[colorize:green:90", "default_dirt.png",
"default_dirt.png", "default_dirt.png^(mcl_core_grass_block_side_overlay.png^[colorize:green:90)",
"default_dirt.png^(mcl_core_grass_block_side_overlay.png^[colorize:green:90)", "default_dirt.png^(mcl_core_grass_block_side_overlay.png^[colorize:green:90)",
"default_dirt.png^(mcl_core_grass_block_side_overlay.png^[colorize:green:90)", "default_dirt.png^(mcl_core_grass_block_side_overlay.png^[colorize:green:90)",
"default_dirt.png^(mcl_core_grass_block_side_overlay.png^[colorize:green:90)", "default_dirt.png^(mcl_core_grass_block_side_overlay.png^[colorize:green:90)",
"default_dirt.png^(mcl_core_grass_block_side_overlay.png^[colorize:green:90)"} },
} }
-- List of nodes on which mobs can spawn -- List of nodes on which mobs can spawn

View File

@ -134,6 +134,7 @@ lightning.strike = function(pos)
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
-- TODO: use an API insteed of hardcoding this behaviour
local objs = 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]
@ -153,7 +154,7 @@ lightning.strike = function(pos)
end end
obj:set_properties({textures = lua.base_texture}) obj:set_properties({textures = lua.base_texture})
-- villager → witch (no damage) -- villager → witch (no damage)
elseif lua and lua.name == "mobs_mc:villager" then --elseif lua and lua.name == "mobs_mc:villager" then
-- Witches are incomplete, this code is unused -- Witches are incomplete, this code is unused
-- TODO: Enable this code when witches are working. -- TODO: Enable this code when witches are working.
--[[ --[[

View File

@ -4,18 +4,16 @@ local SHEET_W = 4
local SHEET_H = 2 local SHEET_H = 2
-- Randomize initial moon phase, based on map seed -- Randomize initial moon phase, based on map seed
local phase_offset
local mg_seed = minetest.get_mapgen_setting("seed") local mg_seed = minetest.get_mapgen_setting("seed")
local rand = PseudoRandom(mg_seed) local rand = PseudoRandom(mg_seed)
local phase_offset = rand:next(0, MOON_PHASES - 1) local phase_offset = rand:next(0, MOON_PHASES - 1)
rand = nil
minetest.log("info", "[mcl_moon] Moon phase offset of this world: "..phase_offset) minetest.log("info", "[mcl_moon] Moon phase offset of this world: "..phase_offset)
mcl_moon = {} mcl_moon = {}
mcl_moon.MOON_PHASES = MOON_PHASES mcl_moon.MOON_PHASES = MOON_PHASES
mcl_moon.get_moon_phase = function() function mcl_moon.get_moon_phase()
local after_midday = 0 local after_midday = 0
-- Moon phase changes after midday -- Moon phase changes after midday
local tod = minetest.get_timeofday() local tod = minetest.get_timeofday()
@ -25,7 +23,7 @@ mcl_moon.get_moon_phase = function()
return (minetest.get_day_count() + phase_offset + after_midday) % MOON_PHASES return (minetest.get_day_count() + phase_offset + after_midday) % MOON_PHASES
end end
local get_moon_texture = function() local function get_moon_texture()
local phase = mcl_moon.get_moon_phase() local phase = mcl_moon.get_moon_phase()
local x = phase % MOON_PHASES_HALF local x = phase % MOON_PHASES_HALF
local y local y

View File

@ -1,5 +1,5 @@
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 pos_to_dim = mcl_worlds.pos_to_dimension
local dim_change = mcl_worlds.dimension_change local dim_change = mcl_worlds.dimension_change
@ -39,9 +39,9 @@ minetest.register_on_mods_loaded(function()
end end
self._void_timer = 0 self._void_timer = 0
local void, void_deadly = is_in_void(pos) local _, 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()
return return
end end
@ -61,7 +61,7 @@ minetest.register_globalstep(function(dtime)
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 = is_in_void(pos) local _, 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

View File

@ -20,7 +20,7 @@ mcl_weather.rain = {
init_done = false, init_done = false,
} }
mcl_weather.rain.sound_handler = function(player) function mcl_weather.rain.sound_handler(player)
return minetest.sound_play("weather_rain", { return minetest.sound_play("weather_rain", {
to_player = player:get_player_name(), to_player = player:get_player_name(),
loop = true, loop = true,
@ -28,7 +28,7 @@ mcl_weather.rain.sound_handler = function(player)
end end
-- set skybox based on time (uses skycolor api) -- set skybox based on time (uses skycolor api)
mcl_weather.rain.set_sky_box = function() function mcl_weather.rain.set_sky_box()
if mcl_weather.state == "rain" then if mcl_weather.state == "rain" then
mcl_weather.skycolor.add_layer( mcl_weather.skycolor.add_layer(
"weather-pack-rain-sky", "weather-pack-rain-sky",
@ -46,8 +46,7 @@ end
-- creating manually parctiles instead of particles spawner because of easier to control -- creating manually parctiles instead of particles spawner because of easier to control
-- spawn position. -- spawn position.
mcl_weather.rain.add_rain_particles = function(player) function mcl_weather.rain.add_rain_particles(player)
mcl_weather.rain.last_rp_count = 0 mcl_weather.rain.last_rp_count = 0
for i=mcl_weather.rain.particles_count, 1,-1 do for i=mcl_weather.rain.particles_count, 1,-1 do
local random_pos_x, random_pos_y, random_pos_z = mcl_weather.get_random_pos_by_player_look_dir(player) local random_pos_x, random_pos_y, random_pos_z = mcl_weather.get_random_pos_by_player_look_dir(player)
@ -70,7 +69,7 @@ mcl_weather.rain.add_rain_particles = function(player)
end end
-- Simple random texture getter -- Simple random texture getter
mcl_weather.rain.get_texture = function() function mcl_weather.rain.get_texture()
local texture_name local texture_name
local random_number = math.random() local random_number = math.random()
if random_number > 0.33 then if random_number > 0.33 then
@ -85,7 +84,7 @@ end
-- register player for rain weather. -- register player for rain weather.
-- basically needs for origin sky reference and rain sound controls. -- basically needs for origin sky reference and rain sound controls.
mcl_weather.rain.add_player = function(player) function mcl_weather.rain.add_player(player)
if mcl_weather.players[player:get_player_name()] == nil then if mcl_weather.players[player:get_player_name()] == nil then
local player_meta = {} local player_meta = {}
player_meta.origin_sky = {player:get_sky()} player_meta.origin_sky = {player:get_sky()}
@ -95,7 +94,7 @@ end
-- remove player from player list effected by rain. -- remove player from player list effected by rain.
-- be sure to remove sound before removing player otherwise soundhandler reference will be lost. -- be sure to remove sound before removing player otherwise soundhandler reference will be lost.
mcl_weather.rain.remove_player = function(player) function mcl_weather.rain.remove_player(player)
local player_meta = mcl_weather.players[player:get_player_name()] local player_meta = mcl_weather.players[player:get_player_name()]
if player_meta ~= nil and player_meta.origin_sky ~= nil then if player_meta ~= nil and player_meta.origin_sky ~= nil then
player:set_clouds({color="#FFF0F0E5"}) player:set_clouds({color="#FFF0F0E5"})
@ -119,7 +118,7 @@ end)
-- adds and removes rain sound depending how much rain particles around player currently exist. -- adds and removes rain sound depending how much rain particles around player currently exist.
-- have few seconds delay before each check to avoid on/off sound too often -- have few seconds delay before each check to avoid on/off sound too often
-- when player stay on 'edge' where sound should play and stop depending from random raindrop appearance. -- when player stay on 'edge' where sound should play and stop depending from random raindrop appearance.
mcl_weather.rain.update_sound = function(player) function mcl_weather.rain.update_sound(player)
local player_meta = mcl_weather.players[player:get_player_name()] local player_meta = mcl_weather.players[player:get_player_name()]
if player_meta ~= nil then if player_meta ~= nil then
if player_meta.sound_updated ~= nil and player_meta.sound_updated + 5 > minetest.get_gametime() then if player_meta.sound_updated ~= nil and player_meta.sound_updated + 5 > minetest.get_gametime() then
@ -140,7 +139,7 @@ mcl_weather.rain.update_sound = function(player)
end end
-- rain sound removed from player. -- rain sound removed from player.
mcl_weather.rain.remove_sound = function(player) function mcl_weather.rain.remove_sound(player)
local player_meta = mcl_weather.players[player:get_player_name()] local player_meta = mcl_weather.players[player:get_player_name()]
if player_meta ~= nil and player_meta.sound_handler ~= nil then if player_meta ~= nil and player_meta.sound_handler ~= nil then
minetest.sound_fade(player_meta.sound_handler, -0.5, 0.0) minetest.sound_fade(player_meta.sound_handler, -0.5, 0.0)
@ -150,7 +149,7 @@ mcl_weather.rain.remove_sound = function(player)
end end
-- callback function for removing rain -- callback function for removing rain
mcl_weather.rain.clear = function() function mcl_weather.rain.clear()
mcl_weather.rain.raining = false mcl_weather.rain.raining = false
mcl_weather.rain.sky_last_update = -1 mcl_weather.rain.sky_last_update = -1
mcl_weather.rain.init_done = false mcl_weather.rain.init_done = false
@ -166,11 +165,10 @@ minetest.register_globalstep(function(dtime)
if mcl_weather.state ~= "rain" then if mcl_weather.state ~= "rain" then
return false return false
end end
mcl_weather.rain.make_weather() mcl_weather.rain.make_weather()
end) end)
mcl_weather.rain.make_weather = function() function mcl_weather.rain.make_weather()
if mcl_weather.rain.init_done == false then if mcl_weather.rain.init_done == false then
mcl_weather.rain.raining = true mcl_weather.rain.raining = true
mcl_weather.rain.set_sky_box() mcl_weather.rain.set_sky_box()
@ -190,7 +188,7 @@ mcl_weather.rain.make_weather = function()
end end
-- Switch the number of raindrops: "thunder" for many raindrops, otherwise for normal raindrops -- Switch the number of raindrops: "thunder" for many raindrops, otherwise for normal raindrops
mcl_weather.rain.set_particles_mode = function(mode) function mcl_weather.rain.set_particles_mode(mode)
if mode == "thunder" then if mode == "thunder" then
mcl_weather.rain.particles_count = PARTICLES_COUNT_THUNDER mcl_weather.rain.particles_count = PARTICLES_COUNT_THUNDER
else else
@ -249,7 +247,7 @@ if mcl_weather.allow_abm then
end end
end end
end end
}) })
-- Wetten the soil -- Wetten the soil
minetest.register_abm({ minetest.register_abm({
@ -264,7 +262,7 @@ if mcl_weather.allow_abm then
end end
end end
end end
}) })
end end
if mcl_weather.reg_weathers.rain == nil then if mcl_weather.reg_weathers.rain == nil then

View File

@ -11,7 +11,7 @@ mcl_weather.skycolor = {
-- Update interval. -- Update interval.
update_interval = 15, update_interval = 15,
-- Main sky colors: starts from midnight to midnight. -- Main sky colors: starts from midnight to midnight.
-- Please do not set directly. Use add_layer instead. -- Please do not set directly. Use add_layer instead.
colors = {}, colors = {},
@ -205,8 +205,8 @@ mcl_weather.skycolor = {
-- Returns first player sky color. I assume that all players are in same color layout. -- Returns first player sky color. I assume that all players are in same color layout.
get_current_bg_color = function() get_current_bg_color = function()
local players = mcl_weather.skycolor.utils.get_players(nil) local players = mcl_weather.skycolor.utils.get_players(nil)
for _, player in ipairs(players) do if players[1] then
return player:get_sky() return players[1]:get_sky()
end end
return nil return nil
end end

View File

@ -5,80 +5,80 @@ mcl_weather.snow = {}
mcl_weather.snow.particles_count = 15 mcl_weather.snow.particles_count = 15
mcl_weather.snow.init_done = false mcl_weather.snow.init_done = false
-- calculates coordinates and draw particles for snow weather -- calculates coordinates and draw particles for snow weather
mcl_weather.snow.add_snow_particles = function(player) mcl_weather.snow.add_snow_particles = function(player)
mcl_weather.rain.last_rp_count = 0 mcl_weather.rain.last_rp_count = 0
for i=mcl_weather.snow.particles_count, 1,-1 do for i=mcl_weather.snow.particles_count, 1,-1 do
local random_pos_x, random_pos_y, random_pos_z = mcl_weather.get_random_pos_by_player_look_dir(player) local random_pos_x, _, random_pos_z = mcl_weather.get_random_pos_by_player_look_dir(player)
random_pos_y = math.random() + math.random(player:get_pos().y - 1, player:get_pos().y + 7) local random_pos_y = math.random() + math.random(player:get_pos().y - 1, player:get_pos().y + 7)
if minetest.get_node_light({x=random_pos_x, y=random_pos_y, z=random_pos_z}, 0.5) == 15 then if minetest.get_node_light({x=random_pos_x, y=random_pos_y, z=random_pos_z}, 0.5) == 15 then
mcl_weather.rain.last_rp_count = mcl_weather.rain.last_rp_count + 1 mcl_weather.rain.last_rp_count = mcl_weather.rain.last_rp_count + 1
minetest.add_particle({ minetest.add_particle({
pos = {x=random_pos_x, y=random_pos_y, z=random_pos_z}, pos = {x=random_pos_x, y=random_pos_y, z=random_pos_z},
velocity = {x = math.random(-100,100)*0.001, y = math.random(-300,-100)*0.004, z = math.random(-100,100)*0.001}, velocity = {x = math.random(-100,100)*0.001, y = math.random(-300,-100)*0.004, z = math.random(-100,100)*0.001},
acceleration = {x = 0, y=0, z = 0}, acceleration = {x = 0, y=0, z = 0},
expirationtime = 8.0, expirationtime = 8.0,
size = 1, size = 1,
collisiondetection = true, collisiondetection = true,
collision_removal = true, collision_removal = true,
object_collision = false, object_collision = false,
vertical = false, vertical = false,
texture = mcl_weather.snow.get_texture(), texture = mcl_weather.snow.get_texture(),
playername = player:get_player_name() playername = player:get_player_name()
}) })
end end
end end
end end
mcl_weather.snow.set_sky_box = function() mcl_weather.snow.set_sky_box = function()
mcl_weather.skycolor.add_layer( mcl_weather.skycolor.add_layer(
"weather-pack-snow-sky", "weather-pack-snow-sky",
{{r=0, g=0, b=0}, {{r=0, g=0, b=0},
{r=85, g=86, b=86}, {r=85, g=86, b=86},
{r=135, g=135, b=135}, {r=135, g=135, b=135},
{r=85, g=86, b=86}, {r=85, g=86, b=86},
{r=0, g=0, b=0}}) {r=0, g=0, b=0}})
mcl_weather.skycolor.active = true mcl_weather.skycolor.active = true
for _, player in pairs(get_connected_players()) do for _, player in pairs(get_connected_players()) do
player:set_clouds({color="#ADADADE8"}) player:set_clouds({color="#ADADADE8"})
end end
mcl_weather.skycolor.active = true mcl_weather.skycolor.active = true
end end
mcl_weather.snow.clear = function() function mcl_weather.snow.clear()
mcl_weather.skycolor.remove_layer("weather-pack-snow-sky") mcl_weather.skycolor.remove_layer("weather-pack-snow-sky")
mcl_weather.snow.init_done = false mcl_weather.snow.init_done = false
end end
-- Simple random texture getter -- Simple random texture getter
mcl_weather.snow.get_texture = function() function mcl_weather.snow.get_texture()
return "weather_pack_snow_snowflake"..math.random(1,2)..".png" return "weather_pack_snow_snowflake"..math.random(1,2)..".png"
end end
local timer = 0 local timer = 0
minetest.register_globalstep(function(dtime) minetest.register_globalstep(function(dtime)
if mcl_weather.state ~= "snow" then if mcl_weather.state ~= "snow" then
return false return false
end end
timer = timer + dtime;
if timer >= 0.5 then
timer = 0
else
return
end
if mcl_weather.snow.init_done == false then timer = timer + dtime;
mcl_weather.snow.set_sky_box() if timer >= 0.5 then
mcl_weather.snow.init_done = true timer = 0
end else
return
end
for _, player in pairs(get_connected_players()) do if mcl_weather.snow.init_done == false then
if (mcl_weather.is_underwater(player) or not mcl_worlds.has_weather(player:get_pos())) then mcl_weather.snow.set_sky_box()
return false mcl_weather.snow.init_done = true
end end
mcl_weather.snow.add_snow_particles(player)
end for _, player in pairs(get_connected_players()) do
if (mcl_weather.is_underwater(player) or not mcl_worlds.has_weather(player:get_pos())) then
return false
end
mcl_weather.snow.add_snow_particles(player)
end
end) end)
-- register snow weather -- register snow weather

View File

@ -4,60 +4,58 @@ local get_connected_players = minetest.get_connected_players
lightning.auto = false lightning.auto = false
mcl_weather.thunder = { mcl_weather.thunder = {
next_strike = 0, next_strike = 0,
min_delay = 3, min_delay = 3,
max_delay = 12, max_delay = 12,
init_done = false, init_done = false,
} }
minetest.register_globalstep(function(dtime) minetest.register_globalstep(function(dtime)
if mcl_weather.get_weather() ~= "thunder" then if mcl_weather.get_weather() ~= "thunder" then
return false return false
end end
mcl_weather.rain.set_particles_mode("thunder")
mcl_weather.rain.make_weather()
if mcl_weather.thunder.init_done == false then mcl_weather.rain.set_particles_mode("thunder")
mcl_weather.skycolor.add_layer( mcl_weather.rain.make_weather()
"weather-pack-thunder-sky",
{{r=0, g=0, b=0},
{r=40, g=40, b=40},
{r=85, g=86, b=86},
{r=40, g=40, b=40},
{r=0, g=0, b=0}})
mcl_weather.skycolor.active = true
for _, player in pairs(get_connected_players()) do
player:set_clouds({color="#3D3D3FE8"})
end
mcl_weather.thunder.init_done = true
end
if (mcl_weather.thunder.next_strike <= minetest.get_gametime()) then
lightning.strike()
local delay = math.random(mcl_weather.thunder.min_delay, mcl_weather.thunder.max_delay)
mcl_weather.thunder.next_strike = minetest.get_gametime() + delay
end
if mcl_weather.thunder.init_done == false then
mcl_weather.skycolor.add_layer("weather-pack-thunder-sky", {
{r=0, g=0, b=0},
{r=40, g=40, b=40},
{r=85, g=86, b=86},
{r=40, g=40, b=40},
{r=0, g=0, b=0},
})
mcl_weather.skycolor.active = true
for _, player in pairs(get_connected_players()) do
player:set_clouds({color="#3D3D3FE8"})
end
mcl_weather.thunder.init_done = true
end
if (mcl_weather.thunder.next_strike <= minetest.get_gametime()) then
lightning.strike()
local delay = math.random(mcl_weather.thunder.min_delay, mcl_weather.thunder.max_delay)
mcl_weather.thunder.next_strike = minetest.get_gametime() + delay
end
end) end)
mcl_weather.thunder.clear = function() function mcl_weather.thunder.clear()
mcl_weather.rain.clear() mcl_weather.rain.clear()
mcl_weather.skycolor.remove_layer("weather-pack-thunder-sky") mcl_weather.skycolor.remove_layer("weather-pack-thunder-sky")
mcl_weather.skycolor.remove_layer("lightning") mcl_weather.skycolor.remove_layer("lightning")
mcl_weather.thunder.init_done = false mcl_weather.thunder.init_done = false
end end
-- register thunderstorm weather -- register thunderstorm weather
if mcl_weather.reg_weathers.thunder == nil then if mcl_weather.reg_weathers.thunder == nil then
mcl_weather.reg_weathers.thunder = { mcl_weather.reg_weathers.thunder = {
clear = mcl_weather.thunder.clear, clear = mcl_weather.thunder.clear,
light_factor = 0.33333, light_factor = 0.33333,
-- 10min - 20min -- 10min - 20min
min_duration = 600, min_duration = 600,
max_duration = 1200, max_duration = 1200,
transitions = { transitions = {
[100] = "rain", [100] = "rain",
} },
} }
end end

View File

@ -1,27 +1,29 @@
local S = minetest.get_translator("mcl_weather") local S = minetest.get_translator("mcl_weather")
local math = math
-- weather states, 'none' is default, other states depends from active mods -- weather states, 'none' is default, other states depends from active mods
mcl_weather.state = "none" mcl_weather.state = "none"
-- player list for saving player meta info -- player list for saving player meta info
mcl_weather.players = {} mcl_weather.players = {}
-- default weather check interval for global step -- default weather check interval for global step
mcl_weather.check_interval = 5 mcl_weather.check_interval = 5
-- weather min duration -- weather min duration
mcl_weather.min_duration = 600 mcl_weather.min_duration = 600
-- weather max duration -- weather max duration
mcl_weather.max_duration = 9000 mcl_weather.max_duration = 9000
-- weather calculated end time -- weather calculated end time
mcl_weather.end_time = nil mcl_weather.end_time = nil
-- registered weathers -- registered weathers
mcl_weather.reg_weathers = {} mcl_weather.reg_weathers = {}
-- global flag to disable/enable ABM logic. -- global flag to disable/enable ABM logic.
mcl_weather.allow_abm = true mcl_weather.allow_abm = true
mcl_weather.reg_weathers["none"] = { mcl_weather.reg_weathers["none"] = {
@ -51,7 +53,7 @@ mcl_weather.get_rand_end_time = function(min_duration, max_duration)
r = math.random(min_duration, max_duration) r = math.random(min_duration, max_duration)
else else
r = math.random(mcl_weather.min_duration, mcl_weather.max_duration) r = math.random(mcl_weather.min_duration, mcl_weather.max_duration)
end end
return minetest.get_gametime() + r return minetest.get_gametime() + r
end end
@ -80,8 +82,8 @@ end
mcl_weather.is_underwater = function(player) mcl_weather.is_underwater = function(player)
local ppos = player:get_pos() local ppos = player:get_pos()
local offset = player:get_eye_offset() local offset = player:get_eye_offset()
local player_eye_pos = {x = ppos.x + offset.x, local player_eye_pos = {x = ppos.x + offset.x,
y = ppos.y + offset.y + 1.5, y = ppos.y + offset.y + 1.5,
z = ppos.z + offset.z} z = ppos.z + offset.z}
local node_level = minetest.get_node_level(player_eye_pos) local node_level = minetest.get_node_level(player_eye_pos)
if node_level == 8 or node_level == 7 then if node_level == 8 or node_level == 7 then
@ -91,14 +93,12 @@ mcl_weather.is_underwater = function(player)
end end
-- trying to locate position for particles by player look direction for performance reason. -- trying to locate position for particles by player look direction for performance reason.
-- it is costly to generate many particles around player so goal is focus mainly on front view. -- it is costly to generate many particles around player so goal is focus mainly on front view.
mcl_weather.get_random_pos_by_player_look_dir = function(player) mcl_weather.get_random_pos_by_player_look_dir = function(player)
local look_dir = player:get_look_dir() local look_dir = player:get_look_dir()
local player_pos = player:get_pos() local player_pos = player:get_pos()
local random_pos_x = 0 local random_pos_x, random_pos_y, random_pos_z
local random_pos_y = 0
local random_pos_z = 0
if look_dir.x > 0 then if look_dir.x > 0 then
if look_dir.z > 0 then if look_dir.z > 0 then
@ -208,7 +208,7 @@ minetest.register_privilege("weather_manager", {
give_to_singleplayer = false give_to_singleplayer = false
}) })
-- Weather command definition. Set -- Weather command definition. Set
minetest.register_chatcommand("weather", { minetest.register_chatcommand("weather", {
params = "(clear | rain | snow | thunder) [<duration>]", params = "(clear | rain | snow | thunder) [<duration>]",
description = S("Changes the weather to the specified parameter."), description = S("Changes the weather to the specified parameter."),
@ -270,7 +270,7 @@ minetest.register_chatcommand("toggledownfall", {
local weather_allow_abm = minetest.settings:get_bool("weather_allow_abm") local weather_allow_abm = minetest.settings:get_bool("weather_allow_abm")
if weather_allow_abm ~= nil and weather_allow_abm == false then if weather_allow_abm ~= nil and weather_allow_abm == false then
mcl_weather.allow_abm = false mcl_weather.allow_abm = false
end end
local load_weather = function() local load_weather = function()

View File

@ -233,7 +233,7 @@ end
-- Returns true if the specified entry has been viewed by the player -- Returns true if the specified entry has been viewed by the player
function doc.entry_viewed(playername, category_id, entry_id) function doc.entry_viewed(playername, category_id, entry_id)
local entry, category_id, entry_id = get_entry(category_id, entry_id) local _, category_id, entry_id = get_entry(category_id, entry_id)
if doc.data.players[playername].stored_data.viewed[category_id] == nil then if doc.data.players[playername].stored_data.viewed[category_id] == nil then
return false return false
else else
@ -243,7 +243,7 @@ end
-- Returns true if the specified entry is hidden from the player -- Returns true if the specified entry is hidden from the player
function doc.entry_revealed(playername, category_id, entry_id) function doc.entry_revealed(playername, category_id, entry_id)
local entry, category_id, entry_id = get_entry(category_id, entry_id) local _, category_id, entry_id = get_entry(category_id, entry_id)
local hidden = doc.data.categories[category_id].entries[entry_id].hidden local hidden = doc.data.categories[category_id].entries[entry_id].hidden
if doc.data.players[playername].stored_data.revealed[category_id] == nil then if doc.data.players[playername].stored_data.revealed[category_id] == nil then
return not hidden return not hidden
@ -302,7 +302,7 @@ function doc.show_entry(playername, category_id, entry_id, ignore_hidden)
minetest.show_formspec(playername, "doc:error_no_categories", doc.formspec_error_no_categories()) minetest.show_formspec(playername, "doc:error_no_categories", doc.formspec_error_no_categories())
return return
end end
local entry, category_id, entry_id = get_entry(category_id, entry_id) local _, category_id, entry_id = get_entry(category_id, entry_id)
if ignore_hidden or doc.entry_revealed(playername, category_id, entry_id) then if ignore_hidden or doc.entry_revealed(playername, category_id, entry_id) then
local playerdata = doc.data.players[playername] local playerdata = doc.data.players[playername]
playerdata.category = category_id playerdata.category = category_id
@ -587,8 +587,6 @@ doc.widgets.gallery = function(imagedata, playername, x, y, aspect_ratio, width,
formstring = formstring .. "label["..nx..","..ny..";"..i.."]" formstring = formstring .. "label["..nx..","..ny..";"..i.."]"
pos = pos + 1 pos = pos + 1
end end
local bw, bh
return formstring, ih return formstring, ih
end end

View File

@ -164,7 +164,7 @@ local factoid_toolcaps = function(tool_capabilities, check_uses)
local useslines = 0 local useslines = 0
for k,v in pairs(groupcaps) do for k,v in pairs(groupcaps) do
-- Mining capabilities -- Mining capabilities
local minrating, maxrating --[[local minrating, maxrating
if v.times then if v.times then
for rating, time in pairs(v.times) do for rating, time in pairs(v.times) do
if minrating == nil then minrating = rating else if minrating == nil then minrating = rating else
@ -177,7 +177,7 @@ local factoid_toolcaps = function(tool_capabilities, check_uses)
else else
minrating = 1 minrating = 1
maxrating = 1 maxrating = 1
end end]]
local maxlevel = v.maxlevel local maxlevel = v.maxlevel
if not maxlevel then if not maxlevel then
-- Default from tool.h -- Default from tool.h
@ -577,11 +577,8 @@ doc.add_category("nodes", {
description = S("Item reference of blocks and other things which are capable of occupying space"), description = S("Item reference of blocks and other things which are capable of occupying space"),
build_formspec = function(data, playername) build_formspec = function(data, playername)
if data then if data then
local formstring = "" local formstring = entry_image(data)
local datastring = "" local datastring = factoids_header(data, "nodes")
formstring = entry_image(data)
datastring = factoids_header(data, "nodes")
local liquid = data.def.liquidtype ~= "none" and minetest.get_item_group(data.itemstring, "fake_liquid") == 0 local liquid = data.def.liquidtype ~= "none" and minetest.get_item_group(data.itemstring, "fake_liquid") == 0
if not forbidden_core_factoids.basics then if not forbidden_core_factoids.basics then
@ -834,7 +831,7 @@ doc.add_category("nodes", {
elseif type(data.def.drop) == "table" and data.def.drop.items ~= nil then elseif type(data.def.drop) == "table" and data.def.drop.items ~= nil then
local max = data.def.drop.max_items local max = data.def.drop.max_items
local dropstring = "" local dropstring = ""
local dropstring_base = "" local dropstring_base
if max == nil then if max == nil then
dropstring_base = N("This block will drop the following items when mined: @1.") dropstring_base = N("This block will drop the following items when mined: @1.")
elseif max == 1 then elseif max == 1 then
@ -852,7 +849,7 @@ doc.add_category("nodes", {
local rarity_history = {} local rarity_history = {}
for i=1,#data.def.drop.items do for i=1,#data.def.drop.items do
local local_rarity = data.def.drop.items[i].rarity local local_rarity = data.def.drop.items[i].rarity
local chance = 1 local chance
local rarity = 1 local rarity = 1
if local_rarity == nil then if local_rarity == nil then
local_rarity = 1 local_rarity = 1
@ -937,7 +934,6 @@ doc.add_category("nodes", {
end end
local rarity = probtable.rarity local rarity = probtable.rarity
local raritystring = ""
-- No percentage if there's only one possible guaranteed drop -- No percentage if there's only one possible guaranteed drop
if not(rarity == 1 and #data.def.drop.items == 1) then if not(rarity == 1 and #data.def.drop.items == 1) then
local chance = (1/rarity)*100 local chance = (1/rarity)*100
@ -1086,11 +1082,8 @@ doc.add_category("tools", {
end, end,
build_formspec = function(data, playername) build_formspec = function(data, playername)
if data then if data then
local formstring = "" local formstring = entry_image(data)
local datastring = "" local datastring = factoids_header(data, "tools")
formstring = entry_image(data)
datastring = factoids_header(data, "tools")
-- Overwritten durability info -- Overwritten durability info
if type(data.def._doc_items_durability) == "number" then if type(data.def._doc_items_durability) == "number" then
@ -1120,11 +1113,8 @@ doc.add_category("craftitems", {
description = S("Item reference of items which are neither blocks, tools or weapons (esp. crafting items)"), description = S("Item reference of items which are neither blocks, tools or weapons (esp. crafting items)"),
build_formspec = function(data, playername) build_formspec = function(data, playername)
if data then if data then
local formstring = "" local formstring = entry_image(data)
local datastring = "" local datastring = factoids_header(data, "craftitems")
formstring = entry_image(data)
datastring = factoids_header(data, "craftitems")
datastring = datastring .. factoids_footer(data, playername, "craftitems") datastring = datastring .. factoids_footer(data, playername, "craftitems")
formstring = formstring .. doc.widgets.text(datastring, nil, nil, doc.FORMSPEC.ENTRY_WIDTH - 1.2) formstring = formstring .. doc.widgets.text(datastring, nil, nil, doc.FORMSPEC.ENTRY_WIDTH - 1.2)

View File

@ -417,9 +417,9 @@ local function get_tooltip(item, groups, cooktime, burntime)
-- and just print the normal item name without special formatting -- and just print the normal item name without special formatting
if groups[1] == "compass" or groups[1] == "clock" then if groups[1] == "compass" or groups[1] == "clock" then
groupstr = reg_items[item].description groupstr = reg_items[item].description
elseif group_names[groups[1]] then elseif g then
-- Use the special group name string -- Use the special group name string
groupstr = minetest.colorize(gcol, group_names[groups[1]]) groupstr = minetest.colorize(gcol, g)
else else
--[[ Fallback: Generic group explanation: This always --[[ Fallback: Generic group explanation: This always
works, but the internally used group name (which works, but the internally used group name (which
@ -545,7 +545,7 @@ local function get_recipe_fs(data, iY)
if custom_recipe or shapeless or recipe.type == "cooking" then if custom_recipe or shapeless or recipe.type == "cooking" then
local icon = custom_recipe and custom_recipe.icon or local icon = custom_recipe and custom_recipe.icon or
shapeless and "shapeless" or "furnace" shapeless and "shapeless" or "furnace"
if recipe.type == "cooking" then if recipe.type == "cooking" then
icon = "default_furnace_front_active.png" icon = "default_furnace_front_active.png"
@ -638,7 +638,7 @@ local function make_formspec(name)
fs[#fs + 1] = "background9[1,1;1,1;mcl_base_textures_background9.png;true;7]" fs[#fs + 1] = "background9[1,1;1,1;mcl_base_textures_background9.png;true;7]"
fs[#fs + 1] = fmt([[ tooltip[size_inc;%s] fs[#fs + 1] = fmt([[ tooltip[size_inc;%s]
tooltip[size_dec;%s] ]], tooltip[size_dec;%s] ]],
ESC(S("Increase window size")), ESC(S("Increase window size")),
ESC(S("Decrease window size"))) ESC(S("Decrease window size")))
@ -656,9 +656,9 @@ local function make_formspec(name)
]] ]]
fs[#fs + 1] = fmt([[ tooltip[search;%s] fs[#fs + 1] = fmt([[ tooltip[search;%s]
tooltip[clear;%s] tooltip[clear;%s]
tooltip[prev;%s] tooltip[prev;%s]
tooltip[next;%s] ]], tooltip[next;%s] ]],
ESC(S("Search")), ESC(S("Search")),
ESC(S("Reset")), ESC(S("Reset")),
ESC(S("Previous page")), ESC(S("Previous page")),

View File

@ -154,7 +154,7 @@ doc.sub.items.register_factoid(nil, "use", function(itemstring, def)
return s return s
end) end)
doc.sub.items.register_factoid(nil, "groups", function(itemstring, def) doc.sub.items.register_factoid(nil, "groups", function(itemstring, def)
local def = minetest.registered_items[itemstring] --local def = minetest.registered_items[itemstring]
local s = "" local s = ""
local use = minetest.get_item_group(itemstring, "mcl_armor_uses") local use = minetest.get_item_group(itemstring, "mcl_armor_uses")
local pts = minetest.get_item_group(itemstring, "mcl_armor_points") local pts = minetest.get_item_group(itemstring, "mcl_armor_points")
@ -289,7 +289,7 @@ doc.sub.items.register_factoid("nodes", "drops", function(itemstring, def)
local itemname = item:get_name() local itemname = item:get_name()
local itemcount = item:get_count() local itemcount = item:get_count()
local idef = minetest.registered_items[itemname] local idef = minetest.registered_items[itemname]
local text = "" local text
if idef.description and idef.description ~= "" then if idef.description and idef.description ~= "" then
text = idef.description text = idef.description
else else

View File

@ -1,6 +1,6 @@
local S = minetest.get_translator("mcl_tt") local S = minetest.get_translator("mcl_tt")
local function get_min_digtime(caps) --[[local function get_min_digtime(caps)
local mintime local mintime
local unique = true local unique = true
local maxlevel = caps.maxlevel local maxlevel = caps.maxlevel
@ -25,7 +25,7 @@ local function get_min_digtime(caps)
end end
end end
return mintime, unique return mintime, unique
end end]]
local function newline(str) local function newline(str)
if str ~= "" then if str ~= "" then
@ -47,7 +47,7 @@ tt.register_snippet(function(itemstring, toolcaps)
local minestring = "" local minestring = ""
local capstr = "" local capstr = ""
local caplines = 0 local caplines = 0
for k,v in pairs(groupcaps) do for _,v in pairs(groupcaps) do
local speedstr = "" local speedstr = ""
local miningusesstr = "" local miningusesstr = ""
-- Mining capabilities -- Mining capabilities
@ -153,9 +153,9 @@ tt.register_snippet(function(itemstring, toolcaps)
end) end)
-- Weapon stats -- Weapon stats
tt.register_snippet(function(itemstring) --[[tt.register_snippet(function(itemstring)
local def = minetest.registered_items[itemstring] local def = minetest.registered_items[itemstring]
end) end)]]
-- Food -- Food
tt.register_snippet(function(itemstring) tt.register_snippet(function(itemstring)

View File

@ -2,7 +2,7 @@ local S = minetest.get_translator("mcl_tt")
-- Armor -- Armor
tt.register_snippet(function(itemstring) tt.register_snippet(function(itemstring)
local def = minetest.registered_items[itemstring] --local def = minetest.registered_items[itemstring]
local s = "" local s = ""
local head = minetest.get_item_group(itemstring, "armor_head") local head = minetest.get_item_group(itemstring, "armor_head")
local torso = minetest.get_item_group(itemstring, "armor_torso") local torso = minetest.get_item_group(itemstring, "armor_torso")
@ -26,7 +26,7 @@ tt.register_snippet(function(itemstring)
return s return s
end) end)
tt.register_snippet(function(itemstring, _, itemstack) tt.register_snippet(function(itemstring, _, itemstack)
local def = minetest.registered_items[itemstring] --local def = minetest.registered_items[itemstring]
local s = "" local s = ""
local use = minetest.get_item_group(itemstring, "mcl_armor_uses") local use = minetest.get_item_group(itemstring, "mcl_armor_uses")
local pts = minetest.get_item_group(itemstring, "mcl_armor_points") local pts = minetest.get_item_group(itemstring, "mcl_armor_points")
@ -75,7 +75,7 @@ tt.register_snippet(function(itemstring)
end) end)
tt.register_snippet(function(itemstring) tt.register_snippet(function(itemstring)
local def = minetest.registered_items[itemstring] --local def = minetest.registered_items[itemstring]
if minetest.get_item_group(itemstring, "crush_after_fall") == 1 then if minetest.get_item_group(itemstring, "crush_after_fall") == 1 then
return S("Deals damage when falling"), mcl_colors.YELLOW return S("Deals damage when falling"), mcl_colors.YELLOW
end end

View File

@ -250,9 +250,7 @@ minetest.register_on_dignode(function(pos, oldnode, digger)
local tnodedug = string.split(entry.node, ":") local tnodedug = string.split(entry.node, ":")
local tmod = tnodedug[1] local tmod = tnodedug[1]
local titem = tnodedug[2] local titem = tnodedug[2]
if not tmod or not titem or not data.count[tmod] or not data.count[tmod][titem] then if tmod and titem and data.count[tmod] and data.count[tmod][titem] and data.count[tmod][titem] > entry.target-1 then
-- table running failed!
elseif data.count[tmod][titem] > entry.target-1 then
return entry.award return entry.award
end end
elseif awards.get_total_item_count(data, "count") > entry.target-1 then elseif awards.get_total_item_count(data, "count") > entry.target-1 then
@ -277,9 +275,7 @@ minetest.register_on_placenode(function(pos, node, digger)
local tnodedug = string.split(entry.node, ":") local tnodedug = string.split(entry.node, ":")
local tmod = tnodedug[1] local tmod = tnodedug[1]
local titem = tnodedug[2] local titem = tnodedug[2]
if not tmod or not titem or not data.place[tmod] or not data.place[tmod][titem] then if tmod and titem and data.place[tmod] and data.place[tmod][titem] and data.place[tmod][titem] > entry.target-1 then
-- table running failed!
elseif data.place[tmod][titem] > entry.target-1 then
return entry.award return entry.award
end end
elseif awards.get_total_item_count(data, "place") > entry.target-1 then elseif awards.get_total_item_count(data, "place") > entry.target-1 then
@ -303,9 +299,7 @@ minetest.register_on_item_eat(function(hp_change, replace_with_item, itemstack,
local titemstring = string.split(entry.item, ":") local titemstring = string.split(entry.item, ":")
local tmod = titemstring[1] local tmod = titemstring[1]
local titem = titemstring[2] local titem = titemstring[2]
if not tmod or not titem or not data.eat[tmod] or not data.eat[tmod][titem] then if tmod and titem and data.eat[tmod] and data.eat[tmod][titem] and data.eat[tmod][titem] > entry.target-1 then
-- table running failed!
elseif data.eat[tmod][titem] > entry.target-1 then
return entry.award return entry.award
end end
elseif awards.get_total_item_count(data, "eat") > entry.target-1 then elseif awards.get_total_item_count(data, "eat") > entry.target-1 then
@ -331,9 +325,7 @@ minetest.register_on_craft(function(itemstack, player, old_craft_grid, craft_inv
local titemcrafted = string.split(entry.item, ":") local titemcrafted = string.split(entry.item, ":")
local tmod = titemcrafted[1] local tmod = titemcrafted[1]
local titem = titemcrafted[2] local titem = titemcrafted[2]
if not tmod or not titem or not data.craft[tmod] or not data.craft[tmod][titem] then if tmod and titem and data.craft[tmod] and data.craft[tmod][titem] and data.craft[tmod][titem] > entry.target-1 then
-- table running failed!
elseif data.craft[tmod][titem] > entry.target-1 then
return entry.award return entry.award
end end
elseif awards.get_total_item_count(data, "craft") > entry.target-1 then elseif awards.get_total_item_count(data, "craft") > entry.target-1 then

View File

@ -1,6 +1,5 @@
if minetest.get_modpath("unified_inventory") ~= nil then if minetest.get_modpath("unified_inventory") then
local S = minetest.get_translator("awards") local S = minetest.get_translator(minetest.get_current_modname())
unified_inventory.register_button("awards", { unified_inventory.register_button("awards", {
type = "image", type = "image",
image = "awards_ui_icon.png", image = "awards_ui_icon.png",

View File

@ -1,17 +1,22 @@
local S = minetest.get_translator("hudbars") local modname = minetest.get_current_modname()
local modpath = minetest.get_modpath(modname)
local S = minetest.get_translator(modname)
local N = function(s) return s end local N = function(s) return s end
hb = {} local math = math
local table = table
hb.hudtables = {} hb = {
hudtables = {},
-- number of registered HUD bars -- number of registered HUD bars
hb.hudbars_count = 0 hudbars_count = 0,
-- table which records which HUD bar slots have been “registered” so far; used for automatic positioning
-- table which records which HUD bar slots have been “registered” so far; used for automatic positioning registered_slots = {},
hb.registered_slots = {} settings = {},
-- Table which contains all players with active default HUD bars (only for internal use)
hb.settings = {} players = {},
}
function hb.load_setting(sname, stype, defaultval, valid_values) function hb.load_setting(sname, stype, defaultval, valid_values)
local sval local sval
@ -45,7 +50,8 @@ function hb.load_setting(sname, stype, defaultval, valid_values)
end end
-- Load default settings -- Load default settings
dofile(minetest.get_modpath("hudbars").."/default_settings.lua") dofile(modpath.."/default_settings.lua")
if minetest.get_modpath("mcl_experience") and not minetest.is_creative_enabled("") then if minetest.get_modpath("mcl_experience") and not minetest.is_creative_enabled("") then
-- reserve some space for experience bar: -- reserve some space for experience bar:
hb.settings.start_offset_left.y = hb.settings.start_offset_left.y - 20 hb.settings.start_offset_left.y = hb.settings.start_offset_left.y - 20
@ -85,9 +91,6 @@ local function make_label(format_string, format_string_config, label, start_valu
return ret return ret
end end
-- Table which contains all players with active default HUD bars (only for internal use)
hb.players = {}
function hb.value_to_barlength(value, max) function hb.value_to_barlength(value, max)
if max == 0 then if max == 0 then
return 0 return 0

View File

@ -237,12 +237,10 @@ mcl_damage.register_on_damage(function(obj, damage, reason)
end) end)
minetest.register_globalstep(function(dtime) minetest.register_globalstep(function(dtime)
local new_assist = {}
for obj, tbl in pairs(mcl_death_messages.assist) do for obj, tbl in pairs(mcl_death_messages.assist) do
tbl.timeout = tbl.timeout - dtime tbl.timeout = tbl.timeout - dtime
if (obj:is_player() or obj:get_luaentity()) and tbl.timeout > 0 then if not obj:is_player() and not obj:get_luaentity() or tbl.timeout > 0 then
new_assist[obj] = tbl mcl_death_messages.assist[obj] = nil
end end
end end
end) end)

View File

@ -1,5 +1,11 @@
local S = minetest.get_translator("mcl_experience") local S = minetest.get_translator("mcl_experience")
mcl_experience = {} mcl_experience = {}
local vector = vector
local math = math
local string = string
local pool = {} local pool = {}
local registered_nodes local registered_nodes
local max_xp = 2^31-1 local max_xp = 2^31-1
@ -114,9 +120,9 @@ end
hud_manager.hud_exists = function(player,hud_name) hud_manager.hud_exists = function(player,hud_name)
local name = player:get_player_name() local name = player:get_player_name()
if player_huds[name] and player_huds[name][hud_name] then if player_huds[name] and player_huds[name][hud_name] then
return(true) return true
else else
return(false) return false
end end
end end
------------------- -------------------
@ -144,7 +150,7 @@ end)
function mcl_experience.get_player_xp_level(player) function mcl_experience.get_player_xp_level(player)
local name = player:get_player_name() local name = player:get_player_name()
return(pool[name].level) return pool[name].level
end end
function mcl_experience.set_player_xp_level(player,level) function mcl_experience.set_player_xp_level(player,level)
@ -262,7 +268,6 @@ function mcl_experience.add_experience(player, experience)
if #final_candidates > 0 then if #final_candidates > 0 then
local can = final_candidates[math.random(#final_candidates)] local can = final_candidates[math.random(#final_candidates)]
local stack, list, index, wear = can.stack, can.list, can.index, can.wear local stack, list, index, wear = can.stack, can.list, can.index, can.wear
local unbreaking_level = mcl_enchanting.get_enchantment(stack, "unbreaking")
local uses = mcl_util.calculate_durability(stack) local uses = mcl_util.calculate_durability(stack)
local multiplier = 2 * 65535 / uses local multiplier = 2 * 65535 / uses
local repair = experience * multiplier local repair = experience * multiplier
@ -329,14 +334,12 @@ minetest.register_on_dieplayer(function(player)
mcl_experience.throw_experience(player:get_pos(), xp_amount) mcl_experience.throw_experience(player:get_pos(), xp_amount)
end) end)
local name
local collector, pos, pos2 local collector, pos, pos2
local direction, distance, player_velocity, goal local direction, distance, player_velocity, goal
local currentvel, acceleration, multiplier, velocity local currentvel, acceleration, multiplier, velocity
local node, vel, def local node, vel, def
local is_moving, is_slippery, slippery, slip_factor local is_moving, is_slippery, slippery, slip_factor
local size, data local size
local function xp_step(self, dtime) local function xp_step(self, dtime)
--if item set to be collected then only execute go to player --if item set to be collected then only execute go to player
if self.collected == true then if self.collected == true then

View File

@ -1,31 +1,34 @@
local S = minetest.get_translator("mcl_hbarmor") local S = minetest.get_translator(minetest.get_current_modname())
local mcl_hbarmor = {} local math = math
local tonumber = tonumber
-- HUD statbar values local get_connected_players = minetest.get_connected_players
mcl_hbarmor.armor = {}
-- Stores if player's HUD bar has been initialized so far. local mcl_hbarmor = {
mcl_hbarmor.player_active = {} -- HUD statbar values
armor = {},
-- Stores if player's HUD bar has been initialized so far.
player_active = {},
-- Time difference in seconds between updates to the HUD armor bar.
-- Increase this number for slow servers.
tick = 0.1,
-- If true, the armor bar is hidden when the player does not wear any armor
autohide = true,
}
-- Time difference in seconds between updates to the HUD armor bar. local tick_config = minetest.settings:get("mcl_hbarmor_tick")
-- Increase this number for slow servers.
mcl_hbarmor.tick = 0.1
-- If true, the armor bar is hidden when the player does not wear any armor if tonumber(tick_config) ~= nil then
mcl_hbarmor.autohide = true mcl_hbarmor.tick = tonumber(tick_config)
set = minetest.settings:get("mcl_hbarmor_tick")
if tonumber(set) ~= nil then
mcl_hbarmor.tick = tonumber(set)
end end
local must_hide = function(playername, arm) local function must_hide(playername, arm)
return arm == 0 return arm == 0
end end
local arm_printable = function(arm) local function arm_printable(arm)
return math.ceil(math.floor(arm+0.5)) return math.ceil(math.floor(arm+0.5))
end end
@ -106,12 +109,13 @@ end)
local main_timer = 0 local main_timer = 0
local timer = 0 local timer = 0
minetest.register_globalstep(function(dtime) minetest.register_globalstep(function(dtime)
--TODO: replace this by playerglobalstep API then implemented
main_timer = main_timer + dtime main_timer = main_timer + dtime
timer = timer + dtime timer = timer + dtime
if main_timer > mcl_hbarmor.tick or timer > 4 then if main_timer > mcl_hbarmor.tick or timer > 4 then
if minetest.settings:get_bool("enable_damage") then if minetest.settings:get_bool("enable_damage") then
if main_timer > mcl_hbarmor.tick then main_timer = 0 end if main_timer > mcl_hbarmor.tick then main_timer = 0 end
for _,player in pairs(minetest.get_connected_players()) do for _,player in pairs(get_connected_players()) do
local name = player:get_player_name() local name = player:get_player_name()
if mcl_hbarmor.player_active[name] == true then if mcl_hbarmor.player_active[name] == true then
local ret = mcl_hbarmor.get_armor(player) local ret = mcl_hbarmor.get_armor(player)

View File

@ -7,7 +7,7 @@ local players = {}
-- Containing all the items for each Creative Mode tab -- Containing all the items for each Creative Mode tab
local inventory_lists = {} local inventory_lists = {}
local mod_player = minetest.get_modpath("mcl_player") ~= nil --local mod_player = minetest.get_modpath("mcl_player") ~= nil
-- Create tables -- Create tables
local builtin_filter_ids = {"blocks","deco","redstone","rail","food","tools","combat","mobs","brew","matr","misc","all"} local builtin_filter_ids = {"blocks","deco","redstone","rail","food","tools","combat","mobs","brew","matr","misc","all"}
@ -161,7 +161,7 @@ end
local function init(player) local function init(player)
local playername = player:get_player_name() local playername = player:get_player_name()
local inv = minetest.create_detached_inventory("creative_"..playername, { minetest.create_detached_inventory("creative_"..playername, {
allow_move = function(inv, from_list, from_index, to_list, to_index, count, player) allow_move = function(inv, from_list, from_index, to_list, to_index, count, player)
if minetest.is_creative_enabled(playername) then if minetest.is_creative_enabled(playername) then
return count return count
@ -203,7 +203,7 @@ local offset = {} -- string offset:
local boffset = {} -- local boffset = {} --
local hoch = {} local hoch = {}
local filtername = {} local filtername = {}
local bg = {} --local bg = {}
local noffset_x_start = -0.24 local noffset_x_start = -0.24
local noffset_x = noffset_x_start local noffset_x = noffset_x_start
@ -257,7 +257,6 @@ hoch["mobs"] = "_down"
hoch["matr"] = "_down" hoch["matr"] = "_down"
hoch["inv"] = "_down" hoch["inv"] = "_down"
filtername = {}
filtername["blocks"] = S("Building Blocks") filtername["blocks"] = S("Building Blocks")
filtername["deco"] = S("Decoration Blocks") filtername["deco"] = S("Decoration Blocks")
filtername["redstone"] = S("Redstone") filtername["redstone"] = S("Redstone")
@ -272,9 +271,9 @@ filtername["brew"] = S("Brewing")
filtername["matr"] = S("Materials") filtername["matr"] = S("Materials")
filtername["inv"] = S("Survival Inventory") filtername["inv"] = S("Survival Inventory")
local dark_bg = "crafting_creative_bg_dark.png" --local dark_bg = "crafting_creative_bg_dark.png"
local function reset_menu_item_bg() --[[local function reset_menu_item_bg()
bg["blocks"] = dark_bg bg["blocks"] = dark_bg
bg["deco"] = dark_bg bg["deco"] = dark_bg
bg["redstone"] = dark_bg bg["redstone"] = dark_bg
@ -289,11 +288,11 @@ local function reset_menu_item_bg()
bg["matr"] = dark_bg bg["matr"] = dark_bg
bg["inv"] = dark_bg bg["inv"] = dark_bg
bg["default"] = dark_bg bg["default"] = dark_bg
end end]]
mcl_inventory.set_creative_formspec = function(player, start_i, pagenum, inv_size, show, page, filter) mcl_inventory.set_creative_formspec = function(player, start_i, pagenum, inv_size, show, page, filter)
reset_menu_item_bg() --reset_menu_item_bg()
pagenum = math.floor(pagenum) or 1 pagenum = math.floor(pagenum) or 1
local playername = player:get_player_name() local playername = player:get_player_name()
@ -310,7 +309,6 @@ mcl_inventory.set_creative_formspec = function(player, start_i, pagenum, inv_siz
end end
local pagemax = math.max(1, math.floor((inv_size-1) / (9*5) + 1)) local pagemax = math.max(1, math.floor((inv_size-1) / (9*5) + 1))
local name = "nix" local name = "nix"
local formspec = ""
local main_list local main_list
local listrings = "listring[detached:creative_"..playername..";main]".. local listrings = "listring[detached:creative_"..playername..";main]"..
"listring[current_player;main]".. "listring[current_player;main]"..
@ -322,7 +320,7 @@ mcl_inventory.set_creative_formspec = function(player, start_i, pagenum, inv_siz
players[playername].page = page players[playername].page = page
end end
end end
bg[name] = "crafting_creative_bg.png" --bg[name] = "crafting_creative_bg.png"
local inv_bg = "crafting_inventory_creative.png" local inv_bg = "crafting_inventory_creative.png"
if name == "inv" then if name == "inv" then
@ -428,7 +426,7 @@ mcl_inventory.set_creative_formspec = function(player, start_i, pagenum, inv_siz
caption = "label[0,1.2;"..F(minetest.colorize("#313131", filtername[name])).."]" caption = "label[0,1.2;"..F(minetest.colorize("#313131", filtername[name])).."]"
end end
formspec = "size[10,9.3]".. local formspec = "size[10,9.3]"..
"no_prepend[]".. "no_prepend[]"..
mcl_vars.gui_nonbg..mcl_vars.gui_bg_color.. mcl_vars.gui_nonbg..mcl_vars.gui_bg_color..
"background[-0.19,-0.25;10.5,9.87;"..inv_bg.."]".. "background[-0.19,-0.25;10.5,9.87;"..inv_bg.."]"..
@ -560,7 +558,7 @@ minetest.register_on_player_receive_fields(function(player, formname, fields)
end end
-- Figure out current scroll bar from formspec -- Figure out current scroll bar from formspec
local formspec = player:get_inventory_formspec() --local formspec = player:get_inventory_formspec()
local start_i = players[name].start_i local start_i = players[name].start_i
@ -628,7 +626,7 @@ if minetest.is_creative_enabled("") then
end end
mcl_inventory.update_inventory_formspec = function(player) mcl_inventory.update_inventory_formspec = function(player)
local page = nil local page
local name = player:get_player_name() local name = player:get_player_name()
@ -639,7 +637,7 @@ if minetest.is_creative_enabled("") then
end end
-- Figure out current scroll bar from formspec -- Figure out current scroll bar from formspec
local formspec = player:get_inventory_formspec() --local formspec = player:get_inventory_formspec()
local start_i = players[name].start_i local start_i = players[name].start_i
local inv_size local inv_size

View File

@ -3,8 +3,8 @@ local F = minetest.formspec_escape
mcl_inventory = {} mcl_inventory = {}
local mod_player = minetest.get_modpath("mcl_player") ~= nil --local mod_player = minetest.get_modpath("mcl_player") ~= nil
local mod_craftguide = minetest.get_modpath("mcl_craftguide") ~= nil --local mod_craftguide = minetest.get_modpath("mcl_craftguide") ~= nil
-- Returns a single itemstack in the given inventory to the main inventory, or drop it when there's no space left -- Returns a single itemstack in the given inventory to the main inventory, or drop it when there's no space left
function return_item(itemstack, dropper, pos, inv) function return_item(itemstack, dropper, pos, inv)
@ -60,8 +60,6 @@ local function set_inventory(player, armor_change_only)
inv:set_width("craft", 2) inv:set_width("craft", 2)
inv:set_size("craft", 4) inv:set_size("craft", 4)
local player_name = player:get_player_name()
-- Show armor and player image -- Show armor and player image
local player_preview local player_preview
if minetest.settings:get_bool("3d_player_preview", true) then if minetest.settings:get_bool("3d_player_preview", true) then
@ -180,6 +178,6 @@ minetest.register_on_joinplayer(function(player)
end) end)
if minetest.is_creative_enabled("") then if minetest.is_creative_enabled("") then
dofile(minetest.get_modpath("mcl_inventory").."/creative.lua") dofile(minetest.get_modpath(minetest.get_current_modname()).."/creative.lua")
end end

View File

@ -1,6 +1,6 @@
name = mcl_inventory name = mcl_inventory
author = BlockMen author = BlockMen
description = Adds the player inventory and creative inventory. description = Adds the player inventory and creative inventory.
depends = mcl_init, mcl_formspec depends = mcl_init, mcl_formspec, mcl_player
optional_depends = mcl_player, _mcl_autogroup, mcl_armor, mcl_brewing, mcl_potions, mcl_enchanting optional_depends = _mcl_autogroup, mcl_armor, mcl_brewing, mcl_potions, mcl_enchanting, mcl_craftguide

View File

@ -11,7 +11,7 @@ local xp_mod = minetest.get_modpath("mcl_experience")
local function set_hud(player) local function set_hud(player)
if not player:is_player() then return end if not player:is_player() then return end
local player_name = player:get_player_name() local player_name = player:get_player_name()
-- Fixed offset in config file -- Fixed offset in config file
local fixed = tonumber(minetest.settings:get("show_wielded_item_y_offset")) local fixed = tonumber(minetest.settings:get("show_wielded_item_y_offset"))
local off local off
@ -84,7 +84,7 @@ minetest.register_globalstep(function(dtime)
wield[player_name] = wname wield[player_name] = wname
dtimes[player_name] = 0 dtimes[player_name] = 0
if huds[player_name] then if huds[player_name] then
local def = minetest.registered_items[wname] local def = minetest.registered_items[wname]
local meta = wstack:get_meta() local meta = wstack:get_meta()

View File

@ -217,94 +217,94 @@ if minetest.get_modpath("screwdriver") then
end end
for _, mode in pairs{"comp", "sub"} do for _, mode in pairs{"comp", "sub"} do
for _, state in pairs{mesecon.state.on, mesecon.state.off} do for _, state in pairs{mesecon.state.on, mesecon.state.off} do
local state_str = state_strs[state] local state_str = state_strs[state]
local nodename = local nodename =
"mcl_comparators:comparator_"..state_strs[state].."_"..mode "mcl_comparators:comparator_"..state_str.."_"..mode
-- Help -- Help
local longdesc, usagehelp, use_help local longdesc, usagehelp, use_help
if state_strs[state] == "off" and mode == "comp" then if state_str == "off" and mode == "comp" then
longdesc = S("Redstone comparators are multi-purpose redstone components.").."\n".. longdesc = S("Redstone comparators are multi-purpose redstone components.").."\n"..
S("They can transmit a redstone signal, detect whether a block contains any items and compare multiple signals.") S("They can transmit a redstone signal, detect whether a block contains any items and compare multiple signals.")
usagehelp = S("A redstone comparator has 1 main input, 2 side inputs and 1 output. The output is in arrow direction, the main input is in the opposite direction. The other 2 sides are the side inputs.").."\n".. usagehelp = S("A redstone comparator has 1 main input, 2 side inputs and 1 output. The output is in arrow direction, the main input is in the opposite direction. The other 2 sides are the side inputs.").."\n"..
S("The main input can powered in 2 ways: First, it can be powered directly by redstone power like any other component. Second, it is powered if, and only if a container (like a chest) is placed in front of it and the container contains at least one item.").."\n".. S("The main input can powered in 2 ways: First, it can be powered directly by redstone power like any other component. Second, it is powered if, and only if a container (like a chest) is placed in front of it and the container contains at least one item.").."\n"..
S("The side inputs are only powered by normal redstone power. The redstone comparator can operate in two modes: Transmission mode and subtraction mode. It starts in transmission mode and the mode can be changed by using the block.").."\n\n".. S("The side inputs are only powered by normal redstone power. The redstone comparator can operate in two modes: Transmission mode and subtraction mode. It starts in transmission mode and the mode can be changed by using the block.").."\n\n"..
S("Transmission mode:\nThe front torch is unlit and lowered. The output is powered if, and only if the main input is powered. The two side inputs are ignored.").."\n".. S("Transmission mode:\nThe front torch is unlit and lowered. The output is powered if, and only if the main input is powered. The two side inputs are ignored.").."\n"..
S("Subtraction mode:\nThe front torch is lit. The output is powered if, and only if the main input is powered and none of the side inputs is powered.") S("Subtraction mode:\nThe front torch is lit. The output is powered if, and only if the main input is powered and none of the side inputs is powered.")
else else
use_help = false use_help = false
end end
local nodedef = { local nodedef = {
description = S("Redstone Comparator"), description = S("Redstone Comparator"),
inventory_image = icon, inventory_image = icon,
wield_image = icon, wield_image = icon,
_doc_items_create_entry = use_help, _doc_items_create_entry = use_help,
_doc_items_longdesc = longdesc, _doc_items_longdesc = longdesc,
_doc_items_usagehelp = usagehelp, _doc_items_usagehelp = usagehelp,
drawtype = "nodebox", drawtype = "nodebox",
tiles = get_tiles(state_strs[state], mode), tiles = get_tiles(state_str, mode),
use_texture_alpha = minetest.features.use_texture_alpha_string_modes and "opaque" or false, use_texture_alpha = minetest.features.use_texture_alpha_string_modes and "opaque" or false,
wield_image = "mcl_comparators_off.png", --wield_image = "mcl_comparators_off.png",
walkable = true, walkable = true,
selection_box = collision_box, selection_box = collision_box,
collision_box = collision_box, collision_box = collision_box,
node_box = { node_box = {
type = "fixed", type = "fixed",
fixed = node_boxes[mode], fixed = node_boxes[mode],
},
groups = groups,
paramtype = "light",
paramtype2 = "facedir",
sunlight_propagates = false,
is_ground_content = false,
drop = 'mcl_comparators:comparator_off_comp',
on_construct = update_self,
on_rightclick =
make_rightclick_handler(state_strs[state], mode),
comparator_mode = mode,
comparator_onstate = "mcl_comparators:comparator_on_"..mode,
comparator_offstate = "mcl_comparators:comparator_off_"..mode,
sounds = mcl_sounds.node_sound_stone_defaults(),
mesecons = {
receptor = {
state = state,
rules = comparator_get_output_rules,
}, },
effector = { groups = groups,
rules = comparator_get_input_rules, paramtype = "light",
action_change = update_self, paramtype2 = "facedir",
} sunlight_propagates = false,
}, is_ground_content = false,
on_rotate = on_rotate, drop = 'mcl_comparators:comparator_off_comp',
} on_construct = update_self,
on_rightclick =
make_rightclick_handler(state_str, mode),
comparator_mode = mode,
comparator_onstate = "mcl_comparators:comparator_on_"..mode,
comparator_offstate = "mcl_comparators:comparator_off_"..mode,
sounds = mcl_sounds.node_sound_stone_defaults(),
mesecons = {
receptor = {
state = state,
rules = comparator_get_output_rules,
},
effector = {
rules = comparator_get_input_rules,
action_change = update_self,
}
},
on_rotate = on_rotate,
}
if mode == "comp" and state == mesecon.state.off then if mode == "comp" and state == mesecon.state.off then
-- This is the prototype -- This is the prototype
nodedef._doc_items_create_entry = true nodedef._doc_items_create_entry = true
else else
nodedef.groups = table.copy(nodedef.groups) nodedef.groups = table.copy(nodedef.groups)
nodedef.groups.not_in_creative_inventory = 1 nodedef.groups.not_in_creative_inventory = 1
local extra_desc = {} --local extra_desc = {}
if mode == "sub" or state == mesecon.state.on then if mode == "sub" or state == mesecon.state.on then
nodedef.inventory_image = nil nodedef.inventory_image = nil
end
local desc = nodedef.description
if mode ~= "sub" and state == mesecon.state.on then
desc = S("Redstone Comparator (Powered)")
elseif mode == "sub" and state ~= mesecon.state.on then
desc = S("Redstone Comparator (Subtract)")
elseif mode == "sub" and state == mesecon.state.on then
desc = S("Redstone Comparator (Subtract, Powered)")
end
nodedef.description = desc
end end
local desc = nodedef.description
if mode ~= "sub" and state == mesecon.state.on then minetest.register_node(nodename, nodedef)
desc = S("Redstone Comparator (Powered)") mcl_wip.register_wip_item(nodename)
elseif mode == "sub" and state ~= mesecon.state.on then
desc = S("Redstone Comparator (Subtract)")
elseif mode == "sub" and state == mesecon.state.on then
desc = S("Redstone Comparator (Subtract, Powered)")
end
nodedef.description = desc
end end
minetest.register_node(nodename, nodedef)
mcl_wip.register_wip_item(nodename)
end
end end
-- Register recipies -- Register recipies
@ -351,9 +351,9 @@ minetest.register_abm({
-- Add entry aliases for the Help -- Add entry aliases for the Help
if minetest.get_modpath("doc") then if minetest.get_modpath("doc") then
doc.add_entry_alias("nodes", "mcl_comparators:comparator_off_comp", doc.add_entry_alias("nodes", "mcl_comparators:comparator_off_comp",
"nodes", "mcl_comparators:comparator_off_sub") "nodes", "mcl_comparators:comparator_off_sub")
doc.add_entry_alias("nodes", "mcl_comparators:comparator_off_comp", doc.add_entry_alias("nodes", "mcl_comparators:comparator_off_comp",
"nodes", "mcl_comparators:comparator_on_comp") "nodes", "mcl_comparators:comparator_on_comp")
doc.add_entry_alias("nodes", "mcl_comparators:comparator_off_comp", doc.add_entry_alias("nodes", "mcl_comparators:comparator_off_comp",
"nodes", "mcl_comparators:comparator_on_sub") "nodes", "mcl_comparators:comparator_on_sub")
end end

View File

@ -96,125 +96,127 @@ local dispenserdef = {
end, end,
_mcl_blast_resistance = 3.5, _mcl_blast_resistance = 3.5,
_mcl_hardness = 3.5, _mcl_hardness = 3.5,
mesecons = {effector = { mesecons = {
-- Dispense random item when triggered effector = {
action_on = function (pos, node) -- Dispense random item when triggered
local meta = minetest.get_meta(pos) action_on = function (pos, node)
local inv = meta:get_inventory() local meta = minetest.get_meta(pos)
local droppos, dropdir local inv = meta:get_inventory()
if node.name == "mcl_dispensers:dispenser" then local droppos, dropdir
dropdir = vector.multiply(minetest.facedir_to_dir(node.param2), -1) if node.name == "mcl_dispensers:dispenser" then
droppos = vector.add(pos, dropdir) dropdir = vector.multiply(minetest.facedir_to_dir(node.param2), -1)
elseif node.name == "mcl_dispensers:dispenser_up" then droppos = vector.add(pos, dropdir)
dropdir = {x=0, y=1, z=0} elseif node.name == "mcl_dispensers:dispenser_up" then
droppos = {x=pos.x, y=pos.y+1, z=pos.z} dropdir = {x=0, y=1, z=0}
elseif node.name == "mcl_dispensers:dispenser_down" then droppos = {x=pos.x, y=pos.y+1, z=pos.z}
dropdir = {x=0, y=-1, z=0} elseif node.name == "mcl_dispensers:dispenser_down" then
droppos = {x=pos.x, y=pos.y-1, z=pos.z} dropdir = {x=0, y=-1, z=0}
end droppos = {x=pos.x, y=pos.y-1, z=pos.z}
local dropnode = minetest.get_node(droppos)
local dropnodedef = minetest.registered_nodes[dropnode.name]
local stacks = {}
for i=1,inv:get_size("main") do
local stack = inv:get_stack("main", i)
if not stack:is_empty() then
table.insert(stacks, {stack = stack, stackpos = i})
end end
end local dropnode = minetest.get_node(droppos)
if #stacks >= 1 then local dropnodedef = minetest.registered_nodes[dropnode.name]
local r = math.random(1, #stacks) local stacks = {}
local stack = stacks[r].stack for i=1,inv:get_size("main") do
local dropitem = ItemStack(stack) local stack = inv:get_stack("main", i)
dropitem:set_count(1) if not stack:is_empty() then
local stack_id = stacks[r].stackpos table.insert(stacks, {stack = stack, stackpos = i})
local stackdef = stack:get_definition() end
local iname = stack:get_name() end
local igroups = minetest.registered_items[iname].groups if #stacks >= 1 then
local r = math.random(1, #stacks)
local stack = stacks[r].stack
local dropitem = ItemStack(stack)
dropitem:set_count(1)
local stack_id = stacks[r].stackpos
local stackdef = stack:get_definition()
local iname = stack:get_name()
local igroups = minetest.registered_items[iname].groups
--[===[ Dispense item ]===] --[===[ Dispense item ]===]
-- Hardcoded dispensions -- -- Hardcoded dispensions --
-- Armor, mob heads and pumpkins -- Armor, mob heads and pumpkins
if igroups.armor then if igroups.armor then
local droppos_below = {x = droppos.x, y = droppos.y - 1, z = droppos.z} local droppos_below = {x = droppos.x, y = droppos.y - 1, z = droppos.z}
for _, objs in ipairs({minetest.get_objects_inside_radius(droppos, 1), minetest.get_objects_inside_radius(droppos_below, 1)}) do for _, objs in ipairs({minetest.get_objects_inside_radius(droppos, 1), minetest.get_objects_inside_radius(droppos_below, 1)}) do
for _, obj in ipairs(objs) do for _, obj in ipairs(objs) do
stack = mcl_armor.equip(stack, obj) stack = mcl_armor.equip(stack, obj)
if stack:is_empty() then
break
end
end
if stack:is_empty() then if stack:is_empty() then
break break
end end
end end
if stack:is_empty() then
break
end
end
-- Place head or pumpkin as node, if equipping it as armor has failed -- Place head or pumpkin as node, if equipping it as armor has failed
if not stack:is_empty() then if not stack:is_empty() then
if igroups.head or iname == "mcl_farming:pumpkin_face" then if igroups.head or iname == "mcl_farming:pumpkin_face" then
if dropnodedef.buildable_to then if dropnodedef.buildable_to then
minetest.set_node(droppos, {name = iname, param2 = node.param2}) minetest.set_node(droppos, {name = iname, param2 = node.param2})
stack:take_item() stack:take_item()
end
end end
end end
end
inv:set_stack("main", stack_id, stack)
-- Spawn Egg
elseif igroups.spawn_egg then
-- Spawn mob
if not dropnodedef.walkable then
pointed_thing = { above = droppos, under = { x=droppos.x, y=droppos.y-1, z=droppos.z } }
minetest.add_entity(droppos, stack:get_name())
stack:take_item()
inv:set_stack("main", stack_id, stack) inv:set_stack("main", stack_id, stack)
end -- Spawn Egg
elseif igroups.spawn_egg then
-- Spawn mob
if not dropnodedef.walkable then
--pointed_thing = { above = droppos, under = { x=droppos.x, y=droppos.y-1, z=droppos.z } }
minetest.add_entity(droppos, stack:get_name())
-- Generalized dispension
elseif (not dropnodedef.walkable or stackdef._dispense_into_walkable) then
--[[ _on_dispense(stack, pos, droppos, dropnode, dropdir)
* stack: Itemstack which is dispense
* pos: Position of dispenser
* droppos: Position to which to dispense item
* dropnode: Node of droppos
* dropdir: Drop direction
_dispense_into_walkable: If true, can dispense into walkable nodes
]]
if stackdef._on_dispense then
-- Item-specific dispension (if defined)
local od_ret = stackdef._on_dispense(dropitem, pos, droppos, dropnode, dropdir)
if od_ret then
local newcount = stack:get_count() - 1
stack:set_count(newcount)
inv:set_stack("main", stack_id, stack)
if newcount == 0 then
inv:set_stack("main", stack_id, od_ret)
elseif inv:room_for_item("main", od_ret) then
inv:add_item("main", od_ret)
else
minetest.add_item(droppos, dropitem)
end
else
stack:take_item() stack:take_item()
inv:set_stack("main", stack_id, stack) inv:set_stack("main", stack_id, stack)
end end
else
-- Drop item otherwise -- Generalized dispension
minetest.add_item(droppos, dropitem) elseif (not dropnodedef.walkable or stackdef._dispense_into_walkable) then
stack:take_item() --[[ _on_dispense(stack, pos, droppos, dropnode, dropdir)
inv:set_stack("main", stack_id, stack) * stack: Itemstack which is dispense
* pos: Position of dispenser
* droppos: Position to which to dispense item
* dropnode: Node of droppos
* dropdir: Drop direction
_dispense_into_walkable: If true, can dispense into walkable nodes
]]
if stackdef._on_dispense then
-- Item-specific dispension (if defined)
local od_ret = stackdef._on_dispense(dropitem, pos, droppos, dropnode, dropdir)
if od_ret then
local newcount = stack:get_count() - 1
stack:set_count(newcount)
inv:set_stack("main", stack_id, stack)
if newcount == 0 then
inv:set_stack("main", stack_id, od_ret)
elseif inv:room_for_item("main", od_ret) then
inv:add_item("main", od_ret)
else
minetest.add_item(droppos, dropitem)
end
else
stack:take_item()
inv:set_stack("main", stack_id, stack)
end
else
-- Drop item otherwise
minetest.add_item(droppos, dropitem)
stack:take_item()
inv:set_stack("main", stack_id, stack)
end
end end
end end
end,
rules = mesecon.rules.alldirs,
end },
end, },
rules = mesecon.rules.alldirs,
}},
on_rotate = on_rotate, on_rotate = on_rotate,
} }

View File

@ -11,7 +11,7 @@ local realtime = true
local rules_flat = { local rules_flat = {
{ x = 0, y = 0, z = -1, spread = true }, { x = 0, y = 0, z = -1, spread = true },
} }
local get_rules_flat = function(node) local function get_rules_flat(node)
local rules = rules_flat local rules = rules_flat
for i=1, node.param2 do for i=1, node.param2 do
rules = mesecon.rotate_rules_left(rules) rules = mesecon.rotate_rules_left(rules)
@ -46,7 +46,7 @@ end
-- and update the observer state if needed. -- and update the observer state if needed.
-- TODO: Also scan metadata changes. -- TODO: Also scan metadata changes.
-- TODO: Ignore some node changes. -- TODO: Ignore some node changes.
local observer_scan = function(pos, initialize) local function observer_scan(pos, initialize)
local node = minetest.get_node(pos) local node = minetest.get_node(pos)
local front local front
if node.name == "mcl_observers:observer_up_off" or node.name == "mcl_observers:observer_up_on" then if node.name == "mcl_observers:observer_up_off" or node.name == "mcl_observers:observer_up_on" then
@ -87,14 +87,14 @@ local observer_scan = function(pos, initialize)
end end
-- Vertical orientation (CURRENTLY DISABLED) -- Vertical orientation (CURRENTLY DISABLED)
local observer_orientate = function(pos, placer) local function observer_orientate(pos, placer)
-- Not placed by player -- Not placed by player
if not placer then return end if not placer then return end
-- Placer pitch in degrees -- Placer pitch in degrees
local pitch = placer:get_look_vertical() * (180 / math.pi) local pitch = placer:get_look_vertical() * (180 / math.pi)
local node = minetest.get_node(pos) --local node = minetest.get_node(pos)
if pitch > 55 then -- player looking upwards if pitch > 55 then -- player looking upwards
-- Observer looking downwards -- Observer looking downwards
minetest.set_node(pos, {name="mcl_observers:observer_down_off"}) minetest.set_node(pos, {name="mcl_observers:observer_down_off"})
@ -104,162 +104,167 @@ local observer_orientate = function(pos, placer)
end end
end end
mesecon.register_node("mcl_observers:observer", mesecon.register_node("mcl_observers:observer", {
{ is_ground_content = false,
is_ground_content = false, sounds = mcl_sounds.node_sound_stone_defaults(),
sounds = mcl_sounds.node_sound_stone_defaults(), paramtype2 = "facedir",
paramtype2 = "facedir", on_rotate = false,
on_rotate = false, _mcl_blast_resistance = 3.5,
_mcl_blast_resistance = 3.5, _mcl_hardness = 3.5,
_mcl_hardness = 3.5, }, {
}, description = S("Observer"),
{ _tt_help = S("Emits redstone pulse when block in front changes"),
description = S("Observer"), _doc_items_longdesc = S("An observer is a redstone component which observes the block in front of it and sends a very short redstone pulse whenever this block changes."),
_tt_help = S("Emits redstone pulse when block in front changes"), _doc_items_usagehelp = S("Place the observer directly in front of the block you want to observe with the “face” looking at the block. The arrow points to the side of the output, which is at the opposite side of the “face”. You can place your redstone dust or any other component here."),
_doc_items_longdesc = S("An observer is a redstone component which observes the block in front of it and sends a very short redstone pulse whenever this block changes."),
_doc_items_usagehelp = S("Place the observer directly in front of the block you want to observe with the “face” looking at the block. The arrow points to the side of the output, which is at the opposite side of the “face”. You can place your redstone dust or any other component here."),
groups = {pickaxey=1, material_stone=1, not_opaque=1, }, groups = {pickaxey=1, material_stone=1, not_opaque=1, },
tiles = { tiles = {
"mcl_observers_observer_top.png^[transformR180", "default_furnace_bottom.png", "mcl_observers_observer_top.png^[transformR180", "default_furnace_bottom.png",
"mcl_observers_observer_side.png", "mcl_observers_observer_side.png", "mcl_observers_observer_side.png", "mcl_observers_observer_side.png",
"mcl_observers_observer_front.png", "mcl_observers_observer_back.png", "mcl_observers_observer_front.png", "mcl_observers_observer_back.png",
}, },
mesecons = { receptor = { mesecons = {
state = mesecon.state.off, receptor = {
rules = get_rules_flat, state = mesecon.state.off,
}}, rules = get_rules_flat,
on_construct = function(pos) },
if not realtime then },
observer_scan(pos, true) on_construct = function(pos)
end if not realtime then
end, observer_scan(pos, true)
after_place_node = observer_orientate, end
}, end,
{ after_place_node = observer_orientate,
_doc_items_create_entry = false, }, {
groups = {pickaxey=1, material_stone=1, not_opaque=1, not_in_creative_inventory=1 }, _doc_items_create_entry = false,
tiles = { groups = {pickaxey=1, material_stone=1, not_opaque=1, not_in_creative_inventory=1 },
"mcl_observers_observer_top.png^[transformR180", "default_furnace_bottom.png", tiles = {
"mcl_observers_observer_side.png", "mcl_observers_observer_side.png", "mcl_observers_observer_top.png^[transformR180", "default_furnace_bottom.png",
"mcl_observers_observer_front.png", "mcl_observers_observer_back_lit.png", "mcl_observers_observer_side.png", "mcl_observers_observer_side.png",
}, "mcl_observers_observer_front.png", "mcl_observers_observer_back_lit.png",
mesecons = { receptor = { },
state = mesecon.state.on, mesecons = {
rules = get_rules_flat, receptor = {
}}, state = mesecon.state.on,
rules = get_rules_flat,
}
},
-- VERY quickly disable observer after construction -- VERY quickly disable observer after construction
on_construct = function(pos) on_construct = function(pos)
local timer = minetest.get_node_timer(pos) local timer = minetest.get_node_timer(pos)
timer:start(mcl_vars.redstone_tick) timer:start(mcl_vars.redstone_tick)
end, end,
on_timer = function(pos, elapsed) on_timer = function(pos, elapsed)
local node = minetest.get_node(pos) local node = minetest.get_node(pos)
minetest.set_node(pos, {name = "mcl_observers:observer_off", param2 = node.param2}) minetest.set_node(pos, {name = "mcl_observers:observer_off", param2 = node.param2})
mesecon.receptor_off(pos, get_rules_flat(node)) mesecon.receptor_off(pos, get_rules_flat(node))
end, end,
} }
) )
mesecon.register_node("mcl_observers:observer_down", mesecon.register_node("mcl_observers:observer_down", {
{ is_ground_content = false,
is_ground_content = false, sounds = mcl_sounds.node_sound_stone_defaults(),
sounds = mcl_sounds.node_sound_stone_defaults(), groups = {pickaxey=1, material_stone=1, not_opaque=1, not_in_creative_inventory=1 },
groups = {pickaxey=1, material_stone=1, not_opaque=1, not_in_creative_inventory=1 }, on_rotate = false,
on_rotate = false, _mcl_blast_resistance = 3.5,
_mcl_blast_resistance = 3.5, _mcl_hardness = 3.5,
_mcl_hardness = 3.5, drop = "mcl_observers:observer_off",
drop = "mcl_observers:observer_off", }, {
}, tiles = {
{ "mcl_observers_observer_back.png", "mcl_observers_observer_front.png",
tiles = { "mcl_observers_observer_side.png^[transformR90", "mcl_observers_observer_side.png^[transformR90",
"mcl_observers_observer_back.png", "mcl_observers_observer_front.png", "mcl_observers_observer_top.png", "mcl_observers_observer_top.png",
"mcl_observers_observer_side.png^[transformR90", "mcl_observers_observer_side.png^[transformR90", },
"mcl_observers_observer_top.png", "mcl_observers_observer_top.png", mesecons = {
}, receptor = {
mesecons = { receptor = { state = mesecon.state.off,
state = mesecon.state.off, rules = rules_down,
rules = rules_down, },
}}, },
on_construct = function(pos) on_construct = function(pos)
if not realtime then if not realtime then
observer_scan(pos, true) observer_scan(pos, true)
end end
end, end,
}, }, {
{ _doc_items_create_entry = false,
_doc_items_create_entry = false, tiles = {
tiles = { "mcl_observers_observer_back_lit.png", "mcl_observers_observer_front.png",
"mcl_observers_observer_back_lit.png", "mcl_observers_observer_front.png", "mcl_observers_observer_side.png^[transformR90", "mcl_observers_observer_side.png^[transformR90",
"mcl_observers_observer_side.png^[transformR90", "mcl_observers_observer_side.png^[transformR90", "mcl_observers_observer_top.png", "mcl_observers_observer_top.png",
"mcl_observers_observer_top.png", "mcl_observers_observer_top.png", },
}, mesecons = {
mesecons = { receptor = { receptor = {
state = mesecon.state.on, state = mesecon.state.on,
rules = rules_down, rules = rules_down,
}}, },
},
-- VERY quickly disable observer after construction -- VERY quickly disable observer after construction
on_construct = function(pos) on_construct = function(pos)
local timer = minetest.get_node_timer(pos) local timer = minetest.get_node_timer(pos)
timer:start(mcl_vars.redstone_tick) timer:start(mcl_vars.redstone_tick)
end, end,
on_timer = function(pos, elapsed) on_timer = function(pos, elapsed)
local node = minetest.get_node(pos) local node = minetest.get_node(pos)
minetest.set_node(pos, {name = "mcl_observers:observer_down_off", param2 = node.param2}) minetest.set_node(pos, {name = "mcl_observers:observer_down_off", param2 = node.param2})
mesecon.receptor_off(pos, rules_down) mesecon.receptor_off(pos, rules_down)
end, end,
}) }
)
mesecon.register_node("mcl_observers:observer_up", mesecon.register_node("mcl_observers:observer_up", {
{ is_ground_content = false,
is_ground_content = false, sounds = mcl_sounds.node_sound_stone_defaults(),
sounds = mcl_sounds.node_sound_stone_defaults(), groups = {pickaxey=1, material_stone=1, not_opaque=1, not_in_creative_inventory=1 },
groups = {pickaxey=1, material_stone=1, not_opaque=1, not_in_creative_inventory=1 }, on_rotate = false,
on_rotate = false, _mcl_blast_resistance = 3.5,
_mcl_blast_resistance = 3.5, _mcl_hardness = 3.5,
_mcl_hardness = 3.5, drop = "mcl_observers:observer_off",
drop = "mcl_observers:observer_off", }, {
}, tiles = {
{ "mcl_observers_observer_front.png", "mcl_observers_observer_back.png",
tiles = { "mcl_observers_observer_side.png^[transformR270", "mcl_observers_observer_side.png^[transformR270",
"mcl_observers_observer_front.png", "mcl_observers_observer_back.png", "mcl_observers_observer_top.png^[transformR180", "mcl_observers_observer_top.png^[transformR180",
"mcl_observers_observer_side.png^[transformR270", "mcl_observers_observer_side.png^[transformR270", },
"mcl_observers_observer_top.png^[transformR180", "mcl_observers_observer_top.png^[transformR180", mesecons = {
}, receptor = {
mesecons = { receptor = { state = mesecon.state.off,
state = mesecon.state.off, rules = rules_up,
rules = rules_up, },
}}, },
on_construct = function(pos) on_construct = function(pos)
if not realtime then if not realtime then
observer_scan(pos, true) observer_scan(pos, true)
end end
end, end,
}, }, {
{ _doc_items_create_entry = false,
_doc_items_create_entry = false, tiles = {
tiles = { "mcl_observers_observer_front.png", "mcl_observers_observer_back_lit.png",
"mcl_observers_observer_front.png", "mcl_observers_observer_back_lit.png", "mcl_observers_observer_side.png^[transformR270", "mcl_observers_observer_side.png^[transformR270",
"mcl_observers_observer_side.png^[transformR270", "mcl_observers_observer_side.png^[transformR270", "mcl_observers_observer_top.png^[transformR180", "mcl_observers_observer_top.png^[transformR180",
"mcl_observers_observer_top.png^[transformR180", "mcl_observers_observer_top.png^[transformR180", },
}, mesecons = {
mesecons = { receptor = { receptor = {
state = mesecon.state.on, state = mesecon.state.on,
rules = rules_up, rules = rules_up,
}}, },
},
-- VERY quickly disable observer after construction -- VERY quickly disable observer after construction
on_construct = function(pos) on_construct = function(pos)
local timer = minetest.get_node_timer(pos) local timer = minetest.get_node_timer(pos)
timer:start(mcl_vars.redstone_tick) timer:start(mcl_vars.redstone_tick)
end, end,
on_timer = function(pos, elapsed) on_timer = function(pos, elapsed)
minetest.set_node(pos, {name = "mcl_observers:observer_up_off"}) minetest.set_node(pos, {name = "mcl_observers:observer_up_off"})
mesecon.receptor_off(pos, rules_up) mesecon.receptor_off(pos, rules_up)
end, end,
}) }
)
minetest.register_craft({ minetest.register_craft({
output = "mcl_observers:observer_off", output = "mcl_observers:observer_off",
@ -267,7 +272,7 @@ minetest.register_craft({
{ "mcl_core:cobble", "mcl_core:cobble", "mcl_core:cobble" }, { "mcl_core:cobble", "mcl_core:cobble", "mcl_core:cobble" },
{ "mcl_nether:quartz", "mesecons:redstone", "mesecons:redstone" }, { "mcl_nether:quartz", "mesecons:redstone", "mesecons:redstone" },
{ "mcl_core:cobble", "mcl_core:cobble", "mcl_core:cobble" }, { "mcl_core:cobble", "mcl_core:cobble", "mcl_core:cobble" },
} },
}) })
minetest.register_craft({ minetest.register_craft({
output = "mcl_observers:observer_off", output = "mcl_observers:observer_off",
@ -275,7 +280,7 @@ minetest.register_craft({
{ "mcl_core:cobble", "mcl_core:cobble", "mcl_core:cobble" }, { "mcl_core:cobble", "mcl_core:cobble", "mcl_core:cobble" },
{ "mesecons:redstone", "mesecons:redstone", "mcl_nether:quartz" }, { "mesecons:redstone", "mesecons:redstone", "mcl_nether:quartz" },
{ "mcl_core:cobble", "mcl_core:cobble", "mcl_core:cobble" }, { "mcl_core:cobble", "mcl_core:cobble", "mcl_core:cobble" },
} },
}) })
if realtime then if realtime then
@ -454,7 +459,7 @@ minetest.register_lbm({
"mcl_observers:observer_down_on", "mcl_observers:observer_down_on",
"mcl_observers:observer_up_on", "mcl_observers:observer_up_on",
}, },
run_at_every_load = true, run_at_every_load = true,
action = function(pos) action = function(pos)
minetest.after(1, mcl_observers.observer_activate, {x=pos.x, y=pos.y, z=pos.z}) minetest.after(1, mcl_observers.observer_activate, {x=pos.x, y=pos.y, z=pos.z})
end, end,

View File

@ -329,7 +329,7 @@ function mesecon.get_conductor_on(node_off, rulename)
return conductor.states[tonumber(binstate,2)+1] return conductor.states[tonumber(binstate,2)+1]
end end
end end
return offstate return conductor.offstate
end end
function mesecon.get_conductor_off(node_on, rulename) function mesecon.get_conductor_off(node_on, rulename)
@ -345,7 +345,7 @@ function mesecon.get_conductor_off(node_on, rulename)
return conductor.states[tonumber(binstate,2)+1] return conductor.states[tonumber(binstate,2)+1]
end end
end end
return onstate return conductor.onstate
end end
function mesecon.conductor_get_rules(node) function mesecon.conductor_get_rules(node)
@ -391,9 +391,7 @@ function mesecon.turnon(pos, link)
local f = table.remove(frontiers, 1) local f = table.remove(frontiers, 1)
local node = get_node_force(f.pos) local node = get_node_force(f.pos)
if not node then if node and mesecon.is_conductor_off(node, f.link) then
-- Area does not exist; do nothing
elseif mesecon.is_conductor_off(node, f.link) then
local rules = mesecon.conductor_get_rules(node) local rules = mesecon.conductor_get_rules(node)
-- Call turnon on neighbors -- Call turnon on neighbors
@ -453,9 +451,7 @@ function mesecon.turnoff(pos, link)
local f = table.remove(frontiers, 1) local f = table.remove(frontiers, 1)
local node = get_node_force(f.pos) local node = get_node_force(f.pos)
if not node then if node and mesecon.is_conductor_on(node, f.link) then
-- No-op
elseif mesecon.is_conductor_on(node, f.link) then
local rules = mesecon.conductor_get_rules(node) local rules = mesecon.conductor_get_rules(node)
for _, r in pairs(mesecon.rule2meta(f.link, rules)) do for _, r in pairs(mesecon.rule2meta(f.link, rules)) do
local np = vector.add(f.pos, r) local np = vector.add(f.pos, r)

Some files were not shown because too many files have changed in this diff Show More