mirror of
https://git.minetest.land/MineClone2/MineClone2.git
synced 2024-11-30 23:03:45 +01:00
Merge branch 'master' into doc-refactoring
This commit is contained in:
commit
d4e342313d
12
.luacheckrc
12
.luacheckrc
@ -40,4 +40,16 @@ read_globals = {
|
||||
"factorial"
|
||||
}
|
||||
},
|
||||
------
|
||||
--MODS
|
||||
------
|
||||
|
||||
--GENERAL
|
||||
"default",
|
||||
|
||||
--ENTITIES
|
||||
"cmi",
|
||||
|
||||
--HUD
|
||||
"sfinv", "sfinv_buttons", "unified_inventory", "cmsg", "inventory_plus",
|
||||
}
|
@ -1,5 +1,5 @@
|
||||
# Contributing to MineClone 2
|
||||
So you want to MineClone 2?
|
||||
So you want to contribute to MineClone 2?
|
||||
Wow, thank you! :-)
|
||||
|
||||
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`.
|
||||
|
||||
## 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
|
||||
|
||||
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
BIN
menu/Header.blend
Normal file
Binary file not shown.
@ -121,7 +121,7 @@ local hardness_values = get_hardness_values_for_groups()
|
||||
-- hardness_value. Used for quick lookup.
|
||||
local hardness_lookup = get_hardness_lookup_for_groups(hardness_values)
|
||||
|
||||
local function compute_creativetimes(group)
|
||||
--[[local function compute_creativetimes(group)
|
||||
local creativetimes = {}
|
||||
|
||||
for index, hardness in pairs(hardness_values[group]) do
|
||||
@ -129,7 +129,7 @@ local function compute_creativetimes(group)
|
||||
end
|
||||
|
||||
return creativetimes
|
||||
end
|
||||
end]]
|
||||
|
||||
-- Get the list of digging times for using a specific tool on a specific
|
||||
-- diggroup.
|
||||
@ -239,13 +239,13 @@ function mcl_autogroup.can_harvest(nodename, toolname)
|
||||
end
|
||||
|
||||
-- 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 {
|
||||
times = get_digtimes(group, can_harvest, multiplier, efficiency),
|
||||
uses = uses,
|
||||
maxlevel = 0,
|
||||
}
|
||||
end
|
||||
end]]
|
||||
|
||||
-- Returns the tool_capabilities from a tool definition or a default set of
|
||||
-- tool_capabilities
|
||||
@ -271,7 +271,7 @@ end
|
||||
-- toolname - Name of the tool being enchanted (like "mcl_tools:diamond_pickaxe")
|
||||
-- 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
|
||||
-- would have to add _mcl_autogroup as a dependency which would break the mod
|
||||
-- loading order.
|
||||
@ -288,7 +288,7 @@ end
|
||||
-- toolname - Name of the tool used
|
||||
-- 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
|
||||
-- would have to add _mcl_autogroup as a dependency which would break the mod
|
||||
-- loading order.
|
||||
@ -298,7 +298,7 @@ function mcl_autogroup.get_wear(toolname, diggroup)
|
||||
return math.ceil(65535 / uses)
|
||||
end
|
||||
|
||||
local overwrite = function()
|
||||
local function overwrite()
|
||||
for nname, ndef in pairs(minetest.registered_nodes) do
|
||||
local newgroups = table.copy(ndef.groups)
|
||||
if (nname ~= "ignore" and ndef.diggable) then
|
||||
@ -315,12 +315,12 @@ local overwrite = function()
|
||||
newgroups.opaque = 1
|
||||
end
|
||||
|
||||
local creative_breakable = false
|
||||
--local creative_breakable = false
|
||||
|
||||
-- Assign groups used for digging this node depending on
|
||||
-- the registered digging groups
|
||||
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]
|
||||
if ndef.groups[g] then
|
||||
if gdef.levels then
|
||||
|
@ -81,11 +81,11 @@ if v6_use_snow_biomes then
|
||||
end
|
||||
local v6_freq_desert = tonumber(minetest.get_mapgen_setting("mgv6_freq_desert") or 0.45)
|
||||
|
||||
local NOISE_MAGIC_X = 1619
|
||||
local NOISE_MAGIC_Y = 31337
|
||||
local NOISE_MAGIC_Z = 52591
|
||||
local NOISE_MAGIC_SEED = 1013
|
||||
local noise2d = function(x, y, seed)
|
||||
--local NOISE_MAGIC_X = 1619
|
||||
--local NOISE_MAGIC_Y = 31337
|
||||
--local NOISE_MAGIC_Z = 52591
|
||||
--local NOISE_MAGIC_SEED = 1013
|
||||
local function noise2d(x, y, seed)
|
||||
-- TODO: implement noise2d function for biome blend
|
||||
return 0
|
||||
--[[
|
||||
|
@ -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 = {}
|
||||
|
||||
--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)
|
||||
--(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 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]}
|
||||
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
|
||||
|
||||
local is_touching = function(realpos,nodepos,radius)
|
||||
local function is_touching(realpos,nodepos,radius)
|
||||
local boarder = 0.5 - radius
|
||||
return (math.abs(realpos - nodepos) > (boarder))
|
||||
return math.abs(realpos - nodepos) > (boarder)
|
||||
end
|
||||
|
||||
flowlib.is_touching = is_touching
|
||||
|
||||
local is_water = function(pos)
|
||||
return (minetest.get_item_group(minetest.get_node(
|
||||
{x=pos.x,y=pos.y,z=pos.z}).name
|
||||
, "water") ~= 0)
|
||||
local function is_water(pos)
|
||||
return get_item_group(get_node(pos).name, "water") ~= 0
|
||||
end
|
||||
|
||||
flowlib.is_water = is_water
|
||||
|
||||
local node_is_water = function(node)
|
||||
return (minetest.get_item_group(node.name, "water") ~= 0)
|
||||
local function node_is_water(node)
|
||||
return get_item_group(node.name, "water") ~= 0
|
||||
end
|
||||
|
||||
flowlib.node_is_water = node_is_water
|
||||
|
||||
local is_lava = function(pos)
|
||||
return (minetest.get_item_group(minetest.get_node(
|
||||
{x=pos.x,y=pos.y,z=pos.z}).name
|
||||
, "lava") ~= 0)
|
||||
local function is_lava(pos)
|
||||
return get_item_group(get_node(pos).name, "lava") ~= 0
|
||||
end
|
||||
|
||||
flowlib.is_lava = is_lava
|
||||
|
||||
local node_is_lava = function(node)
|
||||
return (minetest.get_item_group(node.name, "lava") ~= 0)
|
||||
local function node_is_lava(node)
|
||||
return get_item_group(node.name, "lava") ~= 0
|
||||
end
|
||||
|
||||
flowlib.node_is_lava = node_is_lava
|
||||
|
||||
|
||||
local is_liquid = function(pos)
|
||||
return (minetest.get_item_group(minetest.get_node(
|
||||
{x=pos.x,y=pos.y,z=pos.z}).name
|
||||
, "liquid") ~= 0)
|
||||
local function is_liquid(pos)
|
||||
return get_item_group(get_node(pos).name, "liquid") ~= 0
|
||||
end
|
||||
|
||||
flowlib.is_liquid = is_liquid
|
||||
|
||||
local node_is_liquid = function(node)
|
||||
return (minetest.get_item_group(node.name, "liquid") ~= 0)
|
||||
local function node_is_liquid(node)
|
||||
return minetest.get_item_group(node.name, "liquid") ~= 0
|
||||
end
|
||||
|
||||
flowlib.node_is_liquid = node_is_liquid
|
||||
|
||||
--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
|
||||
if not minetest.registered_nodes[name] then
|
||||
if not registered_nodes[name] then
|
||||
return 0
|
||||
end
|
||||
if minetest.registered_nodes[name].liquidtype == "source" then
|
||||
local node_testing = minetest.get_node(pos_testing)
|
||||
local param2_testing = node_testing.param2
|
||||
if not minetest.registered_nodes[node_testing.name] then
|
||||
if registered_nodes[name].liquidtype == "source" then
|
||||
local node_testing = get_node(pos_testing)
|
||||
if not registered_nodes[node_testing.name] then
|
||||
return 0
|
||||
end
|
||||
if minetest.registered_nodes[node_testing.name].liquidtype
|
||||
~= "flowing" then
|
||||
if registered_nodes[node_testing.name].liquidtype ~= "flowing" then
|
||||
return 0
|
||||
else
|
||||
return direction
|
||||
end
|
||||
elseif minetest.registered_nodes[name].liquidtype == "flowing" then
|
||||
local node_testing = minetest.get_node(pos_testing)
|
||||
elseif registered_nodes[name].liquidtype == "flowing" then
|
||||
local node_testing = get_node(pos_testing)
|
||||
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
|
||||
end
|
||||
if minetest.registered_nodes[node_testing.name].liquidtype
|
||||
== "source" then
|
||||
if registered_nodes[node_testing.name].liquidtype == "source" then
|
||||
return -direction
|
||||
elseif minetest.registered_nodes[node_testing.name].liquidtype
|
||||
== "flowing" then
|
||||
elseif registered_nodes[node_testing.name].liquidtype == "flowing" then
|
||||
if param2_testing < node.param2 then
|
||||
if (node.param2 - param2_testing) > 6 then
|
||||
return -direction
|
||||
@ -108,48 +113,41 @@ local function quick_flow_logic(node,pos_testing,direction)
|
||||
return 0
|
||||
end
|
||||
|
||||
local quick_flow = function(pos,node)
|
||||
local x = 0
|
||||
local z = 0
|
||||
|
||||
local function quick_flow(pos, node)
|
||||
if not node_is_liquid(node) then
|
||||
return {x=0,y=0,z=0}
|
||||
return {x = 0, y = 0, z = 0}
|
||||
end
|
||||
|
||||
x = x + 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)
|
||||
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})
|
||||
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)
|
||||
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)
|
||||
return to_unit_vector({x = x, y = 0, z = z})
|
||||
end
|
||||
|
||||
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
|
||||
--x has higher precedence than z
|
||||
--if pos changes with x, it affects z
|
||||
local move_centre = function(pos,realpos,node,radius)
|
||||
if is_touching(realpos.x,pos.x,radius) then
|
||||
if 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}
|
||||
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}
|
||||
local function move_centre(pos, realpos, node, radius)
|
||||
if is_touching(realpos.x, pos.x, radius) then
|
||||
if is_liquid({x = pos.x-1, y = pos.y, z = pos.z}) then
|
||||
node = get_node({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 = 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
|
||||
if is_touching(realpos.z,pos.z,radius) 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})
|
||||
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
|
||||
node = minetest.get_node({x=pos.x,y=pos.y,z=pos.z+1})
|
||||
pos = {x=pos.x,y=pos.y,z=pos.z+1}
|
||||
if is_touching(realpos.z, pos.z, radius) then
|
||||
if is_liquid({x = pos.x, y = pos.y, z = pos.z - 1}) then
|
||||
node = get_node({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
|
||||
node = get_node({x = pos.x, y = pos.y, z = pos.z + 1})
|
||||
pos = {x = pos.x, y = pos.y, z = pos.z + 1}
|
||||
end
|
||||
end
|
||||
return pos,node
|
||||
return pos, node
|
||||
end
|
||||
|
||||
flowlib.move_centre = move_centre
|
||||
|
@ -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
|
||||
|
||||
minetest.check_single_for_falling = function(pos)
|
||||
function minetest.check_single_for_falling(pos)
|
||||
local ret_o = original_function(pos)
|
||||
|
||||
local ret = false
|
||||
local node = minetest.get_node(pos)
|
||||
if minetest.get_item_group(node.name, "attached_node_facedir") ~= 0 then
|
||||
local dir = minetest.facedir_to_dir(node.param2)
|
||||
if get_item_group(node.name, "attached_node_facedir") ~= 0 then
|
||||
local dir = facedir_to_dir(node.param2)
|
||||
if dir then
|
||||
local cpos = vector.add(pos, dir)
|
||||
local cnode = minetest.get_node(cpos)
|
||||
if minetest.get_item_group(cnode.name, "solid") == 0 then
|
||||
minetest.remove_node(pos)
|
||||
if get_item_group(get_node(vector.add(pos, dir)).name, "solid") == 0 then
|
||||
remove_node(pos)
|
||||
local drops = minetest.get_node_drops(node.name, "")
|
||||
for dr=1, #drops do
|
||||
minetest.add_item(pos, drops[dr])
|
||||
@ -20,7 +24,6 @@ minetest.check_single_for_falling = function(pos)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
return ret_o or ret
|
||||
end
|
||||
|
||||
|
@ -13,9 +13,7 @@ under the LGPLv2.1 license.
|
||||
mcl_explosions = {}
|
||||
|
||||
local mod_fire = minetest.get_modpath("mcl_fire") ~= nil
|
||||
local CONTENT_FIRE = minetest.get_content_id("mcl_fire:fire")
|
||||
|
||||
local S = minetest.get_translator("mcl_explosions")
|
||||
--local CONTENT_FIRE = minetest.get_content_id("mcl_fire:fire")
|
||||
|
||||
local hash_node_position = minetest.hash_node_position
|
||||
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 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,
|
||||
MaxEdge = emax
|
||||
}
|
||||
}]]
|
||||
local data = vm:get_data()
|
||||
local destroy = {}
|
||||
|
||||
|
@ -1,2 +0,0 @@
|
||||
# textdomain:mcl_explosions
|
||||
@1 was caught in an explosion.=@1 wurde Opfer einer Explosion.
|
@ -1,2 +0,0 @@
|
||||
# textdomain:mcl_explosions
|
||||
@1 was caught in an explosion.=@1 a été pris dans une explosion.
|
@ -1,2 +0,0 @@
|
||||
# textdomain:mcl_explosions
|
||||
@1 was caught in an explosion.=@1 не удалось пережить взрыва.
|
@ -1,2 +0,0 @@
|
||||
# textdomain:mcl_explosions
|
||||
@1 was caught in an explosion.=
|
@ -40,10 +40,9 @@ function mcl_loot.get_loot(loot_definitions, pr)
|
||||
total_weight = total_weight + (loot_definitions.items[i].weight or 1)
|
||||
end
|
||||
|
||||
local stacks_min = loot_definitions.stacks_min
|
||||
local stacks_max = loot_definitions.stacks_max
|
||||
if not stacks_min then stacks_min = 1 end
|
||||
if not stacks_max then stacks_max = 1 end
|
||||
--local stacks_min = loot_definitions.stacks_min or 1
|
||||
--local stacks_max = loot_definitions.stacks_max or 1
|
||||
|
||||
local stacks = pr:next(loot_definitions.stacks_min, loot_definitions.stacks_max)
|
||||
for s=1, stacks do
|
||||
local r = pr:next(1, total_weight)
|
||||
|
@ -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 = {}
|
||||
|
||||
-- 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
|
||||
return
|
||||
end
|
||||
local poshash = minetest.hash_node_position(pos)
|
||||
local poshash = hash_node_position(pos)
|
||||
if not poshash then
|
||||
return
|
||||
end
|
||||
local id = minetest.add_particlespawner(particlespawner_definition)
|
||||
local id = add_particlespawner(particlespawner_definition)
|
||||
if id == -1 then
|
||||
return
|
||||
end
|
||||
@ -47,6 +56,8 @@ function mcl_particles.add_node_particlespawner(pos, particlespawner_definition,
|
||||
return id
|
||||
end
|
||||
|
||||
local add_node_particlespawner = mcl_particles.add_node_particlespawner
|
||||
|
||||
-- Deletes all particlespawners that are assigned to a node position.
|
||||
-- If no particlespawners exist for this position, nothing happens.
|
||||
-- pos: Node positon. MUST use integer values!
|
||||
@ -55,11 +66,11 @@ function mcl_particles.delete_node_particlespawners(pos)
|
||||
if allowed_level == 0 then
|
||||
return false
|
||||
end
|
||||
local poshash = minetest.hash_node_position(pos)
|
||||
local poshash = hash_node_position(pos)
|
||||
local ids = particle_nodes[poshash]
|
||||
if ids then
|
||||
for i=1, #ids do
|
||||
minetest.delete_particlespawner(ids[i])
|
||||
delete_particlespawner(ids[i])
|
||||
end
|
||||
particle_nodes[poshash] = nil
|
||||
return true
|
||||
@ -72,7 +83,6 @@ end
|
||||
local smoke_pdef_cached = {}
|
||||
|
||||
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_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
|
||||
smoke_pdef.minpos = new_minpos
|
||||
smoke_pdef.maxpos = new_maxpos
|
||||
mcl_particles.add_node_particlespawner(pos, smoke_pdef, "high")
|
||||
add_node_particlespawner(pos, smoke_pdef, "high")
|
||||
end
|
||||
-- cache already populated
|
||||
else
|
||||
@ -111,13 +121,11 @@ function mcl_particles.spawn_smoke(pos, name, smoke_pdef_base)
|
||||
smoke_pdef.animation.length = exptime + 0.1
|
||||
-- minexptime must be set such that the last frame is actully rendered,
|
||||
-- even if its very short. Larger exptime -> larger range
|
||||
smoke_pdef.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
|
||||
|
||||
mcl_particles.add_node_particlespawner(pos, smoke_pdef, "high")
|
||||
|
||||
add_node_particlespawner(pos, smoke_pdef, "high")
|
||||
table.insert(smoke_pdef_cached[name], table.copy(smoke_pdef))
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
@ -150,7 +150,7 @@ function mcl_util.get_eligible_transfer_item_slot(src_inventory, src_list, dst_i
|
||||
end
|
||||
|
||||
-- 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")
|
||||
return g == 0 or g == nil
|
||||
end
|
||||
@ -212,7 +212,7 @@ function mcl_util.move_item_container(source_pos, destination_pos, source_list,
|
||||
end
|
||||
|
||||
-- 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
|
||||
pos = mcl_util.get_double_container_neighbor_pos(pos, node.param2, "right")
|
||||
if not pos then
|
||||
@ -456,14 +456,7 @@ function mcl_util.calculate_durability(itemstack)
|
||||
end
|
||||
end
|
||||
end
|
||||
if not uses then
|
||||
local toolcaps = itemstack:get_tool_capabilities()
|
||||
local groupcaps = toolcaps.groupcaps
|
||||
for _, v in pairs(groupcaps) do
|
||||
uses = v.uses
|
||||
break
|
||||
end
|
||||
end
|
||||
uses = uses or (next(itemstack:get_tool_capabilities().groupcaps) or {}).uses
|
||||
end
|
||||
|
||||
return uses or 0
|
||||
|
@ -33,15 +33,15 @@ end
|
||||
-- If the Y coordinate is not located in any dimension, it will return:
|
||||
-- nil, "void"
|
||||
function mcl_worlds.y_to_layer(y)
|
||||
if y >= mcl_vars.mg_overworld_min then
|
||||
return y - mcl_vars.mg_overworld_min, "overworld"
|
||||
elseif y >= mcl_vars.mg_nether_min and y <= mcl_vars.mg_nether_max+128 then
|
||||
return y - mcl_vars.mg_nether_min, "nether"
|
||||
elseif y >= mcl_vars.mg_end_min and y <= mcl_vars.mg_end_max then
|
||||
return y - mcl_vars.mg_end_min, "end"
|
||||
else
|
||||
return nil, "void"
|
||||
end
|
||||
if y >= mcl_vars.mg_overworld_min then
|
||||
return y - mcl_vars.mg_overworld_min, "overworld"
|
||||
elseif y >= mcl_vars.mg_nether_min and y <= mcl_vars.mg_nether_max+128 then
|
||||
return y - mcl_vars.mg_nether_min, "nether"
|
||||
elseif y >= mcl_vars.mg_end_min and y <= mcl_vars.mg_end_max then
|
||||
return y - mcl_vars.mg_end_min, "end"
|
||||
else
|
||||
return nil, "void"
|
||||
end
|
||||
end
|
||||
|
||||
-- Takes a pos and returns the dimension it belongs to (same as above)
|
||||
@ -55,38 +55,38 @@ end
|
||||
-- MineClone 2.
|
||||
-- mc_dimension is one of "overworld", "nether", "end" (default: "overworld").
|
||||
function mcl_worlds.layer_to_y(layer, mc_dimension)
|
||||
if mc_dimension == "overworld" or mc_dimension == nil then
|
||||
return layer + mcl_vars.mg_overworld_min
|
||||
elseif mc_dimension == "nether" then
|
||||
return layer + mcl_vars.mg_nether_min
|
||||
elseif mc_dimension == "end" then
|
||||
return layer + mcl_vars.mg_end_min
|
||||
end
|
||||
if mc_dimension == "overworld" or mc_dimension == nil then
|
||||
return layer + mcl_vars.mg_overworld_min
|
||||
elseif mc_dimension == "nether" then
|
||||
return layer + mcl_vars.mg_nether_min
|
||||
elseif mc_dimension == "end" then
|
||||
return layer + mcl_vars.mg_end_min
|
||||
end
|
||||
end
|
||||
|
||||
-- Takes a position and returns true if this position can have weather
|
||||
function mcl_worlds.has_weather(pos)
|
||||
-- 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
|
||||
-- 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
|
||||
end
|
||||
|
||||
-- Takes a position and returns true if this position can have Nether dust
|
||||
function mcl_worlds.has_dust(pos)
|
||||
-- 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
|
||||
-- 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
|
||||
end
|
||||
|
||||
-- Takes a position (pos) and returns true if compasses are working here
|
||||
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
|
||||
local _, dim = mcl_worlds.y_to_layer(pos.y)
|
||||
if dim == "nether" or dim == "end" then
|
||||
return false
|
||||
elseif dim == "void" then
|
||||
return pos.y <= mcl_vars.mg_overworld_max and pos.y >= mcl_vars.mg_overworld_min - 64
|
||||
else
|
||||
return true
|
||||
end
|
||||
-- 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)
|
||||
if dim == "nether" or dim == "end" then
|
||||
return false
|
||||
elseif dim == "void" then
|
||||
return pos.y <= mcl_vars.mg_overworld_max and pos.y >= mcl_vars.mg_overworld_min - 64
|
||||
else
|
||||
return true
|
||||
end
|
||||
end
|
||||
|
||||
-- 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
|
||||
-- * dimension: New dimension ("overworld", "nether", "end", "void")
|
||||
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
|
||||
mcl_worlds.registered_on_dimension_change[i](player, dimension, last_dimension[playername])
|
||||
end
|
||||
last_dimension[playername] = dimension
|
||||
last_dimension[playername] = dimension
|
||||
end
|
||||
|
||||
----------------------- INTERNAL STUFF ----------------------
|
||||
|
@ -31,24 +31,21 @@ minetest.register_globalstep(function(dtime)
|
||||
timer = timer + dtime;
|
||||
if timer >= 0.3 then
|
||||
for _,player in pairs(get_connected_players()) do
|
||||
local pp = player:get_pos()
|
||||
pp.y = ceil(pp.y)
|
||||
local loc = vector_add(pp, {x=0,y=-1,z=0})
|
||||
if loc ~= nil then
|
||||
|
||||
local nodeiamon = get_node(loc)
|
||||
|
||||
if nodeiamon ~= nil then
|
||||
if on_walk[nodeiamon.name] then
|
||||
on_walk[nodeiamon.name](loc, nodeiamon, player)
|
||||
end
|
||||
for i = 1, #registered_globals do
|
||||
local pp = player:get_pos()
|
||||
pp.y = ceil(pp.y)
|
||||
local loc = vector_add(pp, {x=0,y=-1,z=0})
|
||||
if loc ~= nil then
|
||||
local nodeiamon = get_node(loc)
|
||||
if nodeiamon ~= nil then
|
||||
if on_walk[nodeiamon.name] then
|
||||
on_walk[nodeiamon.name](loc, nodeiamon, player)
|
||||
end
|
||||
for i = 1, #registered_globals do
|
||||
registered_globals[i](loc, nodeiamon, player)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
timer = 0
|
||||
end
|
||||
end)
|
||||
|
@ -1,6 +1,8 @@
|
||||
--Dripping Water Mod
|
||||
--by kddekadenz
|
||||
|
||||
local math = math
|
||||
|
||||
-- License of code, textures & sounds: CC0
|
||||
|
||||
--Drop entities
|
||||
@ -20,26 +22,21 @@ minetest.register_entity("drippingwater:drop_water", {
|
||||
spritediv = {x=1, y=1},
|
||||
initial_sprite_basepos = {x=0, y=0},
|
||||
static_save = false,
|
||||
|
||||
on_activate = function(self, staticdata)
|
||||
self.object:set_sprite({x=0,y=0}, 1, 1, true)
|
||||
end,
|
||||
|
||||
on_step = function(self, dtime)
|
||||
local k = math.random(1,222)
|
||||
local ownpos = self.object:get_pos()
|
||||
|
||||
if k==1 then
|
||||
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
|
||||
self.object:set_acceleration({x=0, y=-5, z=0})
|
||||
end
|
||||
|
||||
local k = math.random(1,222)
|
||||
local ownpos = self.object:get_pos()
|
||||
if k==1 then
|
||||
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
|
||||
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
|
||||
self.object:remove()
|
||||
minetest.sound_play({name="drippingwater_drip"}, {pos = ownpos, gain = 0.5, max_hear_distance = 8}, true)
|
||||
self.object:remove()
|
||||
minetest.sound_play({name="drippingwater_drip"}, {pos = ownpos, gain = 0.5, max_hear_distance = 8}, true)
|
||||
end
|
||||
end,
|
||||
})
|
||||
@ -61,27 +58,21 @@ minetest.register_entity("drippingwater:drop_lava", {
|
||||
spritediv = {x=1, y=1},
|
||||
initial_sprite_basepos = {x=0, y=0},
|
||||
static_save = false,
|
||||
|
||||
on_activate = function(self, staticdata)
|
||||
self.object:set_sprite({x=0,y=0}, 1, 0, true)
|
||||
end,
|
||||
|
||||
on_step = function(self, dtime)
|
||||
local k = math.random(1,222)
|
||||
local ownpos = self.object:get_pos()
|
||||
|
||||
if k==1 then
|
||||
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
|
||||
self.object:set_acceleration({x=0, y=-5, z=0})
|
||||
end
|
||||
|
||||
|
||||
local k = math.random(1,222)
|
||||
local ownpos = self.object:get_pos()
|
||||
if k == 1 then
|
||||
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
|
||||
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
|
||||
self.object:remove()
|
||||
minetest.sound_play({name="drippingwater_lavadrip"}, {pos = ownpos, gain = 0.5, max_hear_distance = 8}, true)
|
||||
self.object:remove()
|
||||
minetest.sound_play({name="drippingwater_lavadrip"}, {pos = ownpos, gain = 0.5, max_hear_distance = 8}, true)
|
||||
end
|
||||
end,
|
||||
})
|
||||
@ -90,36 +81,34 @@ minetest.register_entity("drippingwater:drop_lava", {
|
||||
|
||||
--Create drop
|
||||
|
||||
minetest.register_abm(
|
||||
{
|
||||
minetest.register_abm({
|
||||
label = "Create water drops",
|
||||
nodenames = {"group:opaque", "group:leaves"},
|
||||
neighbors = {"group:water"},
|
||||
interval = 2,
|
||||
chance = 22,
|
||||
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
|
||||
minetest.get_node({x=pos.x, y=pos.y-1, z=pos.z}).name == "air" then
|
||||
interval = 2,
|
||||
chance = 22,
|
||||
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 minetest.get_node({x=pos.x, y=pos.y-1, z=pos.z}).name == "air" then
|
||||
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")
|
||||
end
|
||||
end,
|
||||
end,
|
||||
})
|
||||
|
||||
--Create lava drop
|
||||
|
||||
minetest.register_abm(
|
||||
{
|
||||
minetest.register_abm({
|
||||
label = "Create lava drops",
|
||||
nodenames = {"group:opaque"},
|
||||
neighbors = {"group:lava"},
|
||||
interval = 2,
|
||||
chance = 22,
|
||||
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
|
||||
minetest.get_node({x=pos.x, y=pos.y-1, z=pos.z}).name == "air" then
|
||||
interval = 2,
|
||||
chance = 22,
|
||||
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 minetest.get_node({x=pos.x, y=pos.y-1, z=pos.z}).name == "air" then
|
||||
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")
|
||||
end
|
||||
end,
|
||||
})
|
||||
end,
|
||||
})
|
@ -328,10 +328,10 @@ function boat.on_step(self, dtime, moveresult)
|
||||
|
||||
p.y = p.y - boat_y_offset
|
||||
local new_velo
|
||||
local new_acce = {x = 0, y = 0, z = 0}
|
||||
local new_acce
|
||||
if not is_water(p) and not on_ice then
|
||||
-- Not on water or inside water: Free fall
|
||||
local nodedef = minetest.registered_nodes[minetest.get_node(p).name]
|
||||
--local nodedef = minetest.registered_nodes[minetest.get_node(p).name]
|
||||
new_acce = {x = 0, y = -9.8, z = 0}
|
||||
new_velo = get_velocity(self._v, self.object:get_yaw(),
|
||||
self.object:get_velocity().y)
|
||||
|
@ -1,5 +1,3 @@
|
||||
local S = minetest.get_translator("mcl_burning")
|
||||
|
||||
function mcl_burning.get_storage(obj)
|
||||
return obj:is_player() and mcl_burning.storage[obj] or obj:get_luaentity()
|
||||
end
|
||||
@ -145,4 +143,4 @@ function mcl_burning.tick(obj, dtime, storage)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
@ -1,5 +1,4 @@
|
||||
local S = minetest.get_translator("mcl_burning")
|
||||
local modpath = minetest.get_modpath("mcl_burning")
|
||||
local modpath = minetest.get_modpath(minetest.get_current_modname())
|
||||
|
||||
mcl_burning = {
|
||||
storage = {},
|
||||
@ -56,7 +55,6 @@ minetest.register_on_leaveplayer(function(player)
|
||||
local storage = mcl_burning.storage[player]
|
||||
storage.fire_hud_id = nil
|
||||
player:get_meta():set_string("mcl_burning:data", minetest.serialize(storage))
|
||||
|
||||
mcl_burning.storage[player] = nil
|
||||
end)
|
||||
|
||||
@ -68,11 +66,10 @@ minetest.register_entity("mcl_burning:fire", {
|
||||
visual = "cube",
|
||||
pointable = false,
|
||||
glow = -1,
|
||||
backface_culling = false,
|
||||
},
|
||||
|
||||
animation_frame = 0,
|
||||
animation_timer = 0,
|
||||
|
||||
on_step = function(self, dtime)
|
||||
local parent, storage = self:sanity_check()
|
||||
|
||||
|
@ -1,7 +1,4 @@
|
||||
local S = minetest.get_translator("mcl_falling_nodes")
|
||||
local has_mcl_armor = minetest.get_modpath("mcl_armor")
|
||||
|
||||
local get_falling_depth = function(self)
|
||||
local function get_falling_depth(self)
|
||||
if not self._startpos then
|
||||
-- Fallback
|
||||
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
|
||||
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
|
||||
return
|
||||
end
|
||||
@ -38,7 +35,7 @@ local deal_falling_damage = function(self, dtime)
|
||||
inv:set_stack("armor", 2, helmet)
|
||||
end
|
||||
end
|
||||
local deathmsg, dmg_type
|
||||
local dmg_type
|
||||
if minetest.get_item_group(self.node.name, "anvil") ~= 0 then
|
||||
dmg_type = "anvil"
|
||||
else
|
||||
@ -60,10 +57,8 @@ minetest.register_entity(":__builtin:falling_node", {
|
||||
collide_with_objects = false,
|
||||
collisionbox = {-0.5, -0.5, -0.5, 0.5, 0.5, 0.5},
|
||||
},
|
||||
|
||||
node = {},
|
||||
meta = {},
|
||||
|
||||
set_node = function(self, node, meta)
|
||||
local def = minetest.registered_nodes[node.name]
|
||||
-- Change falling node if definition tells us to
|
||||
@ -90,7 +85,6 @@ minetest.register_entity(":__builtin:falling_node", {
|
||||
glow = glow,
|
||||
})
|
||||
end,
|
||||
|
||||
get_staticdata = function(self)
|
||||
local meta = self.meta
|
||||
-- Workaround: Save inventory seperately from metadata.
|
||||
@ -111,7 +105,6 @@ minetest.register_entity(":__builtin:falling_node", {
|
||||
}
|
||||
return minetest.serialize(ds)
|
||||
end,
|
||||
|
||||
on_activate = function(self, staticdata)
|
||||
self.object:set_armor_groups({immortal = 1})
|
||||
|
||||
@ -134,7 +127,6 @@ minetest.register_entity(":__builtin:falling_node", {
|
||||
end
|
||||
self._startpos = vector.round(self._startpos)
|
||||
end,
|
||||
|
||||
on_step = function(self, dtime)
|
||||
-- Set gravity
|
||||
local acceleration = self.object:get_acceleration()
|
||||
@ -186,10 +178,9 @@ minetest.register_entity(":__builtin:falling_node", {
|
||||
return
|
||||
end
|
||||
local nd = minetest.registered_nodes[n2.name]
|
||||
if n2.name == "mcl_portals:portal_end" then
|
||||
-- TODO: Teleport falling node.
|
||||
|
||||
elseif (nd and nd.buildable_to == true) or minetest.get_item_group(self.node.name, "crush_after_fall") ~= 0 then
|
||||
--if n2.name == "mcl_portals:portal_end" then
|
||||
-- TODO: Teleport falling node.
|
||||
if (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
|
||||
minetest.remove_node(np)
|
||||
-- Run script hook
|
||||
@ -256,7 +247,6 @@ minetest.register_entity(":__builtin:falling_node", {
|
||||
self.object:set_pos(npos)
|
||||
end
|
||||
end
|
||||
|
||||
deal_falling_damage(self, dtime)
|
||||
end
|
||||
})
|
||||
|
@ -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.
|
@ -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.
|
@ -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.
|
@ -1,3 +0,0 @@
|
||||
# textdomain: mcl_falling_nodes
|
||||
@1 was smashed by a falling anvil.=@1 придавило падающей наковальней.
|
||||
@1 was smashed by a falling block.=@1 раздавило падающим блоком.
|
@ -1,3 +0,0 @@
|
||||
# textdomain: mcl_falling_nodes
|
||||
@1 was smashed by a falling anvil.=
|
||||
@1 was smashed by a falling block.=
|
@ -1,5 +1,5 @@
|
||||
--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
|
||||
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
|
||||
|
||||
local get_gravity = function()
|
||||
local function get_gravity()
|
||||
return tonumber(minetest.settings:get("movement_gravity")) or 9.81
|
||||
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_core:diamond", "mcl:diamonds")
|
||||
|
||||
local check_pickup_achievements = function(object, player)
|
||||
local function check_pickup_achievements(object, player)
|
||||
if has_awards then
|
||||
local itemname = ItemStack(object:get_luaentity().itemstring):get_name()
|
||||
local playername = player:get_player_name()
|
||||
@ -72,7 +72,7 @@ local check_pickup_achievements = function(object, player)
|
||||
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
|
||||
luaentity.physical_state = true
|
||||
object:set_properties({
|
||||
@ -83,7 +83,7 @@ local enable_physics = function(object, luaentity, ignore_check)
|
||||
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
|
||||
luaentity.physical_state = false
|
||||
object:set_properties({
|
||||
@ -98,13 +98,11 @@ end
|
||||
|
||||
|
||||
minetest.register_globalstep(function(dtime)
|
||||
|
||||
tick = not tick
|
||||
|
||||
for _,player in pairs(minetest.get_connected_players()) do
|
||||
if player:get_hp() > 0 or not minetest.settings:get_bool("enable_damage") then
|
||||
|
||||
|
||||
local name = player:get_player_name()
|
||||
|
||||
local pos = player:get_pos()
|
||||
@ -426,13 +424,9 @@ minetest.register_entity(":__builtin:item", {
|
||||
if itemtable then
|
||||
itemname = stack:to_table().name
|
||||
end
|
||||
local item_texture = nil
|
||||
local item_type = ""
|
||||
local glow
|
||||
local def = minetest.registered_items[itemname]
|
||||
if def then
|
||||
item_texture = def.inventory_image
|
||||
item_type = def.type
|
||||
description = def.description
|
||||
glow = def.light_source
|
||||
end
|
||||
|
@ -1,3 +1,5 @@
|
||||
local vector = vector
|
||||
|
||||
function mcl_minecarts:get_sign(z)
|
||||
if z == 0 then
|
||||
return 0
|
||||
@ -38,11 +40,9 @@ end
|
||||
|
||||
function mcl_minecarts:check_front_up_down(pos, dir_, check_down, railtype)
|
||||
local dir = vector.new(dir_)
|
||||
local cur = nil
|
||||
|
||||
-- Front
|
||||
dir.y = 0
|
||||
cur = vector.add(pos, dir)
|
||||
local cur = vector.add(pos, dir)
|
||||
if mcl_minecarts:is_rail(cur, railtype) then
|
||||
return dir
|
||||
end
|
||||
@ -65,9 +65,9 @@ end
|
||||
|
||||
function mcl_minecarts:get_rail_direction(pos_, dir, ctrl, old_switch, railtype)
|
||||
local pos = vector.round(pos_)
|
||||
local cur = nil
|
||||
local cur
|
||||
local left_check, right_check = true, true
|
||||
|
||||
|
||||
-- Check left and right
|
||||
local left = {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
|
||||
right.z = -dir.x
|
||||
end
|
||||
|
||||
|
||||
if ctrl then
|
||||
if old_switch == 1 then
|
||||
left_check = false
|
||||
@ -100,13 +100,13 @@ function mcl_minecarts:get_rail_direction(pos_, dir, ctrl, old_switch, railtype)
|
||||
right_check = true
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
-- Normal
|
||||
cur = mcl_minecarts:check_front_up_down(pos, dir, true, railtype)
|
||||
if cur then
|
||||
return cur
|
||||
end
|
||||
|
||||
|
||||
-- Left, if not already checked
|
||||
if left_check then
|
||||
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
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
-- Right, if not already checked
|
||||
if right_check then
|
||||
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
|
||||
end
|
||||
end
|
||||
|
||||
-- Backwards
|
||||
if not old_switch then
|
||||
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
|
||||
end
|
||||
end
|
||||
|
||||
return {x=0, y=0, z=0}
|
||||
end
|
||||
|
||||
end
|
@ -486,7 +486,6 @@ local function register_entity(entity_id, mesh, textures, drop, on_rightclick, o
|
||||
if update.pos then
|
||||
self.object:set_pos(pos)
|
||||
end
|
||||
update = nil
|
||||
end
|
||||
|
||||
function cart:get_staticdata()
|
||||
@ -497,7 +496,7 @@ local function register_entity(entity_id, mesh, textures, drop, on_rightclick, o
|
||||
end
|
||||
|
||||
-- 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
|
||||
return
|
||||
end
|
||||
@ -541,7 +540,7 @@ mcl_minecarts.place_minecart = function(itemstack, pointed_thing, placer)
|
||||
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
|
||||
|
||||
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
|
||||
if false then
|
||||
minetest.register_craft({
|
||||
output = "mcl_minecarts:furnace_minecart",
|
||||
recipe = {
|
||||
{"mcl_furnaces:furnace"},
|
||||
{"mcl_minecarts:minecart"},
|
||||
},
|
||||
})
|
||||
--[[minetest.register_craft({
|
||||
output = "mcl_minecarts:furnace_minecart",
|
||||
recipe = {
|
||||
{"mcl_furnaces:furnace"},
|
||||
{"mcl_minecarts:minecart"},
|
||||
},
|
||||
})
|
||||
|
||||
minetest.register_craft({
|
||||
output = "mcl_minecarts:hopper_minecart",
|
||||
recipe = {
|
||||
{"mcl_hoppers:hopper"},
|
||||
{"mcl_minecarts:minecart"},
|
||||
},
|
||||
})
|
||||
minetest.register_craft({
|
||||
output = "mcl_minecarts:hopper_minecart",
|
||||
recipe = {
|
||||
{"mcl_hoppers:hopper"},
|
||||
{"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
|
||||
mcl_wip.register_wip_item("mcl_minecarts:chest_minecart")
|
||||
|
@ -1,7 +1,7 @@
|
||||
local S = minetest.get_translator("mcl_minecarts")
|
||||
|
||||
-- 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}
|
||||
if creative == false then
|
||||
groups.not_in_creative_inventory = 1
|
||||
|
@ -11,133 +11,111 @@ local minetest_get_objects_inside_radius = minetest.get_objects_inside_radius
|
||||
local minetest_get_modpath = minetest.get_modpath
|
||||
local minetest_registered_nodes = minetest.registered_nodes
|
||||
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_line_of_sight = minetest.line_of_sight
|
||||
local minetest_after = minetest.after
|
||||
local minetest_sound_play = minetest.sound_play
|
||||
local minetest_add_particlespawner = minetest.add_particlespawner
|
||||
local minetest_registered_items = minetest.registered_items
|
||||
local minetest_set_node = minetest.set_node
|
||||
--local minetest_line_of_sight = minetest.line_of_sight
|
||||
--local minetest_after = minetest.after
|
||||
--local minetest_sound_play = minetest.sound_play
|
||||
--local minetest_add_particlespawner = minetest.add_particlespawner
|
||||
--local minetest_registered_items = minetest.registered_items
|
||||
--local minetest_set_node = minetest.set_node
|
||||
local minetest_add_item = minetest.add_item
|
||||
local minetest_get_craft_result = minetest.get_craft_result
|
||||
local minetest_find_path = minetest.find_path
|
||||
local minetest_is_protected = minetest.is_protected
|
||||
--local minetest_get_craft_result = minetest.get_craft_result
|
||||
--local minetest_find_path = minetest.find_path
|
||||
local minetest_is_creative_enabled = minetest.is_creative_enabled
|
||||
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_raycast = minetest.raycast
|
||||
local minetest_get_us_time = minetest.get_us_time
|
||||
--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_raycast = minetest.raycast
|
||||
--local minetest_get_us_time = minetest.get_us_time
|
||||
local minetest_add_entity = minetest.add_entity
|
||||
local minetest_get_natural_light = minetest.get_natural_light
|
||||
local minetest_get_node_or_nil = minetest.get_node_or_nil
|
||||
--local minetest_get_natural_light = minetest.get_natural_light
|
||||
--local minetest_get_node_or_nil = minetest.get_node_or_nil
|
||||
|
||||
-- localize math functions
|
||||
local math_pi = math.pi
|
||||
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
|
||||
local math = math
|
||||
|
||||
-- localize vector functions
|
||||
local vector_new = vector.new
|
||||
local vector_add = vector.add
|
||||
local vector_length = vector.length
|
||||
local vector_direction = vector.direction
|
||||
local vector_normalize = vector.normalize
|
||||
local vector_multiply = vector.multiply
|
||||
local vector_divide = vector.divide
|
||||
local vector = vector
|
||||
|
||||
local string = string
|
||||
|
||||
-- mob constants
|
||||
local BREED_TIME = 30
|
||||
local BREED_TIME_AGAIN = 300
|
||||
local CHILD_GROW_TIME = 60*20
|
||||
local DEATH_DELAY = 0.5
|
||||
--local BREED_TIME = 30
|
||||
--local BREED_TIME_AGAIN = 300
|
||||
--local CHILD_GROW_TIME = 60*20
|
||||
--local DEATH_DELAY = 0.5
|
||||
local DEFAULT_FALL_SPEED = -10
|
||||
local FLOP_HEIGHT = 5.0
|
||||
local FLOP_HOR_SPEED = 1.5
|
||||
--local FLOP_HEIGHT = 5.0
|
||||
--local FLOP_HOR_SPEED = 1.5
|
||||
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.passive = 10
|
||||
MOB_CAP.ambient = 15
|
||||
MOB_CAP.water = 15
|
||||
]]
|
||||
|
||||
-- Load main settings
|
||||
local damage_enabled = minetest_settings:get_bool("enable_damage")
|
||||
local disable_blood = minetest_settings:get_bool("mobs_disable_blood")
|
||||
local mobs_drop_items = minetest_settings:get_bool("mobs_drop_items") ~= false
|
||||
local mobs_griefing = minetest_settings:get_bool("mobs_griefing") ~= false
|
||||
local spawn_protected = minetest_settings:get_bool("mobs_spawn_protected") ~= false
|
||||
local remove_far = true
|
||||
--local damage_enabled = minetest_settings:get_bool("enable_damage")
|
||||
--local disable_blood = minetest_settings:get_bool("mobs_disable_blood")
|
||||
--local mobs_drop_items = minetest_settings:get_bool("mobs_drop_items") ~= false
|
||||
--local mobs_griefing = minetest_settings:get_bool("mobs_griefing") ~= false
|
||||
--local spawn_protected = minetest_settings:get_bool("mobs_spawn_protected") ~= false
|
||||
--local remove_far = true
|
||||
local difficulty = tonumber(minetest_settings:get("mob_difficulty")) or 1.0
|
||||
local show_health = false
|
||||
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 show_health = false
|
||||
--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)
|
||||
|
||||
-- pathfinding settings
|
||||
local enable_pathfinding = true
|
||||
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 enable_pathfinding = true
|
||||
--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
|
||||
|
||||
-- default nodes
|
||||
local node_ice = "mcl_core:ice"
|
||||
local node_snowblock = "mcl_core:snowblock"
|
||||
local node_snow = "mcl_core:snow"
|
||||
--local node_ice = "mcl_core:ice"
|
||||
--local node_snowblock = "mcl_core:snowblock"
|
||||
--local node_snow = "mcl_core:snow"
|
||||
mobs.fallback_node = minetest.registered_aliases["mapgen_dirt"] or "mcl_core:dirt"
|
||||
|
||||
local mod_weather = minetest_get_modpath("mcl_weather") ~= nil
|
||||
local mod_explosions = minetest_get_modpath("mcl_explosions") ~= nil
|
||||
local mod_mobspawners = minetest_get_modpath("mcl_mobspawners") ~= nil
|
||||
local mod_hunger = minetest_get_modpath("mcl_hunger") ~= nil
|
||||
local mod_worlds = minetest_get_modpath("mcl_worlds") ~= nil
|
||||
local mod_armor = minetest_get_modpath("mcl_armor") ~= nil
|
||||
local mod_experience = minetest_get_modpath("mcl_experience") ~= nil
|
||||
--local mod_weather = minetest_get_modpath("mcl_weather")
|
||||
--local mod_explosions = minetest_get_modpath("mcl_explosions")
|
||||
local mod_mobspawners = minetest_get_modpath("mcl_mobspawners")
|
||||
--local mod_hunger = minetest_get_modpath("mcl_hunger")
|
||||
--local mod_worlds = minetest_get_modpath("mcl_worlds")
|
||||
--local mod_armor = minetest_get_modpath("mcl_armor")
|
||||
--local mod_experience = minetest_get_modpath("mcl_experience")
|
||||
|
||||
|
||||
-- random locals I found
|
||||
local los_switcher = false
|
||||
local height_switcher = false
|
||||
--local los_switcher = false
|
||||
--local height_switcher = false
|
||||
|
||||
-- Get translator
|
||||
local S = minetest.get_translator("mcl_mobs")
|
||||
|
||||
-- CMI support check
|
||||
local use_cmi = minetest.global_exists("cmi")
|
||||
|
||||
|
||||
-- Invisibility mod check
|
||||
mobs.invis = {}
|
||||
if minetest.global_exists("invisibility") then
|
||||
mobs.invis = invisibility
|
||||
end
|
||||
|
||||
--local use_cmi = minetest.global_exists("cmi")
|
||||
|
||||
-- creative check
|
||||
function mobs.is_creative(name)
|
||||
return minetest_is_creative_enabled(name)
|
||||
end
|
||||
|
||||
|
||||
local atan = function(x)
|
||||
--[[local function atan(x)
|
||||
if not x or x ~= x then
|
||||
return 0
|
||||
else
|
||||
return math_atan(x)
|
||||
return math.atan(x)
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
|
||||
end]]
|
||||
|
||||
-- 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
|
||||
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
|
||||
return default
|
||||
else
|
||||
return math_max(min, value * difficulty)
|
||||
return math.max(min, value * difficulty)
|
||||
end
|
||||
end
|
||||
|
||||
@ -366,15 +344,11 @@ function mobs:register_mob(name, def)
|
||||
random_sound_timer_min = 3,
|
||||
random_sound_timer_max = 10,
|
||||
|
||||
|
||||
--head code variables
|
||||
--defaults are for the cow's default
|
||||
--because I don't know what else to set them
|
||||
--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
|
||||
|
||||
--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_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)
|
||||
end,
|
||||
|
||||
@ -556,10 +530,10 @@ function mobs:register_arrow(name, def)
|
||||
and def.tail_texture then
|
||||
|
||||
--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
|
||||
pos_adjustment = vector_divide(pos_adjustment, divider)
|
||||
local new_pos = vector_add(pos, pos_adjustment)
|
||||
pos_adjustment = vector.divide(pos_adjustment, divider)
|
||||
local new_pos = vector.add(pos, pos_adjustment)
|
||||
minetest.add_particle({
|
||||
pos = new_pos,
|
||||
velocity = {x = 0, y = 0, z = 0},
|
||||
@ -693,12 +667,12 @@ function mobs:register_egg(mob, desc, background, addegg, no_creative)
|
||||
|
||||
if pos
|
||||
--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 privs = minetest.get_player_privs(name)
|
||||
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)
|
||||
return itemstack
|
||||
end
|
||||
@ -743,7 +717,7 @@ function mobs:register_egg(mob, desc, background, addegg, no_creative)
|
||||
nametag = string.sub(nametag, 1, MAX_MOB_NAME_LENGTH)
|
||||
end
|
||||
ent.nametag = nametag
|
||||
update_tag(ent)
|
||||
--update_tag(ent)
|
||||
end
|
||||
|
||||
-- if not in creative then take item
|
||||
|
@ -1,12 +1,8 @@
|
||||
local math_random = math.random
|
||||
local math_pi = math.pi
|
||||
local math_floor = math.floor
|
||||
local math_round = math.round
|
||||
local math = math
|
||||
local vector = vector
|
||||
local string = string
|
||||
|
||||
local vector_multiply = vector.multiply
|
||||
local vector_add = vector.add
|
||||
local vector_new = vector.new
|
||||
local vector_distance = vector.distance
|
||||
local tonumber = tonumber
|
||||
|
||||
local minetest_yaw_to_dir = minetest.yaw_to_dir
|
||||
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 THIRTY_SECONDTH_PI = DOUBLE_PI * 0.03125
|
||||
|
||||
|
||||
--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
|
||||
if self.yaw > DOUBLE_PI then
|
||||
self.yaw = self.yaw - DOUBLE_PI
|
||||
@ -28,46 +23,45 @@ end
|
||||
|
||||
--a simple helper function for rounding
|
||||
--http://lua-users.org/wiki/SimpleRound
|
||||
function round2(num, numDecimalPlaces)
|
||||
local function round2(num, numDecimalPlaces)
|
||||
return tonumber(string.format("%." .. (numDecimalPlaces or 0) .. "f", num))
|
||||
end
|
||||
|
||||
|
||||
--[[
|
||||
_ _
|
||||
_ _
|
||||
| | | |
|
||||
| | __ _ _ __ __| |
|
||||
| | / _` | '_ \ / _` |
|
||||
| | / _` | '_ \ / _` |
|
||||
| |___| (_| | | | | (_| |
|
||||
\_____/\__,_|_| |_|\__,_|
|
||||
]]--
|
||||
|
||||
--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
|
||||
if self.object:get_velocity().y ~= 0 then
|
||||
return false
|
||||
end
|
||||
|
||||
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 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 - self.fear_height, z = pos.z + dir.z})
|
||||
|
||||
return free_fall
|
||||
end
|
||||
|
||||
|
||||
-- state switching logic (stand, walk, run, attacks)
|
||||
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
|
||||
--doing random walking for mobs if all states are not met
|
||||
@ -93,8 +87,8 @@ local land_state_switch = function(self, dtime)
|
||||
end
|
||||
|
||||
--ignore everything else if following
|
||||
if mobs.check_following(self) and
|
||||
(not self.breed_lookout_timer or (self.breed_lookout_timer and self.breed_lookout_timer == 0)) 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_timer or (self.breed_timer and self.breed_timer == 0)) then
|
||||
self.state = "follow"
|
||||
return
|
||||
@ -120,7 +114,7 @@ local land_state_switch = function(self, dtime)
|
||||
end
|
||||
|
||||
-- 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
|
||||
print(self.breed_timer)
|
||||
@ -136,7 +130,6 @@ local land_state_execution = function(self,dtime)
|
||||
if not self.object:get_properties() then
|
||||
return
|
||||
end
|
||||
|
||||
|
||||
--timer to time out looking for mate
|
||||
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
|
||||
--lua is acting really weird so we have to help it
|
||||
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)
|
||||
end
|
||||
else
|
||||
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
|
||||
@ -206,15 +199,13 @@ local land_state_execution = function(self,dtime)
|
||||
end
|
||||
|
||||
mobs.lock_yaw(self)
|
||||
elseif self.state == "follow" then
|
||||
|
||||
elseif self.state == "follow" then
|
||||
--always look at players
|
||||
mobs.set_yaw_while_following(self)
|
||||
|
||||
--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())
|
||||
|
||||
--don't push the player if too close
|
||||
--don't spin around randomly
|
||||
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()
|
||||
|
||||
--set the mob into a random direction
|
||||
self.yaw = (math_random() * (math.pi * 2))
|
||||
self.yaw = (math.random() * (math.pi * 2))
|
||||
end
|
||||
|
||||
--do animation
|
||||
@ -253,15 +244,13 @@ local land_state_execution = function(self,dtime)
|
||||
local node_in_front_of = mobs.jump_check(self)
|
||||
|
||||
if node_in_front_of == 1 then
|
||||
|
||||
mobs.jump(self)
|
||||
|
||||
--turn if on the edge of cliff
|
||||
--(this is written like this because unlike
|
||||
--jump_check which simply tells the mob to jump
|
||||
--this requires a mob to turn, removing the
|
||||
--ease of a full implementation for it in a single
|
||||
--function)
|
||||
--turn if on the edge of cliff
|
||||
--(this is written like this because unlike
|
||||
--jump_check which simply tells the mob to jump
|
||||
--this requires a mob to turn, removing the
|
||||
--ease of a full implementation for it in a single
|
||||
--function)
|
||||
elseif node_in_front_of == 2 or (self.fear_height ~= 0 and cliff_check(self,dtime)) then
|
||||
--turn 45 degrees if so
|
||||
quick_rotate(self,dtime)
|
||||
@ -292,9 +281,7 @@ local land_state_execution = function(self,dtime)
|
||||
local node_in_front_of = mobs.jump_check(self)
|
||||
|
||||
if node_in_front_of == 1 then
|
||||
|
||||
mobs.jump(self)
|
||||
|
||||
--turn if on the edge of cliff
|
||||
--(this is written like this because unlike
|
||||
--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)
|
||||
|
||||
--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")
|
||||
if self.special_breed_timer == 0 then
|
||||
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!
|
||||
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")
|
||||
|
||||
@ -375,14 +362,13 @@ local land_state_execution = function(self,dtime)
|
||||
mobs.set_velocity(self,0)
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
end
|
||||
if float_now then
|
||||
mobs.float(self)
|
||||
else
|
||||
local acceleration = self.object:get_acceleration()
|
||||
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
|
||||
@ -391,10 +377,10 @@ end
|
||||
|
||||
|
||||
--[[
|
||||
_____ _
|
||||
/ ___| (_)
|
||||
\ `--.__ ___ _ __ ___
|
||||
`--. \ \ /\ / / | '_ ` _ \
|
||||
_____ _
|
||||
/ ___| (_)
|
||||
\ `--.__ ___ _ __ ___
|
||||
`--. \ \ /\ / / | '_ ` _ \
|
||||
/\__/ /\ V V /| | | | | | |
|
||||
\____/ \_/\_/ |_|_| |_| |_|
|
||||
]]--
|
||||
@ -404,7 +390,7 @@ end
|
||||
-- state switching logic (stand, walk, run, attacks)
|
||||
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
|
||||
if self.state_timer <= 0 then
|
||||
self.state_timer = math.random(4,10) + math.random()
|
||||
@ -414,41 +400,40 @@ end
|
||||
|
||||
|
||||
--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()
|
||||
pos.y = pos.y + 0.1
|
||||
local dir = minetest_yaw_to_dir(self.yaw)
|
||||
local pos = self.object:get_pos()
|
||||
pos.y = pos.y + 0.1
|
||||
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
|
||||
|
||||
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
|
||||
|
||||
return(green_flag_1)
|
||||
return green_flag_1
|
||||
end
|
||||
|
||||
--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
|
||||
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
|
||||
elseif not inside_swim_node and self.object:get_acceleration().y == 0 then
|
||||
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
|
||||
|
||||
|
||||
local random_pitch_multiplier = {-1,1}
|
||||
-- states are executed here
|
||||
local swim_state_execution = function(self,dtime)
|
||||
local function swim_state_execution(self, dtime)
|
||||
|
||||
local pos = self.object:get_pos()
|
||||
|
||||
@ -465,7 +450,7 @@ local swim_state_execution = function(self,dtime)
|
||||
end
|
||||
|
||||
--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
|
||||
if inside_swim_node then
|
||||
@ -482,22 +467,17 @@ local swim_state_execution = function(self,dtime)
|
||||
end
|
||||
|
||||
mobs.lock_yaw(self)
|
||||
|
||||
elseif self.state == "swim" then
|
||||
|
||||
self.walk_timer = self.walk_timer - dtime
|
||||
|
||||
--reset the walk timer
|
||||
if self.walk_timer <= 0 then
|
||||
|
||||
--re-randomize the walk timer
|
||||
self.walk_timer = math.random(1,6) + math.random()
|
||||
|
||||
--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
|
||||
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
|
||||
|
||||
--do animation
|
||||
@ -535,20 +515,20 @@ end
|
||||
|
||||
|
||||
--[[
|
||||
______ _
|
||||
| ___| |
|
||||
| |_ | |_ _
|
||||
______ _
|
||||
| ___| |
|
||||
| |_ | |_ _
|
||||
| _| | | | | |
|
||||
| | | | |_| |
|
||||
\_| |_|\__, |
|
||||
__/ |
|
||||
|___/
|
||||
__/ |
|
||||
|___/
|
||||
]]--
|
||||
|
||||
-- state switching logic (stand, walk, run, attacks)
|
||||
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
|
||||
self.state = "attack"
|
||||
@ -564,41 +544,41 @@ end
|
||||
|
||||
|
||||
--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()
|
||||
pos.y = pos.y + 0.1
|
||||
local dir = minetest_yaw_to_dir(self.yaw)
|
||||
local pos = self.object:get_pos()
|
||||
pos.y = pos.y + 0.1
|
||||
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
|
||||
|
||||
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
|
||||
|
||||
return(green_flag_1)
|
||||
return green_flag_1
|
||||
end
|
||||
|
||||
--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
|
||||
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
|
||||
elseif not inside_fly_node and self.object:get_acceleration().y == 0 then
|
||||
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
|
||||
|
||||
|
||||
local random_pitch_multiplier = {-1,1}
|
||||
-- states are executed here
|
||||
local fly_state_execution = function(self,dtime)
|
||||
local function fly_state_execution(self, dtime)
|
||||
local pos = self.object:get_pos()
|
||||
pos.y = pos.y + 0.1
|
||||
local current_node = minetest_get_node(pos).name
|
||||
@ -635,15 +615,13 @@ local fly_state_execution = function(self,dtime)
|
||||
|
||||
--reset the walk timer
|
||||
if self.walk_timer <= 0 then
|
||||
|
||||
--re-randomize the walk timer
|
||||
self.walk_timer = math.random(1,6) + math.random()
|
||||
|
||||
--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
|
||||
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
|
||||
|
||||
--do animation
|
||||
@ -663,9 +641,7 @@ local fly_state_execution = function(self,dtime)
|
||||
|
||||
--enable rotation locking
|
||||
mobs.movement_rotation_lock(self)
|
||||
|
||||
elseif self.state == "attack" then
|
||||
|
||||
--execute mob attack type
|
||||
--if self.attack_type == "explode" then
|
||||
|
||||
@ -697,40 +673,39 @@ end
|
||||
|
||||
|
||||
--[[
|
||||
___
|
||||
|_ |
|
||||
| |_ _ _ __ ___ _ __
|
||||
| | | | | '_ ` _ \| '_ \
|
||||
___
|
||||
|_ |
|
||||
| |_ _ _ __ ___ _ __
|
||||
| | | | | '_ ` _ \| '_ \
|
||||
/\__/ / |_| | | | | | | |_) |
|
||||
\____/ \__,_|_| |_| |_| .__/
|
||||
| |
|
||||
|_|
|
||||
\____/ \__,_|_| |_| |_| .__/
|
||||
| |
|
||||
|_|
|
||||
]]--
|
||||
|
||||
|
||||
--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()
|
||||
pos.y = pos.y + 0.1
|
||||
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
|
||||
|
||||
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
|
||||
|
||||
return(green_flag_1)
|
||||
end
|
||||
return green_flag_1
|
||||
end]]
|
||||
|
||||
-- state switching logic (stand, jump, run, attacks)
|
||||
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
|
||||
if self.state_timer <= 0 then
|
||||
self.state_timer = math.random(4,10) + math.random()
|
||||
@ -739,8 +714,8 @@ local jump_state_switch = function(self, dtime)
|
||||
end
|
||||
|
||||
-- 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 collisionbox = self.object:get_properties().collisionbox
|
||||
--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()
|
||||
|
||||
--set the mob into a random direction
|
||||
self.yaw = (math_random() * (math.pi * 2))
|
||||
self.yaw = (math.random() * (math.pi * 2))
|
||||
end
|
||||
|
||||
--do animation
|
||||
@ -793,15 +768,10 @@ local jump_state_execution = function(self,dtime)
|
||||
mobs.jump_move(self,self.walk_velocity)
|
||||
|
||||
elseif self.state == "run" then
|
||||
|
||||
print("run")
|
||||
|
||||
elseif self.state == "attack" then
|
||||
|
||||
print("attack")
|
||||
|
||||
end
|
||||
|
||||
end
|
||||
if float_now then
|
||||
mobs.float(self)
|
||||
end
|
||||
@ -811,18 +781,18 @@ end
|
||||
|
||||
|
||||
--[[
|
||||
___ ___ _ _ _
|
||||
| \/ | (_) | | (_)
|
||||
| . . | __ _ _ _ __ | | ___ __ _ _ ___
|
||||
___ ___ _ _ _
|
||||
| \/ | (_) | | (_)
|
||||
| . . | __ _ _ _ __ | | ___ __ _ _ ___
|
||||
| |\/| |/ _` | | '_ \ | | / _ \ / _` | |/ __|
|
||||
| | | | (_| | | | | | | |___| (_) | (_| | | (__
|
||||
| | | | (_| | | | | | | |___| (_) | (_| | | (__
|
||||
\_| |_/\__,_|_|_| |_| \_____/\___/ \__, |_|\___|
|
||||
__/ |
|
||||
|___/
|
||||
__/ |
|
||||
|___/
|
||||
]]--
|
||||
|
||||
--the main loop
|
||||
mobs.mob_step = function(self, dtime)
|
||||
function mobs.mob_step(self, dtime)
|
||||
|
||||
--do not continue if non-existent
|
||||
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
|
||||
|
||||
--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")
|
||||
--fix double death sound
|
||||
if self.health > 0 then
|
||||
mobs.play_sound(self,"damage")
|
||||
end
|
||||
end
|
||||
end
|
||||
self.old_health = self.health
|
||||
|
||||
--do death logic (animation, poof, explosion, etc)
|
||||
@ -916,7 +886,6 @@ mobs.mob_step = function(self, dtime)
|
||||
|
||||
elseif self.breath < self.breath_max then
|
||||
self.breath = self.breath + dtime
|
||||
|
||||
--clean timer reset
|
||||
if self.breath > self.breath_max then
|
||||
self.breath = self.breath_max
|
||||
@ -948,10 +917,6 @@ mobs.mob_step = function(self, dtime)
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
--baby grows up
|
||||
if self.baby then
|
||||
--print(self.grow_up_timer)
|
||||
@ -968,8 +933,6 @@ mobs.mob_step = function(self, dtime)
|
||||
mobs.baby_grow_up(self)
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
|
||||
--do custom mob instructions
|
||||
if self.do_custom then
|
||||
@ -1015,7 +978,7 @@ mobs.mob_step = function(self, dtime)
|
||||
self.memory = self.memory - dtime
|
||||
--get if memory player is within viewing range
|
||||
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
|
||||
self.memory = 0
|
||||
end
|
||||
@ -1090,7 +1053,7 @@ mobs.mob_step = function(self, dtime)
|
||||
--jump only (like slimes)
|
||||
if self.jump_only then
|
||||
jump_state_switch(self, dtime)
|
||||
jump_state_execution(self, dtime)
|
||||
jump_state_execution(self, dtime)
|
||||
--swimming
|
||||
elseif self.swim then
|
||||
swim_state_switch(self, dtime)
|
||||
@ -1124,28 +1087,22 @@ mobs.mob_step = function(self, dtime)
|
||||
--overrides absolutely everything
|
||||
--mobs get stuck in cobwebs like players
|
||||
if not self.ignores_cobwebs then
|
||||
|
||||
local pos = self.object:get_pos()
|
||||
local node = pos and minetest_get_node(pos).name
|
||||
|
||||
if node == "mcl_core:cobweb" then
|
||||
|
||||
--fight the rest of the api
|
||||
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
|
||||
|
||||
mobs.stick_in_cobweb(self)
|
||||
|
||||
self.was_stuck_in_cobweb = true
|
||||
|
||||
else
|
||||
--do not override other functions
|
||||
if self.was_stuck_in_cobweb == true then
|
||||
--return the mob back to normal
|
||||
self.was_stuck_in_cobweb = nil
|
||||
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
|
||||
|
@ -1,7 +1,7 @@
|
||||
local math_pi = math.pi
|
||||
local math_floor = math.floor
|
||||
local math_random = math.random
|
||||
local HALF_PI = math_pi/2
|
||||
local math = math
|
||||
local vector = vector
|
||||
|
||||
local HALF_PI = math.pi/2
|
||||
|
||||
|
||||
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,
|
||||
0, self.animation[anim .. "_loop"] ~= false)
|
||||
|
||||
|
||||
self.current_animation = anim
|
||||
self.current_animation = anim
|
||||
end
|
||||
|
||||
|
||||
@ -65,14 +64,14 @@ mobs.death_effect = function(pos, yaw, collisionbox, rotate)
|
||||
max = { x = 0.5, y = 0.5, z = 0.5 }
|
||||
end
|
||||
if rotate then
|
||||
min = vector.rotate(min, {x=0, y=yaw, z=math_pi/2})
|
||||
max = vector.rotate(max, {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})
|
||||
min, max = vector.sort(min, max)
|
||||
min = vector.multiply(min, 0.5)
|
||||
max = vector.multiply(max, 0.5)
|
||||
end
|
||||
|
||||
minetest_add_particlespawner({
|
||||
minetest.add_particlespawner({
|
||||
amount = 50,
|
||||
time = 0.001,
|
||||
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",
|
||||
})
|
||||
|
||||
minetest_sound_play("mcl_mobs_mob_poof", {
|
||||
minetest.sound_play("mcl_mobs_mob_poof", {
|
||||
pos = pos,
|
||||
gain = 1.0,
|
||||
max_hear_distance = 8,
|
||||
@ -99,7 +98,6 @@ end
|
||||
--this allows auto facedir rotation while making it so mobs
|
||||
--don't look like wet noodles flopping around
|
||||
mobs.movement_rotation_lock = function(self)
|
||||
|
||||
local current_engine_yaw = self.object:get_yaw()
|
||||
local current_lua_yaw = self.yaw
|
||||
|
||||
@ -159,7 +157,7 @@ local calculate_pitch = function(self)
|
||||
return false
|
||||
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
|
||||
|
||||
--this is a helper function used to make mobs pitch rotation dynamically flow when flying/swimming
|
||||
|
@ -1,11 +1,11 @@
|
||||
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_multiply = vector.multiply
|
||||
local math_random = math.random
|
||||
|
||||
--[[
|
||||
_ _ _ _
|
||||
_ _ _ _
|
||||
| | | | | | | |
|
||||
| | | | __ _ _ __ __| | | |
|
||||
| | | | / _` | '_ \ / _` | | |
|
||||
@ -16,14 +16,14 @@ local math_random = math.random
|
||||
|
||||
|
||||
--[[
|
||||
_____ _ _
|
||||
| ___| | | | |
|
||||
| |____ ___ __ | | ___ __| | ___
|
||||
_____ _ _
|
||||
| ___| | | | |
|
||||
| |____ ___ __ | | ___ __| | ___
|
||||
| __\ \/ / '_ \| |/ _ \ / _` |/ _ \
|
||||
| |___> <| |_) | | (_) | (_| | __/
|
||||
\____/_/\_\ .__/|_|\___/ \__,_|\___|
|
||||
| |
|
||||
|_|
|
||||
| |
|
||||
|_|
|
||||
]]--
|
||||
|
||||
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
|
||||
mobs.jump(self)
|
||||
end
|
||||
|
||||
|
||||
--do biggening explosion thing
|
||||
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)
|
||||
|
||||
--this needs an exception
|
||||
if self.attacking == nil or not self.attacking:is_player() then
|
||||
self.attacking = nil
|
||||
@ -187,14 +185,14 @@ end
|
||||
|
||||
|
||||
--[[
|
||||
______ _ _ _ _
|
||||
| ___ \ (_) | | (_) |
|
||||
| |_/ / __ ___ _ ___ ___| |_ _| | ___
|
||||
______ _ _ _ _
|
||||
| ___ \ (_) | | (_) |
|
||||
| |_/ / __ ___ _ ___ ___| |_ _| | ___
|
||||
| __/ '__/ _ \| |/ _ \/ __| __| | |/ _ \
|
||||
| | | | | (_) | | __/ (__| |_| | | __/
|
||||
\_| |_| \___/| |\___|\___|\__|_|_|\___|
|
||||
_/ |
|
||||
|__/
|
||||
_/ |
|
||||
|__/
|
||||
]]--
|
||||
|
||||
|
||||
@ -255,40 +253,39 @@ end
|
||||
|
||||
|
||||
--[[
|
||||
_ ______ _ _
|
||||
_ ______ _ _
|
||||
| | | ___| | | |
|
||||
| | | |_ | |_ _ | |
|
||||
| | | _| | | | | | | |
|
||||
|_| | | | | |_| | |_|
|
||||
(_) \_| |_|\__, | (_)
|
||||
__/ |
|
||||
|___/
|
||||
__/ |
|
||||
|___/
|
||||
]]--
|
||||
|
||||
|
||||
|
||||
|
||||
--[[
|
||||
______ _ _ _ _
|
||||
| ___ \ (_) | | (_) |
|
||||
| |_/ / __ ___ _ ___ ___| |_ _| | ___
|
||||
______ _ _ _ _
|
||||
| ___ \ (_) | | (_) |
|
||||
| |_/ / __ ___ _ ___ ___| |_ _| | ___
|
||||
| __/ '__/ _ \| |/ _ \/ __| __| | |/ _ \
|
||||
| | | | | (_) | | __/ (__| |_| | | __/
|
||||
\_| |_| \___/| |\___|\___|\__|_|_|\___|
|
||||
_/ |
|
||||
|__/
|
||||
_/ |
|
||||
|__/
|
||||
]]--
|
||||
|
||||
local random_pitch_multiplier = {-1,1}
|
||||
|
||||
mobs.projectile_attack_fly = function(self, dtime)
|
||||
|
||||
--this needs an exception
|
||||
if self.attacking == nil or not self.attacking:is_player() then
|
||||
self.attacking = nil
|
||||
return
|
||||
end
|
||||
|
||||
|
||||
--this is specifically for random ghast movement
|
||||
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())
|
||||
|
||||
if distance_from_attacking >= self.reach then
|
||||
if distance_from_attacking >= self.reach then
|
||||
mobs.set_pitch_while_attacking(self)
|
||||
mobs.set_fly_velocity(self, self.run_velocity)
|
||||
mobs.set_mob_animation(self,"run")
|
||||
|
@ -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
|
||||
luaentity.physical_state = false
|
||||
object:set_properties({
|
||||
@ -12,7 +15,7 @@ local disable_physics = function(object, luaentity, ignore_check, reset_movement
|
||||
end
|
||||
|
||||
----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
|
||||
luaentity.physical_state = true
|
||||
object:set_properties({
|
||||
@ -272,7 +275,7 @@ local falling = function(self, pos)
|
||||
|
||||
self.object:set_acceleration({
|
||||
x = 0,
|
||||
y = -self.fall_speed / (math_max(1, v.y) ^ 2),
|
||||
y = -self.fall_speed / (math.max(1, v.y) ^ 2),
|
||||
z = 0
|
||||
})
|
||||
end
|
||||
@ -503,9 +506,9 @@ local follow_flop = function(self)
|
||||
if sdef and sdef.walkable then
|
||||
mob_sound(self, "flop")
|
||||
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,
|
||||
z = math_random(-FLOP_HOR_SPEED, FLOP_HOR_SPEED),
|
||||
z = math.random(-FLOP_HOR_SPEED, FLOP_HOR_SPEED),
|
||||
})
|
||||
end
|
||||
|
||||
@ -987,7 +990,7 @@ local check_for_death = function(self, cause, cmi_cause)
|
||||
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
|
||||
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
|
||||
@ -1361,7 +1364,7 @@ local do_attack = function(self, player)
|
||||
self.state = "attack"
|
||||
|
||||
-- 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)
|
||||
--end
|
||||
end
|
||||
@ -1396,7 +1399,7 @@ local mob_sound = function(self, soundname, is_opinion, fixed_pitch)
|
||||
pitch = base_pitch
|
||||
end
|
||||
-- randomize the pitch a bit
|
||||
pitch = pitch + math_random(-10, 10) * 0.005
|
||||
pitch = pitch + math.random(-10, 10) * 0.005
|
||||
end
|
||||
minetest_sound_play(sound, {
|
||||
object = self.object,
|
||||
@ -1699,7 +1702,7 @@ local do_env_damage = function(self)
|
||||
end
|
||||
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)
|
||||
if self.breath <= 0 then
|
||||
@ -2044,7 +2047,7 @@ local breed = function(self)
|
||||
|
||||
-- Give XP
|
||||
if mod_experience then
|
||||
mcl_experience.throw_experience(pos, math_random(1, 7))
|
||||
mcl_experience.throw_experience(pos, math.random(1, 7))
|
||||
end
|
||||
|
||||
-- custom breed function
|
||||
@ -2061,7 +2064,7 @@ local breed = function(self)
|
||||
|
||||
|
||||
-- Use texture of one of the parents
|
||||
local p = math_random(1, 2)
|
||||
local p = math.random(1, 2)
|
||||
if p == 1 then
|
||||
ent_c.base_texture = parent1.base_texture
|
||||
else
|
||||
@ -2091,7 +2094,7 @@ local replace = function(self, pos)
|
||||
or not self.replace_what
|
||||
or self.child == true
|
||||
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
|
||||
end
|
||||
|
||||
@ -2099,7 +2102,7 @@ local replace = function(self, pos)
|
||||
|
||||
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 ""
|
||||
with = self.replace_what[num][2] or ""
|
||||
@ -2163,7 +2166,7 @@ function do_states(self)
|
||||
|
||||
if self.state == "stand" then
|
||||
|
||||
if math_random(1, 4) == 1 then
|
||||
if math.random(1, 4) == 1 then
|
||||
|
||||
local lp = nil
|
||||
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
|
||||
else
|
||||
yaw = yaw + math_random(-0.5, 0.5)
|
||||
yaw = yaw + math.random(-0.5, 0.5)
|
||||
end
|
||||
|
||||
yaw = set_yaw(self, yaw, 8)
|
||||
@ -2204,7 +2207,7 @@ function do_states(self)
|
||||
|
||||
if self.walk_chance ~= 0
|
||||
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
|
||||
|
||||
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},
|
||||
{"group:solid"})
|
||||
|
||||
lp = #lp > 0 and lp[math_random(#lp)]
|
||||
lp = #lp > 0 and lp[math.random(#lp)]
|
||||
|
||||
-- did we find land?
|
||||
if lp then
|
||||
@ -2280,8 +2283,8 @@ function do_states(self)
|
||||
else
|
||||
|
||||
-- Randomly turn
|
||||
if math_random(1, 100) <= 30 then
|
||||
yaw = yaw + math_random(-0.5, 0.5)
|
||||
if math.random(1, 100) <= 30 then
|
||||
yaw = yaw + math.random(-0.5, 0.5)
|
||||
yaw = set_yaw(self, yaw, 8)
|
||||
end
|
||||
end
|
||||
@ -2289,9 +2292,9 @@ function do_states(self)
|
||||
yaw = set_yaw(self, yaw, 8)
|
||||
|
||||
-- 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)
|
||||
end
|
||||
|
||||
@ -2302,7 +2305,7 @@ function do_states(self)
|
||||
end
|
||||
if self.facing_fence == true
|
||||
or cliff_or_danger
|
||||
or math_random(1, 100) <= 30 then
|
||||
or math.random(1, 100) <= 30 then
|
||||
|
||||
set_velocity(self, 0)
|
||||
self.state = "stand"
|
||||
@ -2602,7 +2605,7 @@ function do_states(self)
|
||||
self.timer = 0
|
||||
|
||||
if self.double_melee_attack
|
||||
and math_random(1, 2) == 1 then
|
||||
and math.random(1, 2) == 1 then
|
||||
set_animation(self, "punch2")
|
||||
else
|
||||
set_animation(self, "punch")
|
||||
@ -2669,7 +2672,7 @@ function do_states(self)
|
||||
if self.shoot_interval
|
||||
and self.timer > self.shoot_interval
|
||||
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
|
||||
set_animation(self, "shoot")
|
||||
@ -2759,7 +2762,7 @@ end
|
||||
|
||||
|
||||
-- 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()
|
||||
|
||||
-- Name mob with nametag
|
||||
@ -2785,17 +2788,17 @@ local on_rightclick_prefix = function(self, clicker)
|
||||
return false
|
||||
end
|
||||
|
||||
local create_mob_on_rightclick = function(on_rightclick)
|
||||
--[[local function create_mob_on_rightclick(on_rightclick)
|
||||
return function(self, clicker)
|
||||
local stop = on_rightclick_prefix(self, clicker)
|
||||
if (not stop) and (on_rightclick) then
|
||||
on_rightclick(self, clicker)
|
||||
end
|
||||
end
|
||||
end
|
||||
end]]
|
||||
|
||||
-- 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
|
||||
yaw = 0
|
||||
@ -2805,7 +2808,7 @@ local set_yaw = function(self, yaw, delay, dtime)
|
||||
|
||||
if delay == 0 then
|
||||
if self.shaking and dtime then
|
||||
yaw = yaw + (math_random() * 2 - 1) * 5 * dtime
|
||||
yaw = yaw + (math.random() * 2 - 1) * 5 * dtime
|
||||
end
|
||||
self.yaw(yaw)
|
||||
update_roll(self)
|
||||
@ -2825,8 +2828,7 @@ function mobs:yaw(self, yaw, delay, dtime)
|
||||
end
|
||||
|
||||
|
||||
mob_step = function()
|
||||
|
||||
--mob_step = function()
|
||||
--if self.state == "die" then
|
||||
-- print("need custom die stop moving thing")
|
||||
-- return
|
||||
@ -2901,7 +2903,7 @@ mob_step = function()
|
||||
--end
|
||||
|
||||
-- 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)
|
||||
--end
|
||||
|
||||
@ -2934,11 +2936,11 @@ mob_step = function()
|
||||
|
||||
|
||||
--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)
|
||||
-- self.state = "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)
|
||||
-- end
|
||||
--end
|
||||
@ -2982,7 +2984,7 @@ mob_step = function()
|
||||
mcl_burning.extinguish(self.object)
|
||||
self.object:remove()
|
||||
elseif self.lifetimer <= 10 then
|
||||
if math_random(10) < 4 then
|
||||
if math.random(10) < 4 then
|
||||
self.despawn_immediately = true
|
||||
else
|
||||
self.lifetimer = 20
|
||||
@ -2991,4 +2993,4 @@ mob_step = function()
|
||||
end
|
||||
]]--
|
||||
|
||||
end
|
||||
--end
|
@ -1,14 +1,13 @@
|
||||
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
|
||||
mobs.check_following = function(self) -- returns true or false
|
||||
|
||||
--ignore
|
||||
if not self.follow then
|
||||
self.following_person = nil
|
||||
return(false)
|
||||
return false
|
||||
end
|
||||
|
||||
--hey look, this thing works for passive mobs too!
|
||||
@ -20,20 +19,20 @@ mobs.check_following = function(self) -- returns true or false
|
||||
--safety check
|
||||
if not stack then
|
||||
self.following_person = nil
|
||||
return(false)
|
||||
return false
|
||||
end
|
||||
|
||||
local item_name = stack:get_name()
|
||||
--all checks have passed, that guy has some good looking food
|
||||
if item_name == self.follow then
|
||||
self.following_person = follower
|
||||
return(true)
|
||||
return true
|
||||
end
|
||||
end
|
||||
|
||||
--everything failed
|
||||
self.following_person = nil
|
||||
return(false)
|
||||
return false
|
||||
end
|
||||
|
||||
--a function which attempts to make mobs enter
|
||||
@ -42,30 +41,30 @@ mobs.enter_breed_state = function(self,clicker)
|
||||
|
||||
--do not breed if baby
|
||||
if self.baby then
|
||||
return(false)
|
||||
return false
|
||||
end
|
||||
|
||||
--do not do anything if looking for mate or
|
||||
--if cooling off from breeding
|
||||
if self.breed_lookout_timer > 0 or self.breed_timer > 0 then
|
||||
return(false)
|
||||
return false
|
||||
end
|
||||
|
||||
--if this is caught, that means something has gone
|
||||
--seriously wrong
|
||||
if not clicker or not clicker:is_player() then
|
||||
return(false)
|
||||
return false
|
||||
end
|
||||
|
||||
local stack = clicker:get_wielded_item()
|
||||
--safety check
|
||||
if not stack then
|
||||
return(false)
|
||||
return false
|
||||
end
|
||||
|
||||
local item_name = stack:get_name()
|
||||
--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
|
||||
stack:take_item()
|
||||
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.bred = true
|
||||
mobs.play_sound_specific(self,"mobs_mc_animal_eat_generic")
|
||||
return(true)
|
||||
return true
|
||||
end
|
||||
|
||||
--everything failed
|
||||
return(false)
|
||||
return false
|
||||
end
|
||||
|
||||
|
||||
@ -96,23 +95,23 @@ mobs.look_for_mate = function(self)
|
||||
for _,mate in pairs(minetest_get_objects_inside_radius(pos1, radius)) do
|
||||
|
||||
--look for a breeding mate
|
||||
if mate and mate:get_luaentity()
|
||||
and mate:get_luaentity()._cmi_is_mob
|
||||
and mate:get_luaentity().name == self.name
|
||||
if mate and mate:get_luaentity()
|
||||
and mate:get_luaentity()._cmi_is_mob
|
||||
and mate:get_luaentity().name == self.name
|
||||
and mate:get_luaentity().breed_lookout_timer > 0
|
||||
and mate:get_luaentity() ~= self then
|
||||
|
||||
local pos2 = mate:get_pos()
|
||||
|
||||
local distance = vector_distance(pos1,pos2)
|
||||
local distance = vector.distance(pos1,pos2)
|
||||
|
||||
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
|
||||
--seethrough nodes being a blocker (like grass)
|
||||
if minetest_line_of_sight(
|
||||
vector_new(pos1.x, pos1.y, pos1.z),
|
||||
vector_new(pos2.x, pos2.y + mate:get_properties().eye_height, pos2.z)
|
||||
if minetest.line_of_sight(
|
||||
vector.new(pos1.x, pos1.y, pos1.z),
|
||||
vector.new(pos2.x, pos2.y + mate:get_properties().eye_height, pos2.z)
|
||||
) then
|
||||
mates_detected = mates_detected + 1
|
||||
mates_in_area[mate] = distance
|
||||
@ -141,9 +140,7 @@ mobs.look_for_mate = function(self)
|
||||
winner_mate = mate
|
||||
end
|
||||
end
|
||||
|
||||
return(winner_mate)
|
||||
|
||||
return winner_mate
|
||||
end
|
||||
|
||||
--make the baby grow up
|
||||
@ -160,14 +157,14 @@ mobs.make_baby_grow_faster = function(self,clicker)
|
||||
if clicker and clicker:is_player() then
|
||||
local stack = clicker:get_wielded_item()
|
||||
--safety check
|
||||
if not stack then
|
||||
return(false)
|
||||
if not stack then
|
||||
return false
|
||||
end
|
||||
|
||||
local item_name = stack:get_name()
|
||||
--all checks have passed, that guy has some good looking food
|
||||
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
|
||||
stack:take_item()
|
||||
@ -175,10 +172,8 @@ mobs.make_baby_grow_faster = function(self,clicker)
|
||||
end
|
||||
|
||||
mobs.play_sound_specific(self,"mobs_mc_animal_eat_generic")
|
||||
|
||||
return(true)
|
||||
return true
|
||||
end
|
||||
end
|
||||
|
||||
return(false)
|
||||
return false
|
||||
end
|
@ -8,10 +8,8 @@ local vector_direction = vector.direction
|
||||
local integer_test = {-1,1}
|
||||
|
||||
mobs.collision = function(self)
|
||||
|
||||
local pos = self.object:get_pos()
|
||||
|
||||
|
||||
if not self or not self.object or not self.object:get_luaentity() then
|
||||
return
|
||||
end
|
||||
@ -20,7 +18,7 @@ mobs.collision = function(self)
|
||||
local collisionbox = self.object:get_properties().collisionbox
|
||||
|
||||
pos.y = pos.y + collisionbox[2]
|
||||
|
||||
|
||||
local collision_boundary = collisionbox[4]
|
||||
|
||||
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
|
||||
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
|
||||
(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
|
||||
--stop infinite loop
|
||||
collision_count = collision_count + 1
|
||||
@ -52,7 +50,7 @@ mobs.collision = function(self)
|
||||
end
|
||||
|
||||
local pos2 = object:get_pos()
|
||||
|
||||
|
||||
local object_collisionbox = object:get_properties().collisionbox
|
||||
|
||||
pos2.y = pos2.y + object_collisionbox[2]
|
||||
@ -74,7 +72,7 @@ mobs.collision = function(self)
|
||||
local dir = vector.direction(pos,pos2)
|
||||
|
||||
dir.y = 0
|
||||
|
||||
|
||||
--eliminate mob being stuck in corners
|
||||
if dir.x == 0 and dir.z == 0 then
|
||||
--slightly adjust mob position to prevent equal length
|
||||
@ -84,7 +82,7 @@ mobs.collision = function(self)
|
||||
end
|
||||
|
||||
local velocity = dir
|
||||
|
||||
|
||||
--0.5 is the max force multiplier
|
||||
local force = 0.5 - (0.5 * distance / (collision_boundary + object_collision_boundary))
|
||||
|
||||
@ -104,11 +102,9 @@ mobs.collision = function(self)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
self.object:add_velocity(vel1)
|
||||
object:add_velocity(vel2)
|
||||
end
|
||||
|
||||
end
|
||||
end
|
||||
end
|
||||
@ -116,7 +112,6 @@ end
|
||||
|
||||
--this is used for arrow collisions
|
||||
mobs.arrow_hit = function(self, player)
|
||||
|
||||
player:punch(self.object, 1.0, {
|
||||
full_punch_interval = 1.0,
|
||||
damage_groups = {fleshy = self._damage}
|
||||
|
@ -1,5 +1,5 @@
|
||||
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_random = math.random
|
||||
@ -19,7 +19,7 @@ local item_drop = function(self, cooked, looting_level)
|
||||
return
|
||||
end
|
||||
|
||||
local obj, item, num
|
||||
local obj, item
|
||||
local pos = self.object:get_pos()
|
||||
|
||||
self.drops = self.drops or {} -- nil check
|
||||
@ -56,8 +56,11 @@ local item_drop = function(self, cooked, looting_level)
|
||||
-- cook items when true
|
||||
if cooked then
|
||||
|
||||
local output = minetest_get_craft_result({
|
||||
method = "cooking", width = 1, items = {item}})
|
||||
local output = minetest.get_craft_result({
|
||||
method = "cooking",
|
||||
width = 1,
|
||||
items = {item},
|
||||
})
|
||||
|
||||
if output and output.item and not output.item:is_empty() then
|
||||
item = output.item:get_name()
|
||||
@ -117,15 +120,10 @@ mobs.death_logic = function(self, dtime)
|
||||
|
||||
--the final POOF of a mob despawning
|
||||
if self.death_animation_timer >= 1.25 then
|
||||
|
||||
item_drop(self,false,1)
|
||||
|
||||
mobs.death_effect(self)
|
||||
|
||||
mcl_experience.throw_experience(self.object:get_pos(), math_random(self.xp_min, self.xp_max))
|
||||
|
||||
self.object:remove()
|
||||
|
||||
return
|
||||
end
|
||||
|
||||
|
@ -1,5 +1,5 @@
|
||||
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_get_node = minetest.get_node
|
||||
local minetest_get_item_group = minetest.get_item_group
|
||||
@ -18,19 +18,16 @@ local table_copy = table.copy
|
||||
local math_abs = math.abs
|
||||
|
||||
-- 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, {
|
||||
full_punch_interval = 1.0,
|
||||
damage_groups = {fleshy = damage},
|
||||
}, nil)
|
||||
|
||||
return false, true, {}
|
||||
end
|
||||
end]]
|
||||
|
||||
--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)
|
||||
|
||||
local pos1 = self.object:get_pos()
|
||||
local players_in_area = {}
|
||||
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
|
||||
--seethrough nodes being a blocker (like grass)
|
||||
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)
|
||||
) then
|
||||
players_detected = players_detected + 1
|
||||
@ -79,8 +76,7 @@ mobs.detect_closest_player_within_radius = function(self, line_of_sight, radius,
|
||||
winner_player = player
|
||||
end
|
||||
end
|
||||
|
||||
return(winner_player)
|
||||
return winner_player
|
||||
end
|
||||
|
||||
|
||||
@ -107,14 +103,13 @@ mobs.jump_check = function(self,dtime)
|
||||
|
||||
if green_flag_1 and green_flag_2 then
|
||||
--can jump over node
|
||||
return(1)
|
||||
elseif green_flag_1 and not green_flag_2 then
|
||||
return 1
|
||||
elseif green_flag_1 and not green_flag_2 then
|
||||
--wall in front of mob
|
||||
return(2)
|
||||
return 2
|
||||
end
|
||||
|
||||
--nothing to jump over
|
||||
return(0)
|
||||
return 0
|
||||
end
|
||||
|
||||
-- a helper function to quickly turn neutral passive mobs hostile
|
||||
@ -180,15 +175,10 @@ end
|
||||
-- check if within physical map limits (-30911 to 30927)
|
||||
-- within_limits, wmin, wmax = nil, -30913, 30928
|
||||
mobs.within_limits = function(pos, radius)
|
||||
local wmin, wmax
|
||||
if mcl_vars 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
|
||||
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
|
||||
return pos
|
||||
@ -231,12 +221,12 @@ mobs.check_for_player_within_area = function(self, radius)
|
||||
local distance = vector_distance(pos1,pos2)
|
||||
if distance < radius then
|
||||
--found a player
|
||||
return(true)
|
||||
return true
|
||||
end
|
||||
end
|
||||
end
|
||||
--did not find a player
|
||||
return(false)
|
||||
return false
|
||||
end
|
||||
|
||||
|
||||
@ -244,7 +234,7 @@ end
|
||||
mobs.get_2d_distance = function(pos1,pos2)
|
||||
pos1.y = 0
|
||||
pos2.y = 0
|
||||
return(vector_distance(pos1, pos2))
|
||||
return vector_distance(pos1, pos2)
|
||||
end
|
||||
|
||||
-- fall damage onto solid ground
|
||||
|
@ -1,112 +1,98 @@
|
||||
local vector_new = vector.new
|
||||
|
||||
local math = math
|
||||
local vector = vector
|
||||
|
||||
--converts yaw to degrees
|
||||
local degrees = function(yaw)
|
||||
return(yaw*180.0/math.pi)
|
||||
return yaw*180.0/math.pi
|
||||
end
|
||||
|
||||
|
||||
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()
|
||||
look_at.y = look_at.y + player:get_properties().eye_height
|
||||
local look_at = player:get_pos()
|
||||
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
|
||||
|
||||
|
||||
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
|
||||
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])
|
||||
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
|
@ -2,22 +2,19 @@ local minetest_after = minetest.after
|
||||
local minetest_sound_play = minetest.sound_play
|
||||
local minetest_dir_to_yaw = minetest.dir_to_yaw
|
||||
|
||||
local math_floor = math.floor
|
||||
local math_min = math.min
|
||||
local math_random = math.random
|
||||
|
||||
local vector_direction = vector.direction
|
||||
local vector_multiply = vector.multiply
|
||||
local math = math
|
||||
local vector = vector
|
||||
|
||||
local MAX_MOB_NAME_LENGTH = 30
|
||||
|
||||
local mod_hunger = minetest.get_modpath("mcl_hunger")
|
||||
|
||||
mobs.feed_tame = function(self)
|
||||
return nil
|
||||
end
|
||||
|
||||
-- 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()
|
||||
|
||||
-- Name mob with nametag
|
||||
@ -60,7 +57,6 @@ end
|
||||
|
||||
-- deal damage and effects when mob punched
|
||||
mobs.mob_punch = function(self, hitter, tflp, tool_capabilities, dir)
|
||||
|
||||
--don't do anything if the mob is already dead
|
||||
if self.health <= 0 then
|
||||
return
|
||||
@ -94,14 +90,13 @@ mobs.mob_punch = function(self, hitter, tflp, tool_capabilities, dir)
|
||||
pos2.y = 0
|
||||
|
||||
|
||||
local dir = vector_direction(pos2,pos1)
|
||||
local dir = vector.direction(pos2,pos1)
|
||||
|
||||
local yaw = minetest_dir_to_yaw(dir)
|
||||
|
||||
self.yaw = yaw
|
||||
end
|
||||
|
||||
|
||||
-- custom punch function
|
||||
if self.do_punch then
|
||||
-- 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
|
||||
if self.pause_timer > 0 then
|
||||
return
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
-- error checking when mod profiling is enabled
|
||||
if not tool_capabilities then
|
||||
minetest.log("warning", "[mobs_mc] Mod profiling enabled, damage not enabled")
|
||||
return
|
||||
end
|
||||
|
||||
|
||||
local is_player = hitter:is_player()
|
||||
|
||||
|
||||
-- punch interval
|
||||
local weapon = hitter:get_wielded_item()
|
||||
|
||||
local punch_interval = 1.4
|
||||
--local punch_interval = 1.4
|
||||
|
||||
-- exhaust attacker
|
||||
if mod_hunger and is_player then
|
||||
@ -139,7 +131,6 @@ mobs.mob_punch = function(self, hitter, tflp, tool_capabilities, dir)
|
||||
-- calculate mob damage
|
||||
local damage = 0
|
||||
local armor = self.object:get_armor_groups() or {}
|
||||
local tmp
|
||||
|
||||
--calculate damage groups
|
||||
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
|
||||
if damage <= -1 then
|
||||
self.health = self.health - math_floor(damage)
|
||||
self.health = self.health - math.floor(damage)
|
||||
return
|
||||
end
|
||||
|
||||
if tool_capabilities then
|
||||
punch_interval = tool_capabilities.full_punch_interval or 1.4
|
||||
end
|
||||
--if tool_capabilities then
|
||||
-- punch_interval = tool_capabilities.full_punch_interval or 1.4
|
||||
--end
|
||||
|
||||
-- add weapon wear manually
|
||||
-- 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 def = weapon:get_definition()
|
||||
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)
|
||||
hitter:set_wielded_item(weapon)
|
||||
end
|
||||
@ -224,7 +215,7 @@ mobs.mob_punch = function(self, hitter, tflp, tool_capabilities, dir)
|
||||
|
||||
-- knock back effect
|
||||
local velocity = self.object:get_velocity()
|
||||
|
||||
|
||||
--2d direction
|
||||
local pos1 = self.object:get_pos()
|
||||
pos1.y = 0
|
||||
@ -240,9 +231,8 @@ mobs.mob_punch = function(self, hitter, tflp, tool_capabilities, dir)
|
||||
up = 0
|
||||
end
|
||||
|
||||
|
||||
--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
|
||||
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
|
||||
if self.hostile then
|
||||
multiplier = multiplier + 2
|
||||
end
|
||||
|
||||
dir = vector_multiply(dir,multiplier)
|
||||
|
||||
end
|
||||
dir = vector.multiply(dir,multiplier)
|
||||
dir.y = up
|
||||
|
||||
--add the velocity
|
||||
self.object:add_velocity(dir)
|
||||
|
||||
end
|
||||
end
|
||||
|
||||
--do internal per mob projectile calculations
|
||||
mobs.shoot_projectile = function(self)
|
||||
|
||||
local pos1 = self.object:get_pos()
|
||||
--add mob 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
|
||||
|
||||
--get direction
|
||||
local dir = vector_direction(pos1,pos2)
|
||||
local dir = vector.direction(pos1,pos2)
|
||||
|
||||
--call internal shoot_arrow function
|
||||
self.shoot_arrow(self,pos1,dir)
|
||||
|
@ -1,9 +1,8 @@
|
||||
local minetest_add_particlespawner = minetest.add_particlespawner
|
||||
|
||||
mobs.death_effect = function(self)
|
||||
|
||||
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 min, max
|
||||
@ -33,7 +32,7 @@ end
|
||||
mobs.critical_effect = function(self)
|
||||
|
||||
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 min, max
|
||||
@ -62,9 +61,8 @@ end
|
||||
|
||||
--when feeding a mob
|
||||
mobs.feed_effect = function(self)
|
||||
|
||||
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 min, max
|
||||
@ -94,7 +92,7 @@ end
|
||||
--hearts when tamed
|
||||
mobs.tamed_effect = function(self)
|
||||
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 min, max
|
||||
@ -124,7 +122,7 @@ end
|
||||
--hearts when breeding
|
||||
mobs.breeding_effect = function(self)
|
||||
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 min, max
|
||||
|
@ -1,16 +1,10 @@
|
||||
local math_pi = math.pi
|
||||
local math_sin = math.sin
|
||||
local math_cos = math.cos
|
||||
local math_random = math.random
|
||||
local HALF_PI = math_pi / 2
|
||||
local DOUBLE_PI = math_pi * 2
|
||||
-- localize math functions
|
||||
local math = math
|
||||
local HALF_PI = math.pi / 2
|
||||
local DOUBLE_PI = math.pi * 2
|
||||
|
||||
-- localize vector functions
|
||||
local vector_new = vector.new
|
||||
local vector_length = vector.length
|
||||
local vector_multiply = vector.multiply
|
||||
local vector_distance = vector.distance
|
||||
local vector_normalize = vector.normalize
|
||||
local vector = vector
|
||||
|
||||
local minetest_yaw_to_dir = minetest.yaw_to_dir
|
||||
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_CLIMB_SPEED = 3
|
||||
|
||||
|
||||
mobs.stick_in_cobweb = function(self)
|
||||
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
|
||||
|
||||
local new_velocity_addition = vector.subtract(goal_velocity,current_velocity)
|
||||
|
||||
--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)
|
||||
end
|
||||
end
|
||||
@ -38,8 +31,11 @@ end
|
||||
--this is a generic float function
|
||||
mobs.float = function(self)
|
||||
|
||||
if self.object:get_acceleration().y ~= 0 then
|
||||
self.object:set_acceleration(vector_new(0,0,0))
|
||||
local acceleration = self.object:get_acceleration()
|
||||
if acceleration and acceleration.y ~= 0 then
|
||||
self.object:set_acceleration(vector.new(0,0,0))
|
||||
else
|
||||
return
|
||||
end
|
||||
|
||||
local current_velocity = self.object:get_velocity()
|
||||
@ -56,7 +52,7 @@ mobs.float = function(self)
|
||||
new_velocity_addition.z = 0
|
||||
|
||||
--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)
|
||||
end
|
||||
end
|
||||
@ -78,7 +74,7 @@ mobs.climb = function(self)
|
||||
new_velocity_addition.z = 0
|
||||
|
||||
--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)
|
||||
end
|
||||
end
|
||||
@ -86,10 +82,10 @@ end
|
||||
|
||||
|
||||
--[[
|
||||
_ _
|
||||
_ _
|
||||
| | | |
|
||||
| | __ _ _ __ __| |
|
||||
| | / _` | '_ \ / _` |
|
||||
| | / _` | '_ \ / _` |
|
||||
| |___| (_| | | | | (_| |
|
||||
\_____/\__,_|_| |_|\__,_|
|
||||
]]
|
||||
@ -100,28 +96,28 @@ end
|
||||
--internal = lua (self.yaw)
|
||||
--engine = c++ (self.object:get_yaw())
|
||||
mobs.set_velocity = function(self, v)
|
||||
|
||||
|
||||
local yaw = (self.yaw or 0)
|
||||
|
||||
local current_velocity = self.object:get_velocity()
|
||||
|
||||
local goal_velocity = {
|
||||
x = (math_sin(yaw) * -v),
|
||||
x = (math.sin(yaw) * -v),
|
||||
y = 0,
|
||||
z = (math_cos(yaw) * v),
|
||||
z = (math.cos(yaw) * v),
|
||||
}
|
||||
|
||||
|
||||
local new_velocity_addition = vector.subtract(goal_velocity,current_velocity)
|
||||
|
||||
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)))
|
||||
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)))
|
||||
end
|
||||
|
||||
new_velocity_addition.y = 0
|
||||
|
||||
--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)
|
||||
end
|
||||
end
|
||||
@ -136,7 +132,7 @@ mobs.get_velocity = function(self)
|
||||
v.y = 0
|
||||
|
||||
if v then
|
||||
return vector_length(v)
|
||||
return vector.length(v)
|
||||
end
|
||||
|
||||
return 0
|
||||
@ -152,7 +148,7 @@ mobs.jump = function(self, velocity)
|
||||
--fallback velocity to allow modularity
|
||||
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
|
||||
|
||||
--make mobs fall slowly
|
||||
@ -172,15 +168,15 @@ mobs.mob_fall_slow = function(self)
|
||||
new_velocity_addition.x = 0
|
||||
new_velocity_addition.z = 0
|
||||
|
||||
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)))
|
||||
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)))
|
||||
end
|
||||
|
||||
new_velocity_addition.x = 0
|
||||
new_velocity_addition.z = 0
|
||||
|
||||
--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)
|
||||
end
|
||||
|
||||
@ -188,10 +184,10 @@ end
|
||||
|
||||
|
||||
--[[
|
||||
_____ _
|
||||
/ ___| (_)
|
||||
\ `--.__ ___ _ __ ___
|
||||
`--. \ \ /\ / / | '_ ` _ \
|
||||
_____ _
|
||||
/ ___| (_)
|
||||
\ `--.__ ___ _ __ ___
|
||||
`--. \ \ /\ / / | '_ ` _ \
|
||||
/\__/ /\ V V /| | | | | | |
|
||||
\____/ \_/\_/ |_|_| |_| |_|
|
||||
]]--
|
||||
@ -212,16 +208,16 @@ mobs.flop = function(self, velocity)
|
||||
velocity = velocity or DEFAULT_JUMP_HEIGHT
|
||||
|
||||
--create a random direction (2d yaw)
|
||||
local dir = DOUBLE_PI * math_random()
|
||||
local dir = DOUBLE_PI * math.random()
|
||||
|
||||
--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
|
||||
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
|
||||
final_additional_force.y = velocity
|
||||
final_additional_force.y = velocity
|
||||
|
||||
self.object:add_velocity(final_additional_force)
|
||||
|
||||
@ -235,7 +231,7 @@ end
|
||||
--internal = lua (self.yaw)
|
||||
--engine = c++ (self.object:get_yaw())
|
||||
mobs.set_swim_velocity = function(self, v)
|
||||
|
||||
|
||||
local yaw = (self.yaw 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 goal_velocity = {
|
||||
x = (math_sin(yaw) * -v),
|
||||
x = (math.sin(yaw) * -v),
|
||||
y = pitch,
|
||||
z = (math_cos(yaw) * v),
|
||||
z = (math.cos(yaw) * v),
|
||||
}
|
||||
|
||||
|
||||
local new_velocity_addition = vector.subtract(goal_velocity,current_velocity)
|
||||
|
||||
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)))
|
||||
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)))
|
||||
end
|
||||
|
||||
--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)
|
||||
end
|
||||
end
|
||||
|
||||
--[[
|
||||
______ _
|
||||
| ___| |
|
||||
| |_ | |_ _
|
||||
______ _
|
||||
| ___| |
|
||||
| |_ | |_ _
|
||||
| _| | | | | |
|
||||
| | | | |_| |
|
||||
\_| |_|\__, |
|
||||
__/ |
|
||||
|___/
|
||||
|___/
|
||||
]]--
|
||||
|
||||
-- move mob in facing direction
|
||||
@ -280,7 +276,7 @@ ______ _
|
||||
--internal = lua (self.yaw)
|
||||
--engine = c++ (self.object:get_yaw())
|
||||
mobs.set_fly_velocity = function(self, v)
|
||||
|
||||
|
||||
local yaw = (self.yaw 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 goal_velocity = {
|
||||
x = (math_sin(yaw) * -v),
|
||||
x = (math.sin(yaw) * -v),
|
||||
y = pitch,
|
||||
z = (math_cos(yaw) * v),
|
||||
z = (math.cos(yaw) * v),
|
||||
}
|
||||
|
||||
|
||||
local new_velocity_addition = vector.subtract(goal_velocity,current_velocity)
|
||||
|
||||
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)))
|
||||
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)))
|
||||
end
|
||||
|
||||
--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)
|
||||
end
|
||||
end
|
||||
@ -316,7 +312,7 @@ mobs.calculate_pitch = function(pos1, pos2)
|
||||
return false
|
||||
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
|
||||
|
||||
--make mobs fly up or down based on their y difference
|
||||
@ -332,14 +328,14 @@ end
|
||||
|
||||
|
||||
--[[
|
||||
___
|
||||
|_ |
|
||||
| |_ _ _ __ ___ _ __
|
||||
| | | | | '_ ` _ \| '_ \
|
||||
___
|
||||
|_ |
|
||||
| |_ _ _ __ ___ _ __
|
||||
| | | | | '_ ` _ \| '_ \
|
||||
/\__/ / |_| | | | | | | |_) |
|
||||
\____/ \__,_|_| |_| |_| .__/
|
||||
| |
|
||||
|_|
|
||||
\____/ \__,_|_| |_| |_| .__/
|
||||
| |
|
||||
|_|
|
||||
]]--
|
||||
|
||||
--special mob jump movement
|
||||
@ -353,27 +349,27 @@ mobs.jump_move = function(self, velocity)
|
||||
mobs.set_velocity(self,0)
|
||||
|
||||
--fallback velocity to allow modularity
|
||||
jump_height = DEFAULT_JUMP_HEIGHT
|
||||
local jump_height = DEFAULT_JUMP_HEIGHT
|
||||
|
||||
local yaw = (self.yaw or 0)
|
||||
|
||||
local current_velocity = self.object:get_velocity()
|
||||
|
||||
local goal_velocity = {
|
||||
x = (math_sin(yaw) * -velocity),
|
||||
x = (math.sin(yaw) * -velocity),
|
||||
y = jump_height,
|
||||
z = (math_cos(yaw) * velocity),
|
||||
z = (math.cos(yaw) * velocity),
|
||||
}
|
||||
|
||||
|
||||
local new_velocity_addition = vector.subtract(goal_velocity,current_velocity)
|
||||
|
||||
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)))
|
||||
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)))
|
||||
end
|
||||
|
||||
--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)
|
||||
end
|
||||
end
|
||||
@ -388,4 +384,4 @@ mobs.swap_auto_step_height_adjust = function(self)
|
||||
elseif y_vel ~= 0 and self.stepheight ~= 0 then
|
||||
self.stepheight = 0
|
||||
end
|
||||
end
|
||||
end
|
||||
|
@ -1,10 +1,12 @@
|
||||
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
|
||||
mobs.mob_staticdata = function(self)
|
||||
|
||||
--despawn mechanism
|
||||
--don't despawned tamed or bred mobs
|
||||
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)
|
||||
end
|
||||
|
||||
|
||||
|
||||
if not self.random_sound_timer then
|
||||
self.random_sound_timer = math_random(self.random_sound_timer_min,self.random_sound_timer_max)
|
||||
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.texture_mods = {}
|
||||
|
||||
|
||||
self.v_start = false
|
||||
self.timer = 0
|
||||
@ -199,7 +198,6 @@ mobs.mob_activate = function(self, staticdata, def, dtime)
|
||||
else
|
||||
self.object:set_texture_mod("")
|
||||
end
|
||||
|
||||
|
||||
-- set anything changed above
|
||||
self.object:set_properties(self)
|
||||
|
@ -1,8 +1,11 @@
|
||||
|
||||
-- lib_mount by Blert2112 (edited by TenPlus1)
|
||||
|
||||
local enable_crash = false
|
||||
local crash_threshold = 6.5 -- ignored if enable_crash=false
|
||||
--local 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
|
||||
--
|
||||
|
||||
local node_ok = function(pos, fallback)
|
||||
--[[local function node_ok(pos, fallback)
|
||||
|
||||
fallback = fallback or mobs.fallback_node
|
||||
|
||||
@ -21,10 +24,10 @@ local node_ok = function(pos, fallback)
|
||||
end
|
||||
|
||||
return {name = fallback}
|
||||
end
|
||||
end]]
|
||||
|
||||
|
||||
local function node_is(pos)
|
||||
--[[local function node_is(pos)
|
||||
|
||||
local node = node_ok(pos)
|
||||
|
||||
@ -45,7 +48,7 @@ local function node_is(pos)
|
||||
end
|
||||
|
||||
return "other"
|
||||
end
|
||||
end]]
|
||||
|
||||
|
||||
local function get_sign(i)
|
||||
@ -60,13 +63,11 @@ local function get_sign(i)
|
||||
end
|
||||
|
||||
|
||||
local function get_velocity(v, yaw, y)
|
||||
|
||||
--[[local function get_velocity(v, yaw, y)
|
||||
local x = -math.sin(yaw) * v
|
||||
local z = math.cos(yaw) * v
|
||||
|
||||
return {x = x, y = y, z = z}
|
||||
end
|
||||
end]]
|
||||
|
||||
|
||||
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}
|
||||
|
||||
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)
|
||||
@ -187,13 +188,13 @@ end
|
||||
|
||||
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
|
||||
rot_view = math.pi/2
|
||||
end
|
||||
--if entity.player_rotation.y == 90 then
|
||||
-- rot_view = math.pi/2
|
||||
--end
|
||||
|
||||
local acce_y = 0
|
||||
--local acce_y = 0
|
||||
local velo = entity.object:get_velocity()
|
||||
|
||||
entity.v = get_v(velo) * get_sign(entity.v)
|
||||
@ -388,7 +389,6 @@ end
|
||||
-- directional flying routine by D00Med (edited by TenPlus1)
|
||||
|
||||
function mobs.fly(entity, dtime, speed, shoots, arrow, moving_anim, stand_anim)
|
||||
|
||||
if true then
|
||||
print("succ")
|
||||
return
|
||||
|
@ -9,9 +9,9 @@ local get_objects_inside_radius = minetest.get_objects_inside_radius
|
||||
|
||||
local math_random = math.random
|
||||
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_floor = vector.floor
|
||||
|
||||
@ -167,7 +167,7 @@ Overworld regular:
|
||||
|
||||
|
||||
-- count how many mobs are in an area
|
||||
local count_mobs = function(pos)
|
||||
local function count_mobs(pos)
|
||||
local num = 0
|
||||
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
|
||||
@ -242,8 +242,7 @@ function mobs:spawn_specific(name, dimension, type_of_spawning, biomes, min_ligh
|
||||
end
|
||||
|
||||
--[[
|
||||
local spawn_action
|
||||
spawn_action = function(pos, node, active_object_count, active_object_count_wider, name)
|
||||
local function spawn_action(pos, node, active_object_count, active_object_count_wider, name)
|
||||
|
||||
local orig_pos = table.copy(pos)
|
||||
-- is mob actually registered?
|
||||
@ -486,7 +485,8 @@ local axis
|
||||
local inner = 15
|
||||
local outer = 64
|
||||
local int = {-1,1}
|
||||
local position_calculation = function(pos)
|
||||
|
||||
local function position_calculation(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.x = pos.x + math_random(-outer,outer)
|
||||
end
|
||||
return(pos)
|
||||
return pos
|
||||
end
|
||||
|
||||
--[[
|
||||
@ -573,10 +573,10 @@ if mobs_spawn then
|
||||
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
|
||||
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
|
||||
end
|
||||
|
||||
|
||||
--hard code mob limit in area to 5 for now
|
||||
if count_mobs(spawning_position) >= 5 then
|
||||
break
|
||||
@ -606,7 +606,7 @@ if mobs_spawn then
|
||||
local is_lava = get_item_group(gotten_node, "lava") ~= 0
|
||||
|
||||
local mob_def = nil
|
||||
|
||||
|
||||
--create a disconnected clone of the spawn dictionary
|
||||
--prevents memory leak
|
||||
local mob_library_worker_table = table_copy(spawn_dictionary)
|
||||
|
@ -2,4 +2,4 @@ name = mcl_mobs
|
||||
author = PilzAdam
|
||||
description = Adds a mob API for mods to add animals or monsters, etc.
|
||||
depends = mcl_particles
|
||||
optional_depends = mcl_weather, mcl_explosions, mcl_hunger, mcl_worlds, invisibility, 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
|
||||
|
@ -4,9 +4,11 @@ dofile(minetest.get_modpath(minetest.get_current_modname()).."/paintings.lua")
|
||||
|
||||
local S = minetest.get_translator("mcl_paintings")
|
||||
|
||||
local math = math
|
||||
|
||||
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
|
||||
minetest.record_protection_violation(pos, name)
|
||||
return true
|
||||
@ -17,7 +19,7 @@ end
|
||||
-- Check if there's a painting for provided painting size.
|
||||
-- If yes, returns the arguments.
|
||||
-- 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
|
||||
return nil
|
||||
end
|
||||
@ -43,7 +45,7 @@ local shrink_painting = function(x, y)
|
||||
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]
|
||||
if not painting then
|
||||
return nil
|
||||
@ -53,7 +55,7 @@ local get_painting = function(x, y, motive)
|
||||
return "[combine:"..sx.."x"..sy..":"..px..","..py.."=mcl_paintings_paintings.png"
|
||||
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
|
||||
return nil
|
||||
end
|
||||
@ -65,7 +67,7 @@ local get_random_painting = function(x, y)
|
||||
return get_painting(x, y, r), r
|
||||
end
|
||||
|
||||
local size_to_minmax = function(size)
|
||||
--[[local function size_to_minmax(size)
|
||||
local min, max
|
||||
if size == 2 then
|
||||
min = -0.5
|
||||
@ -81,13 +83,13 @@ local size_to_minmax = function(size)
|
||||
max = 0.5
|
||||
end
|
||||
return min, max
|
||||
end
|
||||
end]]
|
||||
|
||||
local size_to_minmax_entity = function(size)
|
||||
local function size_to_minmax_entity(size)
|
||||
return -size/2, size/2
|
||||
end
|
||||
|
||||
local set_entity = function(object)
|
||||
local function set_entity(object)
|
||||
local ent = object:get_luaentity()
|
||||
local wallm = ent._facing
|
||||
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)
|
||||
-- Drop as item on punch
|
||||
if puncher and puncher:is_player() then
|
||||
kname = puncher:get_player_name()
|
||||
local kname = puncher:get_player_name()
|
||||
local pos = self._pos
|
||||
if not pos then
|
||||
pos = self.object:get_pos()
|
||||
|
@ -3,7 +3,7 @@ local TS = 16 -- texture size
|
||||
mcl_paintings.paintings = {
|
||||
[1] = {
|
||||
[1] = {
|
||||
{ cx = 0, cy = 0 },
|
||||
{ cx = 0, cy = 0 },
|
||||
{ cx = TS, cy = 0 },
|
||||
{ cx = 2*TS, cy = 0 },
|
||||
{ cx = 3*TS, cy = 0 },
|
||||
@ -26,7 +26,7 @@ mcl_paintings.paintings = {
|
||||
{ cx = 0, cy = 4*TS },
|
||||
{ cx = TS, cy = 4*TS },
|
||||
},
|
||||
[2] = {
|
||||
[2] = {
|
||||
{ cx = 0, cy = 8*TS },
|
||||
{ cx = 2*TS, cy = 8*TS },
|
||||
{ cx = 4*TS, cy = 8*TS },
|
||||
@ -35,7 +35,7 @@ mcl_paintings.paintings = {
|
||||
{ cx = 10*TS, cy = 8*TS },
|
||||
},
|
||||
[3] = 2,
|
||||
[4] = {
|
||||
[4] = {
|
||||
{ cx = 0, cy = 6*TS },
|
||||
},
|
||||
},
|
||||
|
@ -83,7 +83,7 @@ mobs_mc.items = {
|
||||
water_source = "default:water_source",
|
||||
water_flowing = "default:water_flowing",
|
||||
river_water_source = "default:river_water_source",
|
||||
water_flowing = "default:river_water_flowing",
|
||||
--water_flowing = "default:river_water_flowing",
|
||||
black_dye = "dye:black",
|
||||
poppy = "flowers:rose",
|
||||
dandelion = "flowers:dandelion_yellow",
|
||||
@ -128,7 +128,6 @@ mobs_mc.items = {
|
||||
|
||||
nether_portal = "nether:portal",
|
||||
netherrack = "nether:rack",
|
||||
nether_brick_block = "nether:brick",
|
||||
|
||||
-- Wool (Minecraft color scheme)
|
||||
wool_white = "wool:white",
|
||||
|
@ -6,7 +6,7 @@
|
||||
-- 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.
|
||||
|
||||
local S = minetest.get_translator("mobs_mc")
|
||||
--local S = minetest.get_translator("mobs_mc")
|
||||
|
||||
--maikerumines throwing code
|
||||
--arrow (weapon)
|
||||
|
@ -3,8 +3,9 @@
|
||||
|
||||
-- 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: Add translation.
|
||||
|
||||
local S = minetest.get_translator("mobs_mc")
|
||||
--local S = minetest.get_translator("mobs_mc")
|
||||
|
||||
-- Heads system
|
||||
|
||||
|
@ -20,7 +20,7 @@ mobs:register_mob("mobs_mc:blaze", {
|
||||
xp_max = 10,
|
||||
tilt_fly = false,
|
||||
hostile = true,
|
||||
rotate = 270,
|
||||
--rotate = 270,
|
||||
collisionbox = {-0.3, -0.01, -0.3, 0.3, 1.79, 0.3},
|
||||
rotate = -180,
|
||||
visual = "mesh",
|
||||
|
@ -89,7 +89,7 @@ local cow_def = {
|
||||
--head code
|
||||
has_head = true,
|
||||
head_bone = "head",
|
||||
|
||||
|
||||
swap_y_with_x = false,
|
||||
reverse_head_yaw = false,
|
||||
|
||||
@ -168,7 +168,7 @@ mooshroom_def.on_rightclick = function(self, clicker)
|
||||
pos.y = pos.y + 0.5
|
||||
minetest.add_item(pos, {name = mobs_mc.items.mushroom_stew})
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
mobs:register_mob("mobs_mc:mooshroom", mooshroom_def)
|
||||
|
||||
|
@ -16,7 +16,7 @@ mobs:register_mob("mobs_mc:enderdragon", {
|
||||
shoot_arrow = function(self, pos, dir)
|
||||
-- 2-4 damage per arrow
|
||||
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,
|
||||
hp_max = 200,
|
||||
hp_min = 200,
|
||||
@ -24,7 +24,6 @@ mobs:register_mob("mobs_mc:enderdragon", {
|
||||
xp_max = 500,
|
||||
collisionbox = {-2, 0, -2, 2, 2, 2},
|
||||
eye_height = 1,
|
||||
physical = false,
|
||||
visual = "mesh",
|
||||
mesh = "mobs_mc_dragon.b3d",
|
||||
textures = {
|
||||
@ -60,8 +59,6 @@ mobs:register_mob("mobs_mc:enderdragon", {
|
||||
arrow = "mobs_mc:dragon_fireball",
|
||||
shoot_interval = 0.5,
|
||||
shoot_offset = -1.0,
|
||||
xp_min = 500,
|
||||
xp_max = 500,
|
||||
animation = {
|
||||
fly_speed = 8, stand_speed = 8,
|
||||
stand_start = 0, stand_end = 20,
|
||||
@ -114,8 +111,8 @@ mobs:register_mob("mobs_mc:enderdragon", {
|
||||
fire_resistant = true,
|
||||
})
|
||||
|
||||
|
||||
local mobs_griefing = minetest.settings:get_bool("mobs_griefing") ~= false
|
||||
--TODO: replace this setting by a proper gamerules system
|
||||
local mobs_griefing = minetest.settings:get_bool("mobs_griefing", true)
|
||||
|
||||
-- dragon fireball (projectile)
|
||||
mobs:register_arrow("mobs_mc:dragon_fireball", {
|
||||
@ -143,7 +140,9 @@ mobs:register_arrow("mobs_mc:dragon_fireball", {
|
||||
-- node hit, explode
|
||||
hit_node = function(self, pos, node)
|
||||
--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
|
||||
})
|
||||
|
||||
|
@ -318,12 +318,12 @@ mobs:register_mob("mobs_mc:enderman", {
|
||||
for n = 1, #objs do
|
||||
local obj = objs[n]
|
||||
if obj then
|
||||
if minetest.is_player(obj) then
|
||||
--if minetest.is_player(obj) then
|
||||
-- Warp from players during day.
|
||||
--if (minetest.get_timeofday() * 24000) > 5001 and (minetest.get_timeofday() * 24000) < 19000 then
|
||||
-- self:teleport(nil)
|
||||
--end
|
||||
else
|
||||
if not obj:is_player() then
|
||||
local lua = obj:get_luaentity()
|
||||
if lua then
|
||||
if lua.name == "mcl_bows:arrow_entity" or lua.name == "mcl_throwing:snowball_entity" then
|
||||
|
@ -13,7 +13,7 @@ mobs:register_mob("mobs_mc:guardian", {
|
||||
xp_min = 10,
|
||||
xp_max = 10,
|
||||
breath_max = -1,
|
||||
passive = false,
|
||||
passive = false,
|
||||
attack_type = "punch",
|
||||
pathfinding = 1,
|
||||
view_range = 16,
|
||||
@ -94,7 +94,6 @@ mobs:register_mob("mobs_mc:guardian", {
|
||||
makes_footstep_sound = false,
|
||||
fly_in = { mobs_mc.items.water_source, mobs_mc.items.river_water_source },
|
||||
jump = false,
|
||||
view_range = 16,
|
||||
})
|
||||
|
||||
-- Spawning disabled due to size issues
|
||||
|
@ -104,7 +104,6 @@ mobs:register_mob("mobs_mc:guardian_elder", {
|
||||
makes_footstep_sound = false,
|
||||
fly_in = { mobs_mc.items.water_source, mobs_mc.items.river_water_source },
|
||||
jump = false,
|
||||
view_range = 16,
|
||||
})
|
||||
|
||||
-- Spawning disabled due to size issues <- what do you mean? -j4i
|
||||
|
@ -38,9 +38,9 @@ end
|
||||
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"
|
||||
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"
|
||||
end
|
||||
end]]
|
||||
local can_breed = function(entity_id)
|
||||
return entity_id == "mobs_mc:horse" or "mobs_mc:mule" or entity_id == "mobs_mc:donkey"
|
||||
end
|
||||
@ -314,7 +314,7 @@ local horse = {
|
||||
-- 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
|
||||
|
||||
local inv = clicker:get_inventory()
|
||||
--local inv = clicker:get_inventory()
|
||||
|
||||
-- detatch player already riding horse
|
||||
if self.driver and clicker == self.driver then
|
||||
|
@ -18,7 +18,7 @@ mobs:register_mob("mobs_mc:iron_golem", {
|
||||
passive = true,
|
||||
rotate = 270,
|
||||
hp_min = 100,
|
||||
hp_max = 100,
|
||||
hp_max = 100,
|
||||
protect = true,
|
||||
neutral = true,
|
||||
breath_max = -1,
|
||||
|
@ -35,7 +35,7 @@ mobs:register_mob("mobs_mc:llama", {
|
||||
shoot_arrow = function(self, pos, dir)
|
||||
-- 2-4 damage per arrow
|
||||
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,
|
||||
hp_min = 15,
|
||||
hp_max = 30,
|
||||
@ -146,7 +146,7 @@ mobs:register_mob("mobs_mc:llama", {
|
||||
self.tamed = true
|
||||
self.owner = clicker:get_player_name()
|
||||
return
|
||||
end
|
||||
end
|
||||
|
||||
--ignore other logic
|
||||
--make baby grow faster
|
||||
@ -307,19 +307,19 @@ mobs:register_arrow("mobs_mc:spit", {
|
||||
tail_distance_divider = 4,
|
||||
|
||||
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"
|
||||
end
|
||||
end]]
|
||||
player:punch(self.object, 1.0, {
|
||||
full_punch_interval = 1.0,
|
||||
damage_groups = {fleshy = self._damage},
|
||||
}, nil)
|
||||
end,
|
||||
|
||||
hit_mob = function(self, mob)
|
||||
hit_mob = function(self, mob)
|
||||
mob:punch(self.object, 1.0, {
|
||||
full_punch_interval = 1.0,
|
||||
damage_groups = {fleshy = _damage},
|
||||
damage_groups = {fleshy = self._damage},
|
||||
}, nil)
|
||||
end,
|
||||
|
||||
|
@ -151,7 +151,7 @@ end
|
||||
|
||||
mobs:register_mob("mobs_mc:cat", cat)
|
||||
|
||||
local base_spawn_chance = 5000
|
||||
--local base_spawn_chance = 5000
|
||||
|
||||
-- Spawn ocelot
|
||||
--they get the same as the llama because I'm trying to rework so much of this code right now -j4i
|
||||
|
@ -44,7 +44,7 @@ mobs:register_mob("mobs_mc:parrot", {
|
||||
max = 2,
|
||||
looting = "common",},
|
||||
},
|
||||
animation = {
|
||||
animation = {
|
||||
stand_speed = 50,
|
||||
walk_speed = 50,
|
||||
fly_speed = 50,
|
||||
|
@ -130,7 +130,7 @@ mobs:register_mob("mobs_mc:pig", {
|
||||
-- Put saddle on pig
|
||||
local item = clicker:get_wielded_item()
|
||||
local wielditem = item
|
||||
|
||||
|
||||
if item:get_name() == mobs_mc.items.saddle and self.saddle ~= "yes" then
|
||||
self.base_texture = {
|
||||
"blank.png", -- baby
|
||||
@ -163,7 +163,7 @@ mobs:register_mob("mobs_mc:pig", {
|
||||
end
|
||||
|
||||
-- Mount or detach player
|
||||
local name = clicker:get_player_name()
|
||||
--local name = clicker:get_player_name()
|
||||
if self.driver and clicker == self.driver then
|
||||
-- Detach if already attached
|
||||
mobs.detach(clicker, {x=1, y=0, z=0})
|
||||
|
@ -79,11 +79,11 @@ mobs:register_mob("mobs_mc:sheep", {
|
||||
makes_footstep_sound = true,
|
||||
walk_velocity = 1,
|
||||
run_velocity = 3,
|
||||
|
||||
|
||||
--head code
|
||||
has_head = true,
|
||||
head_bone = "head",
|
||||
|
||||
|
||||
swap_y_with_x = false,
|
||||
reverse_head_yaw = false,
|
||||
|
||||
@ -150,7 +150,6 @@ mobs:register_mob("mobs_mc:sheep", {
|
||||
do_custom = function(self, dtime)
|
||||
if not self.initial_color_set then
|
||||
local r = math.random(0,100000)
|
||||
local textures
|
||||
if r <= 81836 then
|
||||
-- 81.836%
|
||||
self.color = "unicolor_white"
|
||||
|
@ -46,7 +46,6 @@ mobs:register_mob("mobs_mc:silverfish", {
|
||||
view_range = 16,
|
||||
attack_type = "punch",
|
||||
damage = 1,
|
||||
reach = 1,
|
||||
})
|
||||
|
||||
mobs:register_egg("mobs_mc:silverfish", S("Silverfish"), "mobs_mc_spawn_icon_silverfish.png", 0)
|
||||
|
@ -31,12 +31,8 @@ local skeleton = {
|
||||
group_attack = true,
|
||||
visual = "mesh",
|
||||
mesh = "mobs_mc_skeleton.b3d",
|
||||
textures = { {
|
||||
"mcl_bows_bow_0.png", -- bow
|
||||
"mobs_mc_skeleton.png", -- skeleton
|
||||
} },
|
||||
|
||||
--head code
|
||||
--head code
|
||||
has_head = false,
|
||||
head_bone = "head",
|
||||
|
||||
|
@ -15,7 +15,7 @@ mobs:register_mob("mobs_mc:vex", {
|
||||
spawn_class = "hostile",
|
||||
pathfinding = 1,
|
||||
passive = false,
|
||||
attack_type = "punch",
|
||||
attack_type = "dogfight",
|
||||
physical = false,
|
||||
hp_min = 14,
|
||||
hp_max = 14,
|
||||
@ -36,7 +36,6 @@ mobs:register_mob("mobs_mc:vex", {
|
||||
view_range = 16,
|
||||
walk_velocity = 3.2,
|
||||
run_velocity = 5.9,
|
||||
attack_type = "dogfight",
|
||||
sounds = {
|
||||
-- TODO: random
|
||||
death = "mobs_mc_vex_death",
|
||||
|
@ -26,7 +26,6 @@ mobs:register_mob("mobs_mc:wither", {
|
||||
{"mobs_mc_wither.png"},
|
||||
},
|
||||
visual_size = {x=4, y=4},
|
||||
makes_footstep_sound = true,
|
||||
view_range = 16,
|
||||
fear_height = 4,
|
||||
walk_velocity = 2,
|
||||
@ -81,7 +80,7 @@ mobs:register_mob("mobs_mc:wither", {
|
||||
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", {
|
||||
visual = "sprite",
|
||||
|
@ -35,7 +35,7 @@ local wolf = {
|
||||
--head code
|
||||
has_head = false,
|
||||
head_bone = "head",
|
||||
|
||||
|
||||
swap_y_with_x = false,
|
||||
reverse_head_yaw = false,
|
||||
|
||||
@ -186,7 +186,7 @@ dog.on_rightclick = function(self, clicker)
|
||||
if is_food(item:get_name()) then
|
||||
-- Feed to increase health
|
||||
local hp = self.health
|
||||
local hp_add = 0
|
||||
local hp_add
|
||||
-- Use eatable group to determine health boost
|
||||
local eatable = minetest.get_item_group(item, "eatable")
|
||||
if eatable > 0 then
|
||||
|
@ -200,14 +200,14 @@ end
|
||||
mobs_mc.override.enderman_block_texture_overrides = {
|
||||
["mcl_core:cactus"] = ctable,
|
||||
-- FIXME: replace colorize colors with colors from palette
|
||||
["mcl_core:dirt_with_grass"] =
|
||||
{
|
||||
"mcl_core_grass_block_top.png^[colorize:green:90",
|
||||
"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)"}
|
||||
["mcl_core:dirt_with_grass"] = {
|
||||
"mcl_core_grass_block_top.png^[colorize:green:90",
|
||||
"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)",
|
||||
},
|
||||
}
|
||||
|
||||
-- List of nodes on which mobs can spawn
|
||||
|
@ -134,6 +134,7 @@ lightning.strike = function(pos)
|
||||
sound_play({ name = "lightning_thunder", gain = 10 }, { pos = pos, max_hear_distance = 500 }, true)
|
||||
|
||||
-- damage nearby objects, transform mobs
|
||||
-- TODO: use an API insteed of hardcoding this behaviour
|
||||
local objs = get_objects_inside_radius(pos2, 3.5)
|
||||
for o=1, #objs do
|
||||
local obj = objs[o]
|
||||
@ -153,7 +154,7 @@ lightning.strike = function(pos)
|
||||
end
|
||||
obj:set_properties({textures = lua.base_texture})
|
||||
-- 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
|
||||
-- TODO: Enable this code when witches are working.
|
||||
--[[
|
||||
|
@ -4,18 +4,16 @@ local SHEET_W = 4
|
||||
local SHEET_H = 2
|
||||
|
||||
-- Randomize initial moon phase, based on map seed
|
||||
local phase_offset
|
||||
local mg_seed = minetest.get_mapgen_setting("seed")
|
||||
local rand = PseudoRandom(mg_seed)
|
||||
local phase_offset = rand:next(0, MOON_PHASES - 1)
|
||||
rand = nil
|
||||
|
||||
minetest.log("info", "[mcl_moon] Moon phase offset of this world: "..phase_offset)
|
||||
|
||||
mcl_moon = {}
|
||||
mcl_moon.MOON_PHASES = MOON_PHASES
|
||||
|
||||
mcl_moon.get_moon_phase = function()
|
||||
function mcl_moon.get_moon_phase()
|
||||
local after_midday = 0
|
||||
-- Moon phase changes after midday
|
||||
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
|
||||
end
|
||||
|
||||
local get_moon_texture = function()
|
||||
local function get_moon_texture()
|
||||
local phase = mcl_moon.get_moon_phase()
|
||||
local x = phase % MOON_PHASES_HALF
|
||||
local y
|
||||
|
@ -1,5 +1,5 @@
|
||||
local S = minetest.get_translator("mcl_void_damage")
|
||||
local enable_damage = minetest.settings:get_bool("enable_damage")
|
||||
--local enable_damage = minetest.settings:get_bool("enable_damage")
|
||||
|
||||
local pos_to_dim = mcl_worlds.pos_to_dimension
|
||||
local dim_change = mcl_worlds.dimension_change
|
||||
@ -39,9 +39,9 @@ minetest.register_on_mods_loaded(function()
|
||||
end
|
||||
self._void_timer = 0
|
||||
|
||||
local void, void_deadly = is_in_void(pos)
|
||||
local _, void_deadly = is_in_void(pos)
|
||||
if void_deadly then
|
||||
local ent = obj:get_luaentity()
|
||||
--local ent = obj:get_luaentity()
|
||||
obj:remove()
|
||||
return
|
||||
end
|
||||
@ -61,7 +61,7 @@ minetest.register_globalstep(function(dtime)
|
||||
for p=1, #players do
|
||||
local player = players[p]
|
||||
local pos = player:get_pos()
|
||||
local void, void_deadly = is_in_void(pos)
|
||||
local _, void_deadly = is_in_void(pos)
|
||||
if void_deadly then
|
||||
local immortal_val = player:get_armor_groups().immortal
|
||||
local is_immortal = false
|
||||
|
@ -20,7 +20,7 @@ mcl_weather.rain = {
|
||||
init_done = false,
|
||||
}
|
||||
|
||||
mcl_weather.rain.sound_handler = function(player)
|
||||
function mcl_weather.rain.sound_handler(player)
|
||||
return minetest.sound_play("weather_rain", {
|
||||
to_player = player:get_player_name(),
|
||||
loop = true,
|
||||
@ -28,7 +28,7 @@ mcl_weather.rain.sound_handler = function(player)
|
||||
end
|
||||
|
||||
-- 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
|
||||
mcl_weather.skycolor.add_layer(
|
||||
"weather-pack-rain-sky",
|
||||
@ -46,8 +46,7 @@ end
|
||||
|
||||
-- creating manually parctiles instead of particles spawner because of easier to control
|
||||
-- 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
|
||||
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)
|
||||
@ -70,7 +69,7 @@ mcl_weather.rain.add_rain_particles = function(player)
|
||||
end
|
||||
|
||||
-- Simple random texture getter
|
||||
mcl_weather.rain.get_texture = function()
|
||||
function mcl_weather.rain.get_texture()
|
||||
local texture_name
|
||||
local random_number = math.random()
|
||||
if random_number > 0.33 then
|
||||
@ -85,7 +84,7 @@ end
|
||||
|
||||
-- register player for rain weather.
|
||||
-- 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
|
||||
local player_meta = {}
|
||||
player_meta.origin_sky = {player:get_sky()}
|
||||
@ -95,7 +94,7 @@ end
|
||||
|
||||
-- remove player from player list effected by rain.
|
||||
-- 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()]
|
||||
if player_meta ~= nil and player_meta.origin_sky ~= nil then
|
||||
player:set_clouds({color="#FFF0F0E5"})
|
||||
@ -119,7 +118,7 @@ end)
|
||||
-- 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
|
||||
-- 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()]
|
||||
if player_meta ~= nil 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
|
||||
|
||||
-- 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()]
|
||||
if player_meta ~= nil and player_meta.sound_handler ~= nil then
|
||||
minetest.sound_fade(player_meta.sound_handler, -0.5, 0.0)
|
||||
@ -150,7 +149,7 @@ mcl_weather.rain.remove_sound = function(player)
|
||||
end
|
||||
|
||||
-- callback function for removing rain
|
||||
mcl_weather.rain.clear = function()
|
||||
function mcl_weather.rain.clear()
|
||||
mcl_weather.rain.raining = false
|
||||
mcl_weather.rain.sky_last_update = -1
|
||||
mcl_weather.rain.init_done = false
|
||||
@ -166,11 +165,10 @@ minetest.register_globalstep(function(dtime)
|
||||
if mcl_weather.state ~= "rain" then
|
||||
return false
|
||||
end
|
||||
|
||||
mcl_weather.rain.make_weather()
|
||||
end)
|
||||
|
||||
mcl_weather.rain.make_weather = function()
|
||||
function mcl_weather.rain.make_weather()
|
||||
if mcl_weather.rain.init_done == false then
|
||||
mcl_weather.rain.raining = true
|
||||
mcl_weather.rain.set_sky_box()
|
||||
@ -190,7 +188,7 @@ mcl_weather.rain.make_weather = function()
|
||||
end
|
||||
|
||||
-- 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
|
||||
mcl_weather.rain.particles_count = PARTICLES_COUNT_THUNDER
|
||||
else
|
||||
@ -249,7 +247,7 @@ if mcl_weather.allow_abm then
|
||||
end
|
||||
end
|
||||
end
|
||||
})
|
||||
})
|
||||
|
||||
-- Wetten the soil
|
||||
minetest.register_abm({
|
||||
@ -264,7 +262,7 @@ if mcl_weather.allow_abm then
|
||||
end
|
||||
end
|
||||
end
|
||||
})
|
||||
})
|
||||
end
|
||||
|
||||
if mcl_weather.reg_weathers.rain == nil then
|
||||
|
@ -11,7 +11,7 @@ mcl_weather.skycolor = {
|
||||
-- Update interval.
|
||||
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.
|
||||
colors = {},
|
||||
|
||||
@ -205,8 +205,8 @@ mcl_weather.skycolor = {
|
||||
-- Returns first player sky color. I assume that all players are in same color layout.
|
||||
get_current_bg_color = function()
|
||||
local players = mcl_weather.skycolor.utils.get_players(nil)
|
||||
for _, player in ipairs(players) do
|
||||
return player:get_sky()
|
||||
if players[1] then
|
||||
return players[1]:get_sky()
|
||||
end
|
||||
return nil
|
||||
end
|
||||
|
@ -5,80 +5,80 @@ mcl_weather.snow = {}
|
||||
mcl_weather.snow.particles_count = 15
|
||||
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.rain.last_rp_count = 0
|
||||
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)
|
||||
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
|
||||
mcl_weather.rain.last_rp_count = mcl_weather.rain.last_rp_count + 1
|
||||
minetest.add_particle({
|
||||
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},
|
||||
acceleration = {x = 0, y=0, z = 0},
|
||||
expirationtime = 8.0,
|
||||
size = 1,
|
||||
collisiondetection = true,
|
||||
collision_removal = true,
|
||||
object_collision = false,
|
||||
vertical = false,
|
||||
texture = mcl_weather.snow.get_texture(),
|
||||
playername = player:get_player_name()
|
||||
})
|
||||
end
|
||||
end
|
||||
mcl_weather.rain.last_rp_count = 0
|
||||
for i=mcl_weather.snow.particles_count, 1,-1 do
|
||||
local random_pos_x, _, random_pos_z = mcl_weather.get_random_pos_by_player_look_dir(player)
|
||||
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
|
||||
mcl_weather.rain.last_rp_count = mcl_weather.rain.last_rp_count + 1
|
||||
minetest.add_particle({
|
||||
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},
|
||||
acceleration = {x = 0, y=0, z = 0},
|
||||
expirationtime = 8.0,
|
||||
size = 1,
|
||||
collisiondetection = true,
|
||||
collision_removal = true,
|
||||
object_collision = false,
|
||||
vertical = false,
|
||||
texture = mcl_weather.snow.get_texture(),
|
||||
playername = player:get_player_name()
|
||||
})
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
mcl_weather.snow.set_sky_box = function()
|
||||
mcl_weather.skycolor.add_layer(
|
||||
"weather-pack-snow-sky",
|
||||
{{r=0, g=0, b=0},
|
||||
{r=85, g=86, b=86},
|
||||
{r=135, g=135, b=135},
|
||||
{r=85, g=86, b=86},
|
||||
{r=0, g=0, b=0}})
|
||||
mcl_weather.skycolor.active = true
|
||||
for _, player in pairs(get_connected_players()) do
|
||||
player:set_clouds({color="#ADADADE8"})
|
||||
end
|
||||
mcl_weather.skycolor.active = true
|
||||
mcl_weather.skycolor.add_layer(
|
||||
"weather-pack-snow-sky",
|
||||
{{r=0, g=0, b=0},
|
||||
{r=85, g=86, b=86},
|
||||
{r=135, g=135, b=135},
|
||||
{r=85, g=86, b=86},
|
||||
{r=0, g=0, b=0}})
|
||||
mcl_weather.skycolor.active = true
|
||||
for _, player in pairs(get_connected_players()) do
|
||||
player:set_clouds({color="#ADADADE8"})
|
||||
end
|
||||
mcl_weather.skycolor.active = true
|
||||
end
|
||||
|
||||
mcl_weather.snow.clear = function()
|
||||
mcl_weather.skycolor.remove_layer("weather-pack-snow-sky")
|
||||
mcl_weather.snow.init_done = false
|
||||
function mcl_weather.snow.clear()
|
||||
mcl_weather.skycolor.remove_layer("weather-pack-snow-sky")
|
||||
mcl_weather.snow.init_done = false
|
||||
end
|
||||
|
||||
-- Simple random texture getter
|
||||
mcl_weather.snow.get_texture = function()
|
||||
return "weather_pack_snow_snowflake"..math.random(1,2)..".png"
|
||||
function mcl_weather.snow.get_texture()
|
||||
return "weather_pack_snow_snowflake"..math.random(1,2)..".png"
|
||||
end
|
||||
|
||||
local timer = 0
|
||||
minetest.register_globalstep(function(dtime)
|
||||
if mcl_weather.state ~= "snow" then
|
||||
return false
|
||||
end
|
||||
|
||||
timer = timer + dtime;
|
||||
if timer >= 0.5 then
|
||||
timer = 0
|
||||
else
|
||||
return
|
||||
end
|
||||
if mcl_weather.state ~= "snow" then
|
||||
return false
|
||||
end
|
||||
|
||||
if mcl_weather.snow.init_done == false then
|
||||
mcl_weather.snow.set_sky_box()
|
||||
mcl_weather.snow.init_done = true
|
||||
end
|
||||
timer = timer + dtime;
|
||||
if timer >= 0.5 then
|
||||
timer = 0
|
||||
else
|
||||
return
|
||||
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
|
||||
if mcl_weather.snow.init_done == false then
|
||||
mcl_weather.snow.set_sky_box()
|
||||
mcl_weather.snow.init_done = true
|
||||
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)
|
||||
|
||||
-- register snow weather
|
||||
|
@ -4,60 +4,58 @@ local get_connected_players = minetest.get_connected_players
|
||||
lightning.auto = false
|
||||
|
||||
mcl_weather.thunder = {
|
||||
next_strike = 0,
|
||||
min_delay = 3,
|
||||
max_delay = 12,
|
||||
init_done = false,
|
||||
next_strike = 0,
|
||||
min_delay = 3,
|
||||
max_delay = 12,
|
||||
init_done = false,
|
||||
}
|
||||
|
||||
minetest.register_globalstep(function(dtime)
|
||||
if mcl_weather.get_weather() ~= "thunder" then
|
||||
return false
|
||||
end
|
||||
|
||||
mcl_weather.rain.set_particles_mode("thunder")
|
||||
mcl_weather.rain.make_weather()
|
||||
if mcl_weather.get_weather() ~= "thunder" then
|
||||
return false
|
||||
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
|
||||
mcl_weather.rain.set_particles_mode("thunder")
|
||||
mcl_weather.rain.make_weather()
|
||||
|
||||
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)
|
||||
|
||||
mcl_weather.thunder.clear = function()
|
||||
mcl_weather.rain.clear()
|
||||
mcl_weather.skycolor.remove_layer("weather-pack-thunder-sky")
|
||||
mcl_weather.skycolor.remove_layer("lightning")
|
||||
mcl_weather.thunder.init_done = false
|
||||
function mcl_weather.thunder.clear()
|
||||
mcl_weather.rain.clear()
|
||||
mcl_weather.skycolor.remove_layer("weather-pack-thunder-sky")
|
||||
mcl_weather.skycolor.remove_layer("lightning")
|
||||
mcl_weather.thunder.init_done = false
|
||||
end
|
||||
|
||||
-- register thunderstorm weather
|
||||
if mcl_weather.reg_weathers.thunder == nil then
|
||||
mcl_weather.reg_weathers.thunder = {
|
||||
clear = mcl_weather.thunder.clear,
|
||||
light_factor = 0.33333,
|
||||
-- 10min - 20min
|
||||
min_duration = 600,
|
||||
max_duration = 1200,
|
||||
transitions = {
|
||||
[100] = "rain",
|
||||
}
|
||||
}
|
||||
mcl_weather.reg_weathers.thunder = {
|
||||
clear = mcl_weather.thunder.clear,
|
||||
light_factor = 0.33333,
|
||||
-- 10min - 20min
|
||||
min_duration = 600,
|
||||
max_duration = 1200,
|
||||
transitions = {
|
||||
[100] = "rain",
|
||||
},
|
||||
}
|
||||
end
|
||||
|
@ -1,27 +1,29 @@
|
||||
local S = minetest.get_translator("mcl_weather")
|
||||
|
||||
local math = math
|
||||
|
||||
-- weather states, 'none' is default, other states depends from active mods
|
||||
mcl_weather.state = "none"
|
||||
|
||||
|
||||
-- player list for saving player meta info
|
||||
mcl_weather.players = {}
|
||||
|
||||
|
||||
-- default weather check interval for global step
|
||||
mcl_weather.check_interval = 5
|
||||
|
||||
|
||||
-- weather min duration
|
||||
mcl_weather.min_duration = 600
|
||||
|
||||
|
||||
-- weather max duration
|
||||
mcl_weather.max_duration = 9000
|
||||
|
||||
-- weather calculated end time
|
||||
mcl_weather.end_time = nil
|
||||
|
||||
|
||||
-- registered 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.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)
|
||||
else
|
||||
r = math.random(mcl_weather.min_duration, mcl_weather.max_duration)
|
||||
end
|
||||
end
|
||||
return minetest.get_gametime() + r
|
||||
end
|
||||
|
||||
@ -80,8 +82,8 @@ end
|
||||
mcl_weather.is_underwater = function(player)
|
||||
local ppos = player:get_pos()
|
||||
local offset = player:get_eye_offset()
|
||||
local player_eye_pos = {x = ppos.x + offset.x,
|
||||
y = ppos.y + offset.y + 1.5,
|
||||
local player_eye_pos = {x = ppos.x + offset.x,
|
||||
y = ppos.y + offset.y + 1.5,
|
||||
z = ppos.z + offset.z}
|
||||
local node_level = minetest.get_node_level(player_eye_pos)
|
||||
if node_level == 8 or node_level == 7 then
|
||||
@ -91,14 +93,12 @@ mcl_weather.is_underwater = function(player)
|
||||
end
|
||||
|
||||
-- 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)
|
||||
local look_dir = player:get_look_dir()
|
||||
local player_pos = player:get_pos()
|
||||
|
||||
local random_pos_x = 0
|
||||
local random_pos_y = 0
|
||||
local random_pos_z = 0
|
||||
local random_pos_x, random_pos_y, random_pos_z
|
||||
|
||||
if look_dir.x > 0 then
|
||||
if look_dir.z > 0 then
|
||||
@ -208,7 +208,7 @@ minetest.register_privilege("weather_manager", {
|
||||
give_to_singleplayer = false
|
||||
})
|
||||
|
||||
-- Weather command definition. Set
|
||||
-- Weather command definition. Set
|
||||
minetest.register_chatcommand("weather", {
|
||||
params = "(clear | rain | snow | thunder) [<duration>]",
|
||||
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")
|
||||
if weather_allow_abm ~= nil and weather_allow_abm == false then
|
||||
mcl_weather.allow_abm = false
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
local load_weather = function()
|
||||
|
@ -233,7 +233,7 @@ end
|
||||
|
||||
-- Returns true if the specified entry has been viewed by the player
|
||||
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
|
||||
return false
|
||||
else
|
||||
@ -243,7 +243,7 @@ end
|
||||
|
||||
-- Returns true if the specified entry is hidden from the player
|
||||
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
|
||||
if doc.data.players[playername].stored_data.revealed[category_id] == nil then
|
||||
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())
|
||||
return
|
||||
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
|
||||
local playerdata = doc.data.players[playername]
|
||||
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.."]"
|
||||
pos = pos + 1
|
||||
end
|
||||
local bw, bh
|
||||
|
||||
return formstring, ih
|
||||
end
|
||||
|
||||
|
@ -164,7 +164,7 @@ local factoid_toolcaps = function(tool_capabilities, check_uses)
|
||||
local useslines = 0
|
||||
for k,v in pairs(groupcaps) do
|
||||
-- Mining capabilities
|
||||
local minrating, maxrating
|
||||
--[[local minrating, maxrating
|
||||
if v.times then
|
||||
for rating, time in pairs(v.times) do
|
||||
if minrating == nil then minrating = rating else
|
||||
@ -177,7 +177,7 @@ local factoid_toolcaps = function(tool_capabilities, check_uses)
|
||||
else
|
||||
minrating = 1
|
||||
maxrating = 1
|
||||
end
|
||||
end]]
|
||||
local maxlevel = v.maxlevel
|
||||
if not maxlevel then
|
||||
-- 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"),
|
||||
build_formspec = function(data, playername)
|
||||
if data then
|
||||
local formstring = ""
|
||||
local datastring = ""
|
||||
|
||||
formstring = entry_image(data)
|
||||
datastring = factoids_header(data, "nodes")
|
||||
local formstring = entry_image(data)
|
||||
local datastring = factoids_header(data, "nodes")
|
||||
|
||||
local liquid = data.def.liquidtype ~= "none" and minetest.get_item_group(data.itemstring, "fake_liquid") == 0
|
||||
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
|
||||
local max = data.def.drop.max_items
|
||||
local dropstring = ""
|
||||
local dropstring_base = ""
|
||||
local dropstring_base
|
||||
if max == nil then
|
||||
dropstring_base = N("This block will drop the following items when mined: @1.")
|
||||
elseif max == 1 then
|
||||
@ -852,7 +849,7 @@ doc.add_category("nodes", {
|
||||
local rarity_history = {}
|
||||
for i=1,#data.def.drop.items do
|
||||
local local_rarity = data.def.drop.items[i].rarity
|
||||
local chance = 1
|
||||
local chance
|
||||
local rarity = 1
|
||||
if local_rarity == nil then
|
||||
local_rarity = 1
|
||||
@ -937,7 +934,6 @@ doc.add_category("nodes", {
|
||||
end
|
||||
|
||||
local rarity = probtable.rarity
|
||||
local raritystring = ""
|
||||
-- No percentage if there's only one possible guaranteed drop
|
||||
if not(rarity == 1 and #data.def.drop.items == 1) then
|
||||
local chance = (1/rarity)*100
|
||||
@ -1086,11 +1082,8 @@ doc.add_category("tools", {
|
||||
end,
|
||||
build_formspec = function(data, playername)
|
||||
if data then
|
||||
local formstring = ""
|
||||
local datastring = ""
|
||||
|
||||
formstring = entry_image(data)
|
||||
datastring = factoids_header(data, "tools")
|
||||
local formstring = entry_image(data)
|
||||
local datastring = factoids_header(data, "tools")
|
||||
|
||||
-- Overwritten durability info
|
||||
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)"),
|
||||
build_formspec = function(data, playername)
|
||||
if data then
|
||||
local formstring = ""
|
||||
local datastring = ""
|
||||
|
||||
formstring = entry_image(data)
|
||||
datastring = factoids_header(data, "craftitems")
|
||||
local formstring = entry_image(data)
|
||||
local datastring = factoids_header(data, "craftitems")
|
||||
datastring = datastring .. factoids_footer(data, playername, "craftitems")
|
||||
|
||||
formstring = formstring .. doc.widgets.text(datastring, nil, nil, doc.FORMSPEC.ENTRY_WIDTH - 1.2)
|
||||
|
@ -417,9 +417,9 @@ local function get_tooltip(item, groups, cooktime, burntime)
|
||||
-- and just print the normal item name without special formatting
|
||||
if groups[1] == "compass" or groups[1] == "clock" then
|
||||
groupstr = reg_items[item].description
|
||||
elseif group_names[groups[1]] then
|
||||
elseif g then
|
||||
-- Use the special group name string
|
||||
groupstr = minetest.colorize(gcol, group_names[groups[1]])
|
||||
groupstr = minetest.colorize(gcol, g)
|
||||
else
|
||||
--[[ Fallback: Generic group explanation: This always
|
||||
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
|
||||
local icon = custom_recipe and custom_recipe.icon or
|
||||
shapeless and "shapeless" or "furnace"
|
||||
shapeless and "shapeless" or "furnace"
|
||||
|
||||
if recipe.type == "cooking" then
|
||||
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] = fmt([[ tooltip[size_inc;%s]
|
||||
tooltip[size_dec;%s] ]],
|
||||
tooltip[size_dec;%s] ]],
|
||||
ESC(S("Increase window size")),
|
||||
ESC(S("Decrease window size")))
|
||||
|
||||
@ -656,9 +656,9 @@ local function make_formspec(name)
|
||||
]]
|
||||
|
||||
fs[#fs + 1] = fmt([[ tooltip[search;%s]
|
||||
tooltip[clear;%s]
|
||||
tooltip[prev;%s]
|
||||
tooltip[next;%s] ]],
|
||||
tooltip[clear;%s]
|
||||
tooltip[prev;%s]
|
||||
tooltip[next;%s] ]],
|
||||
ESC(S("Search")),
|
||||
ESC(S("Reset")),
|
||||
ESC(S("Previous page")),
|
||||
|
@ -154,7 +154,7 @@ doc.sub.items.register_factoid(nil, "use", function(itemstring, def)
|
||||
return s
|
||||
end)
|
||||
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 use = minetest.get_item_group(itemstring, "mcl_armor_uses")
|
||||
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 itemcount = item:get_count()
|
||||
local idef = minetest.registered_items[itemname]
|
||||
local text = ""
|
||||
local text
|
||||
if idef.description and idef.description ~= "" then
|
||||
text = idef.description
|
||||
else
|
||||
|
@ -1,6 +1,6 @@
|
||||
local S = minetest.get_translator("mcl_tt")
|
||||
|
||||
local function get_min_digtime(caps)
|
||||
--[[local function get_min_digtime(caps)
|
||||
local mintime
|
||||
local unique = true
|
||||
local maxlevel = caps.maxlevel
|
||||
@ -25,7 +25,7 @@ local function get_min_digtime(caps)
|
||||
end
|
||||
end
|
||||
return mintime, unique
|
||||
end
|
||||
end]]
|
||||
|
||||
local function newline(str)
|
||||
if str ~= "" then
|
||||
@ -47,7 +47,7 @@ tt.register_snippet(function(itemstring, toolcaps)
|
||||
local minestring = ""
|
||||
local capstr = ""
|
||||
local caplines = 0
|
||||
for k,v in pairs(groupcaps) do
|
||||
for _,v in pairs(groupcaps) do
|
||||
local speedstr = ""
|
||||
local miningusesstr = ""
|
||||
-- Mining capabilities
|
||||
@ -153,9 +153,9 @@ tt.register_snippet(function(itemstring, toolcaps)
|
||||
end)
|
||||
|
||||
-- Weapon stats
|
||||
tt.register_snippet(function(itemstring)
|
||||
--[[tt.register_snippet(function(itemstring)
|
||||
local def = minetest.registered_items[itemstring]
|
||||
end)
|
||||
end)]]
|
||||
|
||||
-- Food
|
||||
tt.register_snippet(function(itemstring)
|
||||
|
@ -2,7 +2,7 @@ local S = minetest.get_translator("mcl_tt")
|
||||
|
||||
-- Armor
|
||||
tt.register_snippet(function(itemstring)
|
||||
local def = minetest.registered_items[itemstring]
|
||||
--local def = minetest.registered_items[itemstring]
|
||||
local s = ""
|
||||
local head = minetest.get_item_group(itemstring, "armor_head")
|
||||
local torso = minetest.get_item_group(itemstring, "armor_torso")
|
||||
@ -26,7 +26,7 @@ tt.register_snippet(function(itemstring)
|
||||
return s
|
||||
end)
|
||||
tt.register_snippet(function(itemstring, _, itemstack)
|
||||
local def = minetest.registered_items[itemstring]
|
||||
--local def = minetest.registered_items[itemstring]
|
||||
local s = ""
|
||||
local use = minetest.get_item_group(itemstring, "mcl_armor_uses")
|
||||
local pts = minetest.get_item_group(itemstring, "mcl_armor_points")
|
||||
@ -75,7 +75,7 @@ tt.register_snippet(function(itemstring)
|
||||
end)
|
||||
|
||||
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
|
||||
return S("Deals damage when falling"), mcl_colors.YELLOW
|
||||
end
|
||||
|
@ -250,9 +250,7 @@ minetest.register_on_dignode(function(pos, oldnode, digger)
|
||||
local tnodedug = string.split(entry.node, ":")
|
||||
local tmod = tnodedug[1]
|
||||
local titem = tnodedug[2]
|
||||
if not tmod or not titem or not data.count[tmod] or not data.count[tmod][titem] then
|
||||
-- table running failed!
|
||||
elseif data.count[tmod][titem] > entry.target-1 then
|
||||
if tmod and titem and data.count[tmod] and data.count[tmod][titem] and data.count[tmod][titem] > entry.target-1 then
|
||||
return entry.award
|
||||
end
|
||||
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 tmod = tnodedug[1]
|
||||
local titem = tnodedug[2]
|
||||
if not tmod or not titem or not data.place[tmod] or not data.place[tmod][titem] then
|
||||
-- table running failed!
|
||||
elseif data.place[tmod][titem] > entry.target-1 then
|
||||
if tmod and titem and data.place[tmod] and data.place[tmod][titem] and data.place[tmod][titem] > entry.target-1 then
|
||||
return entry.award
|
||||
end
|
||||
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 tmod = titemstring[1]
|
||||
local titem = titemstring[2]
|
||||
if not tmod or not titem or not data.eat[tmod] or not data.eat[tmod][titem] then
|
||||
-- table running failed!
|
||||
elseif data.eat[tmod][titem] > entry.target-1 then
|
||||
if tmod and titem and data.eat[tmod] and data.eat[tmod][titem] and data.eat[tmod][titem] > entry.target-1 then
|
||||
return entry.award
|
||||
end
|
||||
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 tmod = titemcrafted[1]
|
||||
local titem = titemcrafted[2]
|
||||
if not tmod or not titem or not data.craft[tmod] or not data.craft[tmod][titem] then
|
||||
-- table running failed!
|
||||
elseif data.craft[tmod][titem] > entry.target-1 then
|
||||
if tmod and titem and data.craft[tmod] and data.craft[tmod][titem] and data.craft[tmod][titem] > entry.target-1 then
|
||||
return entry.award
|
||||
end
|
||||
elseif awards.get_total_item_count(data, "craft") > entry.target-1 then
|
||||
|
@ -1,6 +1,5 @@
|
||||
if minetest.get_modpath("unified_inventory") ~= nil then
|
||||
local S = minetest.get_translator("awards")
|
||||
|
||||
if minetest.get_modpath("unified_inventory") then
|
||||
local S = minetest.get_translator(minetest.get_current_modname())
|
||||
unified_inventory.register_button("awards", {
|
||||
type = "image",
|
||||
image = "awards_ui_icon.png",
|
||||
|
@ -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
|
||||
|
||||
hb = {}
|
||||
local math = math
|
||||
local table = table
|
||||
|
||||
hb.hudtables = {}
|
||||
|
||||
-- number of registered HUD bars
|
||||
hb.hudbars_count = 0
|
||||
|
||||
-- table which records which HUD bar slots have been “registered” so far; used for automatic positioning
|
||||
hb.registered_slots = {}
|
||||
|
||||
hb.settings = {}
|
||||
hb = {
|
||||
hudtables = {},
|
||||
-- number of registered HUD bars
|
||||
hudbars_count = 0,
|
||||
-- table which records which HUD bar slots have been “registered” so far; used for automatic positioning
|
||||
registered_slots = {},
|
||||
settings = {},
|
||||
-- Table which contains all players with active default HUD bars (only for internal use)
|
||||
players = {},
|
||||
}
|
||||
|
||||
function hb.load_setting(sname, stype, defaultval, valid_values)
|
||||
local sval
|
||||
@ -45,7 +50,8 @@ function hb.load_setting(sname, stype, defaultval, valid_values)
|
||||
end
|
||||
|
||||
-- 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
|
||||
-- reserve some space for experience bar:
|
||||
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
|
||||
end
|
||||
|
||||
-- Table which contains all players with active default HUD bars (only for internal use)
|
||||
hb.players = {}
|
||||
|
||||
function hb.value_to_barlength(value, max)
|
||||
if max == 0 then
|
||||
return 0
|
||||
|
@ -237,12 +237,10 @@ mcl_damage.register_on_damage(function(obj, damage, reason)
|
||||
end)
|
||||
|
||||
minetest.register_globalstep(function(dtime)
|
||||
local new_assist = {}
|
||||
|
||||
for obj, tbl in pairs(mcl_death_messages.assist) do
|
||||
tbl.timeout = tbl.timeout - dtime
|
||||
if (obj:is_player() or obj:get_luaentity()) and tbl.timeout > 0 then
|
||||
new_assist[obj] = tbl
|
||||
if not obj:is_player() and not obj:get_luaentity() or tbl.timeout > 0 then
|
||||
mcl_death_messages.assist[obj] = nil
|
||||
end
|
||||
end
|
||||
end)
|
||||
|
@ -1,5 +1,11 @@
|
||||
local S = minetest.get_translator("mcl_experience")
|
||||
|
||||
mcl_experience = {}
|
||||
|
||||
local vector = vector
|
||||
local math = math
|
||||
local string = string
|
||||
|
||||
local pool = {}
|
||||
local registered_nodes
|
||||
local max_xp = 2^31-1
|
||||
@ -114,9 +120,9 @@ end
|
||||
hud_manager.hud_exists = function(player,hud_name)
|
||||
local name = player:get_player_name()
|
||||
if player_huds[name] and player_huds[name][hud_name] then
|
||||
return(true)
|
||||
return true
|
||||
else
|
||||
return(false)
|
||||
return false
|
||||
end
|
||||
end
|
||||
-------------------
|
||||
@ -144,7 +150,7 @@ end)
|
||||
|
||||
function mcl_experience.get_player_xp_level(player)
|
||||
local name = player:get_player_name()
|
||||
return(pool[name].level)
|
||||
return pool[name].level
|
||||
end
|
||||
|
||||
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
|
||||
local can = final_candidates[math.random(#final_candidates)]
|
||||
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 multiplier = 2 * 65535 / uses
|
||||
local repair = experience * multiplier
|
||||
@ -329,14 +334,12 @@ minetest.register_on_dieplayer(function(player)
|
||||
mcl_experience.throw_experience(player:get_pos(), xp_amount)
|
||||
end)
|
||||
|
||||
|
||||
local name
|
||||
local collector, pos, pos2
|
||||
local direction, distance, player_velocity, goal
|
||||
local currentvel, acceleration, multiplier, velocity
|
||||
local node, vel, def
|
||||
local is_moving, is_slippery, slippery, slip_factor
|
||||
local size, data
|
||||
local size
|
||||
local function xp_step(self, dtime)
|
||||
--if item set to be collected then only execute go to player
|
||||
if self.collected == true then
|
||||
|
@ -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
|
||||
mcl_hbarmor.armor = {}
|
||||
local get_connected_players = minetest.get_connected_players
|
||||
|
||||
-- Stores if player's HUD bar has been initialized so far.
|
||||
mcl_hbarmor.player_active = {}
|
||||
local mcl_hbarmor = {
|
||||
-- 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.
|
||||
-- Increase this number for slow servers.
|
||||
mcl_hbarmor.tick = 0.1
|
||||
local tick_config = minetest.settings:get("mcl_hbarmor_tick")
|
||||
|
||||
-- If true, the armor bar is hidden when the player does not wear any armor
|
||||
mcl_hbarmor.autohide = true
|
||||
|
||||
set = minetest.settings:get("mcl_hbarmor_tick")
|
||||
if tonumber(set) ~= nil then
|
||||
mcl_hbarmor.tick = tonumber(set)
|
||||
if tonumber(tick_config) ~= nil then
|
||||
mcl_hbarmor.tick = tonumber(tick_config)
|
||||
end
|
||||
|
||||
|
||||
local must_hide = function(playername, arm)
|
||||
local function must_hide(playername, arm)
|
||||
return arm == 0
|
||||
end
|
||||
|
||||
local arm_printable = function(arm)
|
||||
local function arm_printable(arm)
|
||||
return math.ceil(math.floor(arm+0.5))
|
||||
end
|
||||
|
||||
@ -106,12 +109,13 @@ end)
|
||||
local main_timer = 0
|
||||
local timer = 0
|
||||
minetest.register_globalstep(function(dtime)
|
||||
--TODO: replace this by playerglobalstep API then implemented
|
||||
main_timer = main_timer + dtime
|
||||
timer = timer + dtime
|
||||
if main_timer > mcl_hbarmor.tick or timer > 4 then
|
||||
if minetest.settings:get_bool("enable_damage") then
|
||||
if main_timer > mcl_hbarmor.tick then main_timer = 0 end
|
||||
for _,player in pairs(minetest.get_connected_players()) do
|
||||
for _,player in pairs(get_connected_players()) do
|
||||
local name = player:get_player_name()
|
||||
if mcl_hbarmor.player_active[name] == true then
|
||||
local ret = mcl_hbarmor.get_armor(player)
|
||||
|
@ -7,7 +7,7 @@ local players = {}
|
||||
-- Containing all the items for each Creative Mode tab
|
||||
local inventory_lists = {}
|
||||
|
||||
local mod_player = minetest.get_modpath("mcl_player") ~= nil
|
||||
--local mod_player = minetest.get_modpath("mcl_player") ~= nil
|
||||
|
||||
-- Create tables
|
||||
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 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)
|
||||
if minetest.is_creative_enabled(playername) then
|
||||
return count
|
||||
@ -203,7 +203,7 @@ local offset = {} -- string offset:
|
||||
local boffset = {} --
|
||||
local hoch = {}
|
||||
local filtername = {}
|
||||
local bg = {}
|
||||
--local bg = {}
|
||||
|
||||
local noffset_x_start = -0.24
|
||||
local noffset_x = noffset_x_start
|
||||
@ -257,7 +257,6 @@ hoch["mobs"] = "_down"
|
||||
hoch["matr"] = "_down"
|
||||
hoch["inv"] = "_down"
|
||||
|
||||
filtername = {}
|
||||
filtername["blocks"] = S("Building Blocks")
|
||||
filtername["deco"] = S("Decoration Blocks")
|
||||
filtername["redstone"] = S("Redstone")
|
||||
@ -272,9 +271,9 @@ filtername["brew"] = S("Brewing")
|
||||
filtername["matr"] = S("Materials")
|
||||
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["deco"] = dark_bg
|
||||
bg["redstone"] = dark_bg
|
||||
@ -289,11 +288,11 @@ local function reset_menu_item_bg()
|
||||
bg["matr"] = dark_bg
|
||||
bg["inv"] = dark_bg
|
||||
bg["default"] = dark_bg
|
||||
end
|
||||
end]]
|
||||
|
||||
|
||||
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
|
||||
|
||||
local playername = player:get_player_name()
|
||||
@ -310,7 +309,6 @@ mcl_inventory.set_creative_formspec = function(player, start_i, pagenum, inv_siz
|
||||
end
|
||||
local pagemax = math.max(1, math.floor((inv_size-1) / (9*5) + 1))
|
||||
local name = "nix"
|
||||
local formspec = ""
|
||||
local main_list
|
||||
local listrings = "listring[detached:creative_"..playername..";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
|
||||
end
|
||||
end
|
||||
bg[name] = "crafting_creative_bg.png"
|
||||
--bg[name] = "crafting_creative_bg.png"
|
||||
|
||||
local inv_bg = "crafting_inventory_creative.png"
|
||||
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])).."]"
|
||||
end
|
||||
|
||||
formspec = "size[10,9.3]"..
|
||||
local formspec = "size[10,9.3]"..
|
||||
"no_prepend[]"..
|
||||
mcl_vars.gui_nonbg..mcl_vars.gui_bg_color..
|
||||
"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
|
||||
|
||||
-- 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
|
||||
|
||||
@ -628,7 +626,7 @@ if minetest.is_creative_enabled("") then
|
||||
end
|
||||
|
||||
mcl_inventory.update_inventory_formspec = function(player)
|
||||
local page = nil
|
||||
local page
|
||||
|
||||
local name = player:get_player_name()
|
||||
|
||||
@ -639,7 +637,7 @@ if minetest.is_creative_enabled("") then
|
||||
end
|
||||
|
||||
-- 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 inv_size
|
||||
|
@ -3,8 +3,8 @@ local F = minetest.formspec_escape
|
||||
|
||||
mcl_inventory = {}
|
||||
|
||||
local mod_player = minetest.get_modpath("mcl_player") ~= nil
|
||||
local mod_craftguide = minetest.get_modpath("mcl_craftguide") ~= nil
|
||||
--local mod_player = minetest.get_modpath("mcl_player") ~= 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
|
||||
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_size("craft", 4)
|
||||
|
||||
local player_name = player:get_player_name()
|
||||
|
||||
-- Show armor and player image
|
||||
local player_preview
|
||||
if minetest.settings:get_bool("3d_player_preview", true) then
|
||||
@ -180,6 +178,6 @@ minetest.register_on_joinplayer(function(player)
|
||||
end)
|
||||
|
||||
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
|
||||
|
||||
|
@ -1,6 +1,6 @@
|
||||
name = mcl_inventory
|
||||
author = BlockMen
|
||||
description = Adds the player inventory and creative inventory.
|
||||
depends = mcl_init, mcl_formspec
|
||||
optional_depends = mcl_player, _mcl_autogroup, mcl_armor, mcl_brewing, mcl_potions, mcl_enchanting
|
||||
depends = mcl_init, mcl_formspec, mcl_player
|
||||
optional_depends = _mcl_autogroup, mcl_armor, mcl_brewing, mcl_potions, mcl_enchanting, mcl_craftguide
|
||||
|
||||
|
@ -11,7 +11,7 @@ local xp_mod = minetest.get_modpath("mcl_experience")
|
||||
|
||||
local function set_hud(player)
|
||||
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
|
||||
local fixed = tonumber(minetest.settings:get("show_wielded_item_y_offset"))
|
||||
local off
|
||||
@ -84,7 +84,7 @@ minetest.register_globalstep(function(dtime)
|
||||
wield[player_name] = wname
|
||||
dtimes[player_name] = 0
|
||||
|
||||
if huds[player_name] then
|
||||
if huds[player_name] then
|
||||
|
||||
local def = minetest.registered_items[wname]
|
||||
local meta = wstack:get_meta()
|
||||
|
@ -217,94 +217,94 @@ if minetest.get_modpath("screwdriver") then
|
||||
end
|
||||
|
||||
for _, mode in pairs{"comp", "sub"} do
|
||||
for _, state in pairs{mesecon.state.on, mesecon.state.off} do
|
||||
local state_str = state_strs[state]
|
||||
local nodename =
|
||||
"mcl_comparators:comparator_"..state_strs[state].."_"..mode
|
||||
for _, state in pairs{mesecon.state.on, mesecon.state.off} do
|
||||
local state_str = state_strs[state]
|
||||
local nodename =
|
||||
"mcl_comparators:comparator_"..state_str.."_"..mode
|
||||
|
||||
-- Help
|
||||
local longdesc, usagehelp, use_help
|
||||
if state_strs[state] == "off" and mode == "comp" then
|
||||
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.")
|
||||
-- Help
|
||||
local longdesc, usagehelp, use_help
|
||||
if state_str == "off" and mode == "comp" then
|
||||
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.")
|
||||
|
||||
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 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("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
|
||||
use_help = false
|
||||
end
|
||||
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 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("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
|
||||
use_help = false
|
||||
end
|
||||
|
||||
local nodedef = {
|
||||
description = S("Redstone Comparator"),
|
||||
inventory_image = icon,
|
||||
wield_image = icon,
|
||||
_doc_items_create_entry = use_help,
|
||||
_doc_items_longdesc = longdesc,
|
||||
_doc_items_usagehelp = usagehelp,
|
||||
drawtype = "nodebox",
|
||||
tiles = get_tiles(state_strs[state], mode),
|
||||
use_texture_alpha = minetest.features.use_texture_alpha_string_modes and "opaque" or false,
|
||||
wield_image = "mcl_comparators_off.png",
|
||||
walkable = true,
|
||||
selection_box = collision_box,
|
||||
collision_box = collision_box,
|
||||
node_box = {
|
||||
type = "fixed",
|
||||
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,
|
||||
local nodedef = {
|
||||
description = S("Redstone Comparator"),
|
||||
inventory_image = icon,
|
||||
wield_image = icon,
|
||||
_doc_items_create_entry = use_help,
|
||||
_doc_items_longdesc = longdesc,
|
||||
_doc_items_usagehelp = usagehelp,
|
||||
drawtype = "nodebox",
|
||||
tiles = get_tiles(state_str, mode),
|
||||
use_texture_alpha = minetest.features.use_texture_alpha_string_modes and "opaque" or false,
|
||||
--wield_image = "mcl_comparators_off.png",
|
||||
walkable = true,
|
||||
selection_box = collision_box,
|
||||
collision_box = collision_box,
|
||||
node_box = {
|
||||
type = "fixed",
|
||||
fixed = node_boxes[mode],
|
||||
},
|
||||
effector = {
|
||||
rules = comparator_get_input_rules,
|
||||
action_change = update_self,
|
||||
}
|
||||
},
|
||||
on_rotate = on_rotate,
|
||||
}
|
||||
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_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
|
||||
-- This is the prototype
|
||||
nodedef._doc_items_create_entry = true
|
||||
else
|
||||
nodedef.groups = table.copy(nodedef.groups)
|
||||
nodedef.groups.not_in_creative_inventory = 1
|
||||
local extra_desc = {}
|
||||
if mode == "sub" or state == mesecon.state.on then
|
||||
nodedef.inventory_image = nil
|
||||
if mode == "comp" and state == mesecon.state.off then
|
||||
-- This is the prototype
|
||||
nodedef._doc_items_create_entry = true
|
||||
else
|
||||
nodedef.groups = table.copy(nodedef.groups)
|
||||
nodedef.groups.not_in_creative_inventory = 1
|
||||
--local extra_desc = {}
|
||||
if mode == "sub" or state == mesecon.state.on then
|
||||
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
|
||||
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
|
||||
|
||||
minetest.register_node(nodename, nodedef)
|
||||
mcl_wip.register_wip_item(nodename)
|
||||
end
|
||||
|
||||
minetest.register_node(nodename, nodedef)
|
||||
mcl_wip.register_wip_item(nodename)
|
||||
end
|
||||
end
|
||||
|
||||
-- Register recipies
|
||||
@ -351,9 +351,9 @@ minetest.register_abm({
|
||||
-- Add entry aliases for the Help
|
||||
if minetest.get_modpath("doc") then
|
||||
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",
|
||||
"nodes", "mcl_comparators:comparator_on_comp")
|
||||
"nodes", "mcl_comparators:comparator_on_comp")
|
||||
doc.add_entry_alias("nodes", "mcl_comparators:comparator_off_comp",
|
||||
"nodes", "mcl_comparators:comparator_on_sub")
|
||||
"nodes", "mcl_comparators:comparator_on_sub")
|
||||
end
|
||||
|
@ -96,125 +96,127 @@ local dispenserdef = {
|
||||
end,
|
||||
_mcl_blast_resistance = 3.5,
|
||||
_mcl_hardness = 3.5,
|
||||
mesecons = {effector = {
|
||||
-- Dispense random item when triggered
|
||||
action_on = function (pos, node)
|
||||
local meta = minetest.get_meta(pos)
|
||||
local inv = meta:get_inventory()
|
||||
local droppos, dropdir
|
||||
if node.name == "mcl_dispensers:dispenser" then
|
||||
dropdir = vector.multiply(minetest.facedir_to_dir(node.param2), -1)
|
||||
droppos = vector.add(pos, dropdir)
|
||||
elseif node.name == "mcl_dispensers:dispenser_up" then
|
||||
dropdir = {x=0, y=1, z=0}
|
||||
droppos = {x=pos.x, y=pos.y+1, z=pos.z}
|
||||
elseif node.name == "mcl_dispensers:dispenser_down" then
|
||||
dropdir = {x=0, y=-1, z=0}
|
||||
droppos = {x=pos.x, y=pos.y-1, z=pos.z}
|
||||
end
|
||||
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})
|
||||
mesecons = {
|
||||
effector = {
|
||||
-- Dispense random item when triggered
|
||||
action_on = function (pos, node)
|
||||
local meta = minetest.get_meta(pos)
|
||||
local inv = meta:get_inventory()
|
||||
local droppos, dropdir
|
||||
if node.name == "mcl_dispensers:dispenser" then
|
||||
dropdir = vector.multiply(minetest.facedir_to_dir(node.param2), -1)
|
||||
droppos = vector.add(pos, dropdir)
|
||||
elseif node.name == "mcl_dispensers:dispenser_up" then
|
||||
dropdir = {x=0, y=1, z=0}
|
||||
droppos = {x=pos.x, y=pos.y+1, z=pos.z}
|
||||
elseif node.name == "mcl_dispensers:dispenser_down" then
|
||||
dropdir = {x=0, y=-1, z=0}
|
||||
droppos = {x=pos.x, y=pos.y-1, z=pos.z}
|
||||
end
|
||||
end
|
||||
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
|
||||
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
|
||||
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
|
||||
if igroups.armor then
|
||||
local droppos_below = {x = droppos.x, y = droppos.y - 1, z = droppos.z}
|
||||
-- Armor, mob heads and pumpkins
|
||||
if igroups.armor then
|
||||
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 _, obj in ipairs(objs) do
|
||||
stack = mcl_armor.equip(stack, obj)
|
||||
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
|
||||
stack = mcl_armor.equip(stack, obj)
|
||||
if stack:is_empty() then
|
||||
break
|
||||
end
|
||||
end
|
||||
if stack:is_empty() then
|
||||
break
|
||||
end
|
||||
end
|
||||
if stack:is_empty() then
|
||||
break
|
||||
end
|
||||
end
|
||||
|
||||
-- Place head or pumpkin as node, if equipping it as armor has failed
|
||||
if not stack:is_empty() then
|
||||
if igroups.head or iname == "mcl_farming:pumpkin_face" then
|
||||
if dropnodedef.buildable_to then
|
||||
minetest.set_node(droppos, {name = iname, param2 = node.param2})
|
||||
stack:take_item()
|
||||
-- Place head or pumpkin as node, if equipping it as armor has failed
|
||||
if not stack:is_empty() then
|
||||
if igroups.head or iname == "mcl_farming:pumpkin_face" then
|
||||
if dropnodedef.buildable_to then
|
||||
minetest.set_node(droppos, {name = iname, param2 = node.param2})
|
||||
stack:take_item()
|
||||
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)
|
||||
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()
|
||||
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)
|
||||
|
||||
-- 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()
|
||||
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,
|
||||
rules = mesecon.rules.alldirs,
|
||||
}},
|
||||
end,
|
||||
rules = mesecon.rules.alldirs,
|
||||
},
|
||||
},
|
||||
on_rotate = on_rotate,
|
||||
}
|
||||
|
||||
|
@ -11,7 +11,7 @@ local realtime = true
|
||||
local rules_flat = {
|
||||
{ x = 0, y = 0, z = -1, spread = true },
|
||||
}
|
||||
local get_rules_flat = function(node)
|
||||
local function get_rules_flat(node)
|
||||
local rules = rules_flat
|
||||
for i=1, node.param2 do
|
||||
rules = mesecon.rotate_rules_left(rules)
|
||||
@ -46,7 +46,7 @@ end
|
||||
-- and update the observer state if needed.
|
||||
-- TODO: Also scan metadata 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 front
|
||||
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
|
||||
|
||||
-- Vertical orientation (CURRENTLY DISABLED)
|
||||
local observer_orientate = function(pos, placer)
|
||||
local function observer_orientate(pos, placer)
|
||||
-- Not placed by player
|
||||
if not placer then return end
|
||||
|
||||
-- Placer pitch in degrees
|
||||
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
|
||||
-- Observer looking downwards
|
||||
minetest.set_node(pos, {name="mcl_observers:observer_down_off"})
|
||||
@ -104,162 +104,167 @@ local observer_orientate = function(pos, placer)
|
||||
end
|
||||
end
|
||||
|
||||
mesecon.register_node("mcl_observers:observer",
|
||||
{
|
||||
is_ground_content = false,
|
||||
sounds = mcl_sounds.node_sound_stone_defaults(),
|
||||
paramtype2 = "facedir",
|
||||
on_rotate = false,
|
||||
_mcl_blast_resistance = 3.5,
|
||||
_mcl_hardness = 3.5,
|
||||
},
|
||||
{
|
||||
description = S("Observer"),
|
||||
_tt_help = S("Emits redstone pulse when block in front changes"),
|
||||
_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."),
|
||||
mesecon.register_node("mcl_observers:observer", {
|
||||
is_ground_content = false,
|
||||
sounds = mcl_sounds.node_sound_stone_defaults(),
|
||||
paramtype2 = "facedir",
|
||||
on_rotate = false,
|
||||
_mcl_blast_resistance = 3.5,
|
||||
_mcl_hardness = 3.5,
|
||||
}, {
|
||||
description = S("Observer"),
|
||||
_tt_help = S("Emits redstone pulse when block in front changes"),
|
||||
_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, },
|
||||
tiles = {
|
||||
"mcl_observers_observer_top.png^[transformR180", "default_furnace_bottom.png",
|
||||
"mcl_observers_observer_side.png", "mcl_observers_observer_side.png",
|
||||
"mcl_observers_observer_front.png", "mcl_observers_observer_back.png",
|
||||
},
|
||||
mesecons = { receptor = {
|
||||
state = mesecon.state.off,
|
||||
rules = get_rules_flat,
|
||||
}},
|
||||
on_construct = function(pos)
|
||||
if not realtime then
|
||||
observer_scan(pos, true)
|
||||
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 },
|
||||
tiles = {
|
||||
"mcl_observers_observer_top.png^[transformR180", "default_furnace_bottom.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,
|
||||
rules = get_rules_flat,
|
||||
}},
|
||||
groups = {pickaxey=1, material_stone=1, not_opaque=1, },
|
||||
tiles = {
|
||||
"mcl_observers_observer_top.png^[transformR180", "default_furnace_bottom.png",
|
||||
"mcl_observers_observer_side.png", "mcl_observers_observer_side.png",
|
||||
"mcl_observers_observer_front.png", "mcl_observers_observer_back.png",
|
||||
},
|
||||
mesecons = {
|
||||
receptor = {
|
||||
state = mesecon.state.off,
|
||||
rules = get_rules_flat,
|
||||
},
|
||||
},
|
||||
on_construct = function(pos)
|
||||
if not realtime then
|
||||
observer_scan(pos, true)
|
||||
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 },
|
||||
tiles = {
|
||||
"mcl_observers_observer_top.png^[transformR180", "default_furnace_bottom.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,
|
||||
rules = get_rules_flat,
|
||||
}
|
||||
},
|
||||
|
||||
-- VERY quickly disable observer after construction
|
||||
on_construct = function(pos)
|
||||
local timer = minetest.get_node_timer(pos)
|
||||
timer:start(mcl_vars.redstone_tick)
|
||||
end,
|
||||
on_timer = function(pos, elapsed)
|
||||
local node = minetest.get_node(pos)
|
||||
minetest.set_node(pos, {name = "mcl_observers:observer_off", param2 = node.param2})
|
||||
mesecon.receptor_off(pos, get_rules_flat(node))
|
||||
end,
|
||||
}
|
||||
-- VERY quickly disable observer after construction
|
||||
on_construct = function(pos)
|
||||
local timer = minetest.get_node_timer(pos)
|
||||
timer:start(mcl_vars.redstone_tick)
|
||||
end,
|
||||
on_timer = function(pos, elapsed)
|
||||
local node = minetest.get_node(pos)
|
||||
minetest.set_node(pos, {name = "mcl_observers:observer_off", param2 = node.param2})
|
||||
mesecon.receptor_off(pos, get_rules_flat(node))
|
||||
end,
|
||||
}
|
||||
)
|
||||
|
||||
mesecon.register_node("mcl_observers:observer_down",
|
||||
{
|
||||
is_ground_content = false,
|
||||
sounds = mcl_sounds.node_sound_stone_defaults(),
|
||||
groups = {pickaxey=1, material_stone=1, not_opaque=1, not_in_creative_inventory=1 },
|
||||
on_rotate = false,
|
||||
_mcl_blast_resistance = 3.5,
|
||||
_mcl_hardness = 3.5,
|
||||
drop = "mcl_observers:observer_off",
|
||||
},
|
||||
{
|
||||
tiles = {
|
||||
"mcl_observers_observer_back.png", "mcl_observers_observer_front.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 = {
|
||||
state = mesecon.state.off,
|
||||
rules = rules_down,
|
||||
}},
|
||||
on_construct = function(pos)
|
||||
if not realtime then
|
||||
observer_scan(pos, true)
|
||||
end
|
||||
end,
|
||||
},
|
||||
{
|
||||
_doc_items_create_entry = false,
|
||||
tiles = {
|
||||
"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_top.png", "mcl_observers_observer_top.png",
|
||||
},
|
||||
mesecons = { receptor = {
|
||||
state = mesecon.state.on,
|
||||
rules = rules_down,
|
||||
}},
|
||||
mesecon.register_node("mcl_observers:observer_down", {
|
||||
is_ground_content = false,
|
||||
sounds = mcl_sounds.node_sound_stone_defaults(),
|
||||
groups = {pickaxey=1, material_stone=1, not_opaque=1, not_in_creative_inventory=1 },
|
||||
on_rotate = false,
|
||||
_mcl_blast_resistance = 3.5,
|
||||
_mcl_hardness = 3.5,
|
||||
drop = "mcl_observers:observer_off",
|
||||
}, {
|
||||
tiles = {
|
||||
"mcl_observers_observer_back.png", "mcl_observers_observer_front.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 = {
|
||||
state = mesecon.state.off,
|
||||
rules = rules_down,
|
||||
},
|
||||
},
|
||||
on_construct = function(pos)
|
||||
if not realtime then
|
||||
observer_scan(pos, true)
|
||||
end
|
||||
end,
|
||||
}, {
|
||||
_doc_items_create_entry = false,
|
||||
tiles = {
|
||||
"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_top.png", "mcl_observers_observer_top.png",
|
||||
},
|
||||
mesecons = {
|
||||
receptor = {
|
||||
state = mesecon.state.on,
|
||||
rules = rules_down,
|
||||
},
|
||||
},
|
||||
|
||||
-- VERY quickly disable observer after construction
|
||||
on_construct = function(pos)
|
||||
local timer = minetest.get_node_timer(pos)
|
||||
timer:start(mcl_vars.redstone_tick)
|
||||
end,
|
||||
on_timer = function(pos, elapsed)
|
||||
local node = minetest.get_node(pos)
|
||||
minetest.set_node(pos, {name = "mcl_observers:observer_down_off", param2 = node.param2})
|
||||
mesecon.receptor_off(pos, rules_down)
|
||||
end,
|
||||
})
|
||||
-- VERY quickly disable observer after construction
|
||||
on_construct = function(pos)
|
||||
local timer = minetest.get_node_timer(pos)
|
||||
timer:start(mcl_vars.redstone_tick)
|
||||
end,
|
||||
on_timer = function(pos, elapsed)
|
||||
local node = minetest.get_node(pos)
|
||||
minetest.set_node(pos, {name = "mcl_observers:observer_down_off", param2 = node.param2})
|
||||
mesecon.receptor_off(pos, rules_down)
|
||||
end,
|
||||
}
|
||||
)
|
||||
|
||||
mesecon.register_node("mcl_observers:observer_up",
|
||||
{
|
||||
is_ground_content = false,
|
||||
sounds = mcl_sounds.node_sound_stone_defaults(),
|
||||
groups = {pickaxey=1, material_stone=1, not_opaque=1, not_in_creative_inventory=1 },
|
||||
on_rotate = false,
|
||||
_mcl_blast_resistance = 3.5,
|
||||
_mcl_hardness = 3.5,
|
||||
drop = "mcl_observers:observer_off",
|
||||
},
|
||||
{
|
||||
tiles = {
|
||||
"mcl_observers_observer_front.png", "mcl_observers_observer_back.png",
|
||||
"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 = {
|
||||
state = mesecon.state.off,
|
||||
rules = rules_up,
|
||||
}},
|
||||
on_construct = function(pos)
|
||||
if not realtime then
|
||||
observer_scan(pos, true)
|
||||
end
|
||||
end,
|
||||
},
|
||||
{
|
||||
_doc_items_create_entry = false,
|
||||
tiles = {
|
||||
"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_top.png^[transformR180", "mcl_observers_observer_top.png^[transformR180",
|
||||
},
|
||||
mesecons = { receptor = {
|
||||
state = mesecon.state.on,
|
||||
rules = rules_up,
|
||||
}},
|
||||
mesecon.register_node("mcl_observers:observer_up", {
|
||||
is_ground_content = false,
|
||||
sounds = mcl_sounds.node_sound_stone_defaults(),
|
||||
groups = {pickaxey=1, material_stone=1, not_opaque=1, not_in_creative_inventory=1 },
|
||||
on_rotate = false,
|
||||
_mcl_blast_resistance = 3.5,
|
||||
_mcl_hardness = 3.5,
|
||||
drop = "mcl_observers:observer_off",
|
||||
}, {
|
||||
tiles = {
|
||||
"mcl_observers_observer_front.png", "mcl_observers_observer_back.png",
|
||||
"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 = {
|
||||
state = mesecon.state.off,
|
||||
rules = rules_up,
|
||||
},
|
||||
},
|
||||
on_construct = function(pos)
|
||||
if not realtime then
|
||||
observer_scan(pos, true)
|
||||
end
|
||||
end,
|
||||
}, {
|
||||
_doc_items_create_entry = false,
|
||||
tiles = {
|
||||
"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_top.png^[transformR180", "mcl_observers_observer_top.png^[transformR180",
|
||||
},
|
||||
mesecons = {
|
||||
receptor = {
|
||||
state = mesecon.state.on,
|
||||
rules = rules_up,
|
||||
},
|
||||
},
|
||||
|
||||
-- VERY quickly disable observer after construction
|
||||
on_construct = function(pos)
|
||||
local timer = minetest.get_node_timer(pos)
|
||||
timer:start(mcl_vars.redstone_tick)
|
||||
end,
|
||||
on_timer = function(pos, elapsed)
|
||||
minetest.set_node(pos, {name = "mcl_observers:observer_up_off"})
|
||||
mesecon.receptor_off(pos, rules_up)
|
||||
end,
|
||||
})
|
||||
-- VERY quickly disable observer after construction
|
||||
on_construct = function(pos)
|
||||
local timer = minetest.get_node_timer(pos)
|
||||
timer:start(mcl_vars.redstone_tick)
|
||||
end,
|
||||
on_timer = function(pos, elapsed)
|
||||
minetest.set_node(pos, {name = "mcl_observers:observer_up_off"})
|
||||
mesecon.receptor_off(pos, rules_up)
|
||||
end,
|
||||
}
|
||||
)
|
||||
|
||||
minetest.register_craft({
|
||||
output = "mcl_observers:observer_off",
|
||||
@ -267,7 +272,7 @@ minetest.register_craft({
|
||||
{ "mcl_core:cobble", "mcl_core:cobble", "mcl_core:cobble" },
|
||||
{ "mcl_nether:quartz", "mesecons:redstone", "mesecons:redstone" },
|
||||
{ "mcl_core:cobble", "mcl_core:cobble", "mcl_core:cobble" },
|
||||
}
|
||||
},
|
||||
})
|
||||
minetest.register_craft({
|
||||
output = "mcl_observers:observer_off",
|
||||
@ -275,7 +280,7 @@ minetest.register_craft({
|
||||
{ "mcl_core:cobble", "mcl_core:cobble", "mcl_core:cobble" },
|
||||
{ "mesecons:redstone", "mesecons:redstone", "mcl_nether:quartz" },
|
||||
{ "mcl_core:cobble", "mcl_core:cobble", "mcl_core:cobble" },
|
||||
}
|
||||
},
|
||||
})
|
||||
|
||||
if realtime then
|
||||
@ -454,7 +459,7 @@ minetest.register_lbm({
|
||||
"mcl_observers:observer_down_on",
|
||||
"mcl_observers:observer_up_on",
|
||||
},
|
||||
run_at_every_load = true,
|
||||
run_at_every_load = true,
|
||||
action = function(pos)
|
||||
minetest.after(1, mcl_observers.observer_activate, {x=pos.x, y=pos.y, z=pos.z})
|
||||
end,
|
||||
|
@ -329,7 +329,7 @@ function mesecon.get_conductor_on(node_off, rulename)
|
||||
return conductor.states[tonumber(binstate,2)+1]
|
||||
end
|
||||
end
|
||||
return offstate
|
||||
return conductor.offstate
|
||||
end
|
||||
|
||||
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]
|
||||
end
|
||||
end
|
||||
return onstate
|
||||
return conductor.onstate
|
||||
end
|
||||
|
||||
function mesecon.conductor_get_rules(node)
|
||||
@ -391,9 +391,7 @@ function mesecon.turnon(pos, link)
|
||||
local f = table.remove(frontiers, 1)
|
||||
local node = get_node_force(f.pos)
|
||||
|
||||
if not node then
|
||||
-- Area does not exist; do nothing
|
||||
elseif mesecon.is_conductor_off(node, f.link) then
|
||||
if node and mesecon.is_conductor_off(node, f.link) then
|
||||
local rules = mesecon.conductor_get_rules(node)
|
||||
|
||||
-- Call turnon on neighbors
|
||||
@ -453,9 +451,7 @@ function mesecon.turnoff(pos, link)
|
||||
local f = table.remove(frontiers, 1)
|
||||
local node = get_node_force(f.pos)
|
||||
|
||||
if not node then
|
||||
-- No-op
|
||||
elseif mesecon.is_conductor_on(node, f.link) then
|
||||
if node and mesecon.is_conductor_on(node, f.link) then
|
||||
local rules = mesecon.conductor_get_rules(node)
|
||||
for _, r in pairs(mesecon.rule2meta(f.link, rules)) do
|
||||
local np = vector.add(f.pos, r)
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user