Merge branch 'master' into mobs

This commit is contained in:
Elias Fleckenstein 2021-10-24 22:56:54 +02:00
commit c7a1734220
No known key found for this signature in database
GPG Key ID: 06927A5199D6C9B2
498 changed files with 11683 additions and 4774 deletions

2
.gitignore vendored Normal file

@ -0,0 +1,2 @@
# Text Editor TMP Files
*.swp

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

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

@ -22,6 +22,7 @@
* Nicu * Nicu
* aligator * aligator
* Code-Sploit * Code-Sploit
* NO11
## Contributors ## Contributors
* Laurent Rocher * Laurent Rocher
@ -40,7 +41,6 @@
* Jared Moody * Jared Moody
* Li0n * Li0n
* Midgard * Midgard
* NO11
* Saku Laesvuori * Saku Laesvuori
* Yukitty * Yukitty
* ZedekThePD * ZedekThePD
@ -102,6 +102,7 @@
* leorockway * leorockway
* xMrVizzy * xMrVizzy
* yutyo * yutyo
* NO11
## Translations ## Translations
* Wuzzy * Wuzzy

@ -149,7 +149,7 @@ These groups are used mostly for informational purposes
* `trapdoor=2`: Open trapdoor * `trapdoor=2`: Open trapdoor
* `glass=1`: Glass (full cubes only) * `glass=1`: Glass (full cubes only)
* `rail=1`: Rail * `rail=1`: Rail
* `music_record`: Music Disc (rating is track ID) * `music_record`: Item is Music Disc
* `tnt=1`: Block is TNT * `tnt=1`: Block is TNT
* `boat=1`: Boat * `boat=1`: Boat
* `minecart=1`: Minecart * `minecart=1`: Minecart

@ -1,5 +1,3 @@
# (Currently in feature freeze)
# MineClone 2 # MineClone 2
An unofficial Minecraft-like game for Minetest. Forked from MineClone by davedevils. An unofficial Minecraft-like game for Minetest. Forked from MineClone by davedevils.
Developed by many people. Not developed or endorsed by Mojang AB. Developed by many people. Not developed or endorsed by Mojang AB.
@ -77,15 +75,16 @@ To install MineClone 2 (if you haven't already), move this directory into the
“games” directory of your Minetest data directory. Consult the help of “games” directory of your Minetest data directory. Consult the help of
Minetest to learn more. Minetest to learn more.
## Reporting bugs ## Useful links
Please report all bugs and missing Minecraft features here: The MineClone2 repository is hosted at Mesehub. To contribute or report issues, head there.
<https://git.minetest.land/MineClone2/MineClone2/issues> * Mesehub: <https://git.minetest.land/MineClone2/MineClone2>
* Discord: <https://discord.gg/xE4z8EEpDC>
## Chating with the community * YouTube <https://www.youtube.com/channel/UClI_YcsXMF3KNeJtoBfnk9A>
Join our discord server at: * IRC: <https://web.libera.chat/#mineclone2>
* Matrix: <https://app.element.io/#/room/#mc2:matrix.org>
<https://discord.gg/84GKcxczG3> * Reddit: <https://www.reddit.com/r/MineClone2/>
* Minetest forums: <https://forum.minetest.net/viewtopic.php?f=50&t=16407>
## Project description ## Project description
The main goal of **MineClone 2** is to be a clone of Minecraft and to be released as free software. The main goal of **MineClone 2** is to be a clone of Minecraft and to be released as free software.

BIN
menu/Header.blend Normal file

Binary file not shown.

@ -83,7 +83,7 @@ local function get_hardness_values_for_groups()
for _, ndef in pairs(minetest.registered_nodes) do for _, ndef in pairs(minetest.registered_nodes) do
for g, _ in pairs(mcl_autogroup.registered_diggroups) do for g, _ in pairs(mcl_autogroup.registered_diggroups) do
if ndef.groups[g] ~= nil then if ndef.groups[g] then
maps[g][ndef._mcl_hardness or 0] = true maps[g][ndef._mcl_hardness or 0] = true
end end
end end
@ -121,7 +121,7 @@ local hardness_values = get_hardness_values_for_groups()
-- hardness_value. Used for quick lookup. -- hardness_value. Used for quick lookup.
local hardness_lookup = get_hardness_lookup_for_groups(hardness_values) local hardness_lookup = get_hardness_lookup_for_groups(hardness_values)
local function compute_creativetimes(group) --[[local function compute_creativetimes(group)
local creativetimes = {} local creativetimes = {}
for index, hardness in pairs(hardness_values[group]) do for index, hardness in pairs(hardness_values[group]) do
@ -129,7 +129,7 @@ local function compute_creativetimes(group)
end end
return creativetimes return creativetimes
end end]]
-- Get the list of digging times for using a specific tool on a specific -- Get the list of digging times for using a specific tool on a specific
-- diggroup. -- diggroup.
@ -207,6 +207,10 @@ end
function mcl_autogroup.can_harvest(nodename, toolname) function mcl_autogroup.can_harvest(nodename, toolname)
local ndef = minetest.registered_nodes[nodename] local ndef = minetest.registered_nodes[nodename]
if not ndef then
return false
end
if minetest.get_item_group(nodename, "dig_immediate") >= 2 then if minetest.get_item_group(nodename, "dig_immediate") >= 2 then
return true return true
end end
@ -239,13 +243,13 @@ function mcl_autogroup.can_harvest(nodename, toolname)
end end
-- Get one groupcap field for using a specific tool on a specific group. -- Get one groupcap field for using a specific tool on a specific group.
local function get_groupcap(group, can_harvest, multiplier, efficiency, uses) --[[local function get_groupcap(group, can_harvest, multiplier, efficiency, uses)
return { return {
times = get_digtimes(group, can_harvest, multiplier, efficiency), times = get_digtimes(group, can_harvest, multiplier, efficiency),
uses = uses, uses = uses,
maxlevel = 0, maxlevel = 0,
} }
end end]]
-- Returns the tool_capabilities from a tool definition or a default set of -- Returns the tool_capabilities from a tool definition or a default set of
-- tool_capabilities -- tool_capabilities
@ -298,7 +302,7 @@ function mcl_autogroup.get_wear(toolname, diggroup)
return math.ceil(65535 / uses) return math.ceil(65535 / uses)
end end
local overwrite = function() local function overwrite()
for nname, ndef in pairs(minetest.registered_nodes) do for nname, ndef in pairs(minetest.registered_nodes) do
local newgroups = table.copy(ndef.groups) local newgroups = table.copy(ndef.groups)
if (nname ~= "ignore" and ndef.diggable) then if (nname ~= "ignore" and ndef.diggable) then
@ -315,12 +319,12 @@ local overwrite = function()
newgroups.opaque = 1 newgroups.opaque = 1
end end
local creative_breakable = false --local creative_breakable = false
-- Assign groups used for digging this node depending on -- Assign groups used for digging this node depending on
-- the registered digging groups -- the registered digging groups
for g, gdef in pairs(mcl_autogroup.registered_diggroups) do for g, gdef in pairs(mcl_autogroup.registered_diggroups) do
creative_breakable = true --creative_breakable = true
local index = hardness_lookup[g][ndef._mcl_hardness or 0] local index = hardness_lookup[g][ndef._mcl_hardness or 0]
if ndef.groups[g] then if ndef.groups[g] then
if gdef.levels then if gdef.levels then

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

@ -1,6 +1,8 @@
local get_connected_players = minetest.get_connected_players local get_connected_players = minetest.get_connected_players
local clock = os.clock local clock = os.clock
local pairs = pairs
controls = {} controls = {}
controls.players = {} controls.players = {}
@ -20,15 +22,15 @@ function controls.register_on_hold(func)
end end
local known_controls = { local known_controls = {
jump=true, jump = true,
right=true, right = true,
left=true, left = true,
LMB=true, LMB = true,
RMB=true, RMB = true,
sneak=true, sneak = true,
aux1=true, aux1 = true,
down=true, down = true,
up=true, up = true,
} }
minetest.register_on_joinplayer(function(player) minetest.register_on_joinplayer(function(player)
@ -52,17 +54,17 @@ minetest.register_globalstep(function(dtime)
for cname, cbool in pairs(player_controls) do for cname, cbool in pairs(player_controls) do
if known_controls[cname] == true then if known_controls[cname] == true then
--Press a key --Press a key
if cbool==true and controls.players[player_name][cname][1]==false then if cbool == true and controls.players[player_name][cname][1] == false then
for _, func in pairs(controls.registered_on_press) do for _, func in pairs(controls.registered_on_press) do
func(player, cname) func(player, cname)
end end
controls.players[player_name][cname] = {true, clock()} controls.players[player_name][cname] = {true, clock()}
elseif cbool==true and controls.players[player_name][cname][1]==true then elseif cbool == true and controls.players[player_name][cname][1] == true then
for _, func in pairs(controls.registered_on_hold) do for _, func in pairs(controls.registered_on_hold) do
func(player, cname, clock()-controls.players[player_name][cname][2]) func(player, cname, clock()-controls.players[player_name][cname][2])
end end
--Release a key --Release a key
elseif cbool==false and controls.players[player_name][cname][1]==true then elseif cbool == false and controls.players[player_name][cname][1] == true then
for _, func in pairs(controls.registered_on_release) do for _, func in pairs(controls.registered_on_release) do
func(player, cname, clock()-controls.players[player_name][cname][2]) func(player, cname, clock()-controls.players[player_name][cname][2])
end end

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

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

@ -12,10 +12,12 @@ under the LGPLv2.1 license.
mcl_explosions = {} mcl_explosions = {}
local mod_fire = minetest.get_modpath("mcl_fire") ~= nil local mod_fire = minetest.get_modpath("mcl_fire")
local CONTENT_FIRE = minetest.get_content_id("mcl_fire:fire") --local CONTENT_FIRE = minetest.get_content_id("mcl_fire:fire")
local S = minetest.get_translator("mcl_explosions") local math = math
local vector = vector
local table = table
local hash_node_position = minetest.hash_node_position local hash_node_position = minetest.hash_node_position
local get_objects_inside_radius = minetest.get_objects_inside_radius local get_objects_inside_radius = minetest.get_objects_inside_radius
@ -26,6 +28,7 @@ local get_voxel_manip = minetest.get_voxel_manip
local bulk_set_node = minetest.bulk_set_node local bulk_set_node = minetest.bulk_set_node
local check_for_falling = minetest.check_for_falling local check_for_falling = minetest.check_for_falling
local add_item = minetest.add_item local add_item = minetest.add_item
local pos_to_string = minetest.pos_to_string
-- Saved sphere explosion shapes for various radiuses -- Saved sphere explosion shapes for various radiuses
local sphere_shapes = {} local sphere_shapes = {}
@ -66,50 +69,48 @@ local function compute_sphere_rays(radius)
local rays = {} local rays = {}
local sphere = {} local sphere = {}
for i=1, 2 do local function add_ray(pos)
sphere[hash_node_position(pos)] = pos
end
for y = -radius, radius do for y = -radius, radius do
for z = -radius, radius do for z = -radius, radius do
for x = -radius, 0, 1 do for x = -radius, 0 do
local d = x * x + y * y + z * z local d = x * x + y * y + z * z
if d <= radius * radius then if d <= radius * radius then
local pos = { x = x, y = y, z = z } add_ray(vector.new(x, y, z))
sphere[hash_node_position(pos)] = pos add_ray(vector.new(-x, y, z))
break break
end end
end end
end end
end end
end
for i=1,2 do
for x = -radius, radius do for x = -radius, radius do
for z = -radius, radius do for z = -radius, radius do
for y = -radius, 0, 1 do for y = -radius, 0 do
local d = x * x + y * y + z * z local d = x * x + y * y + z * z
if d <= radius * radius then if d <= radius * radius then
local pos = { x = x, y = y, z = z } add_ray(vector.new(x, y, z))
sphere[hash_node_position(pos)] = pos add_ray(vector.new(x, -y, z))
break break
end end
end end
end end
end end
end
for i=1,2 do
for x = -radius, radius do for x = -radius, radius do
for y = -radius, radius do for y = -radius, radius do
for z = -radius, 0, 1 do for z = -radius, 0 do
local d = x * x + y * y + z * z local d = x * x + y * y + z * z
if d <= radius * radius then if d <= radius * radius then
local pos = { x = x, y = y, z = z } add_ray(vector.new(x, y, z))
sphere[hash_node_position(pos)] = pos add_ray(vector.new(x, y, -z))
break break
end end
end end
end end
end end
end
for _, pos in pairs(sphere) do for _, pos in pairs(sphere) do
rays[#rays + 1] = vector.normalize(pos) rays[#rays + 1] = vector.normalize(pos)
@ -176,14 +177,11 @@ local function trace_explode(pos, strength, raydirs, radius, info, direct, sourc
local ystride = (emax.x - emin_x + 1) local ystride = (emax.x - emin_x + 1)
local zstride = ystride * (emax.y - emin_y + 1) local zstride = ystride * (emax.y - emin_y + 1)
local pos_x = pos.x
local pos_y = pos.y
local pos_z = pos.z
local area = VoxelArea:new { --[[local area = VoxelArea:new {
MinEdge = emin, MinEdge = emin,
MaxEdge = emax MaxEdge = emax
} }]]
local data = vm:get_data() local data = vm:get_data()
local destroy = {} local destroy = {}
@ -247,7 +245,7 @@ local function trace_explode(pos, strength, raydirs, radius, info, direct, sourc
local ent = obj:get_luaentity() local ent = obj:get_luaentity()
-- Ignore items to lower lag -- Ignore items to lower lag
if (obj:is_player() or (ent and ent.name ~= '__builtin.item')) and obj:get_hp() > 0 then if (obj:is_player() or (ent and ent.name ~= "__builtin.item")) and obj:get_hp() > 0 then
local opos = obj:get_pos() local opos = obj:get_pos()
local collisionbox = nil local collisionbox = nil
@ -260,12 +258,12 @@ local function trace_explode(pos, strength, raydirs, radius, info, direct, sourc
if collisionbox then if collisionbox then
-- Create rays from random points in the collision box -- Create rays from random points in the collision box
local x1 = collisionbox[1] * 2 local x1 = collisionbox[1]
local y1 = collisionbox[2] * 2 local y1 = collisionbox[2]
local z1 = collisionbox[3] * 2 local z1 = collisionbox[3]
local x2 = collisionbox[4] * 2 local x2 = collisionbox[4]
local y2 = collisionbox[5] * 2 local y2 = collisionbox[5]
local z2 = collisionbox[6] * 2 local z2 = collisionbox[6]
local x_len = math.abs(x2 - x1) local x_len = math.abs(x2 - x1)
local y_len = math.abs(y2 - y1) local y_len = math.abs(y2 - y1)
local z_len = math.abs(z2 - z1) local z_len = math.abs(z2 - z1)
@ -363,9 +361,9 @@ local function trace_explode(pos, strength, raydirs, radius, info, direct, sourc
local on_blast = node_on_blast[data[idx]] local on_blast = node_on_blast[data[idx]]
local remove = true local remove = true
if do_drop or on_blast ~= nil then if do_drop or on_blast then
local npos = get_position_from_hash(hash) local npos = get_position_from_hash(hash)
if on_blast ~= nil then if on_blast then
on_blast(npos, 1.0, do_drop) on_blast(npos, 1.0, do_drop)
remove = false remove = false
else else
@ -407,8 +405,7 @@ local function trace_explode(pos, strength, raydirs, radius, info, direct, sourc
end end
-- Log explosion -- Log explosion
minetest.log('action', 'Explosion at ' .. minetest.pos_to_string(pos) .. minetest.log("action", "Explosion at "..pos_to_string(pos).." with strength "..strength.." and radius "..radius)
' with strength ' .. strength .. ' and radius ' .. radius)
end end
-- Create an explosion with strength at pos. -- Create an explosion with strength at pos.

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

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

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

@ -32,9 +32,9 @@ local singlenode = mg_name == "singlenode"
-- Calculate mapgen_edge_min/mapgen_edge_max -- Calculate mapgen_edge_min/mapgen_edge_max
mcl_vars.chunksize = math.max(1, tonumber(minetest.get_mapgen_setting("chunksize")) or 5) mcl_vars.chunksize = math.max(1, tonumber(minetest.get_mapgen_setting("chunksize")) or 5)
mcl_vars.MAP_BLOCKSIZE = math.max(1, core.MAP_BLOCKSIZE or 16) mcl_vars.MAP_BLOCKSIZE = math.max(1, minetest.MAP_BLOCKSIZE or 16)
mcl_vars.mapgen_limit = math.max(1, tonumber(minetest.get_mapgen_setting("mapgen_limit")) or 31000) mcl_vars.mapgen_limit = math.max(1, tonumber(minetest.get_mapgen_setting("mapgen_limit")) or 31000)
mcl_vars.MAX_MAP_GENERATION_LIMIT = math.max(1, core.MAX_MAP_GENERATION_LIMIT or 31000) mcl_vars.MAX_MAP_GENERATION_LIMIT = math.max(1, minetest.MAX_MAP_GENERATION_LIMIT or 31000)
local central_chunk_offset = -math.floor(mcl_vars.chunksize / 2) local central_chunk_offset = -math.floor(mcl_vars.chunksize / 2)
mcl_vars.central_chunk_offset_in_nodes = central_chunk_offset * mcl_vars.MAP_BLOCKSIZE mcl_vars.central_chunk_offset_in_nodes = central_chunk_offset * mcl_vars.MAP_BLOCKSIZE
mcl_vars.chunk_size_in_nodes = mcl_vars.chunksize * mcl_vars.MAP_BLOCKSIZE mcl_vars.chunk_size_in_nodes = mcl_vars.chunksize * mcl_vars.MAP_BLOCKSIZE

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

@ -1,3 +1,12 @@
local vector = vector
local table = table
local hash_node_position = minetest.hash_node_position
local add_particlespawner = minetest.add_particlespawner
local delete_particlespawner = minetest.delete_particlespawner
local ipairs = ipairs
mcl_particles = {} mcl_particles = {}
-- Table of particlespawner IDs on a per-node hash basis -- Table of particlespawner IDs on a per-node hash basis
@ -32,11 +41,11 @@ function mcl_particles.add_node_particlespawner(pos, particlespawner_definition,
if allowed_level == 0 or levels[level] > allowed_level then if allowed_level == 0 or levels[level] > allowed_level then
return return
end end
local poshash = minetest.hash_node_position(pos) local poshash = hash_node_position(pos)
if not poshash then if not poshash then
return return
end end
local id = minetest.add_particlespawner(particlespawner_definition) local id = add_particlespawner(particlespawner_definition)
if id == -1 then if id == -1 then
return return
end end
@ -47,6 +56,8 @@ function mcl_particles.add_node_particlespawner(pos, particlespawner_definition,
return id return id
end end
local add_node_particlespawner = mcl_particles.add_node_particlespawner
-- Deletes all particlespawners that are assigned to a node position. -- Deletes all particlespawners that are assigned to a node position.
-- If no particlespawners exist for this position, nothing happens. -- If no particlespawners exist for this position, nothing happens.
-- pos: Node positon. MUST use integer values! -- pos: Node positon. MUST use integer values!
@ -55,11 +66,11 @@ function mcl_particles.delete_node_particlespawners(pos)
if allowed_level == 0 then if allowed_level == 0 then
return false return false
end end
local poshash = minetest.hash_node_position(pos) local poshash = hash_node_position(pos)
local ids = particle_nodes[poshash] local ids = particle_nodes[poshash]
if ids then if ids then
for i=1, #ids do for i=1, #ids do
minetest.delete_particlespawner(ids[i]) delete_particlespawner(ids[i])
end end
particle_nodes[poshash] = nil particle_nodes[poshash] = nil
return true return true

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.3 KiB

@ -150,7 +150,7 @@ function mcl_util.get_eligible_transfer_item_slot(src_inventory, src_list, dst_i
end end
-- Returns true if itemstack is a shulker box -- Returns true if itemstack is a shulker box
local is_not_shulker_box = function(itemstack) local function is_not_shulker_box(itemstack)
local g = minetest.get_item_group(itemstack:get_name(), "shulker_box") local g = minetest.get_item_group(itemstack:get_name(), "shulker_box")
return g == 0 or g == nil return g == 0 or g == nil
end end
@ -212,7 +212,7 @@ function mcl_util.move_item_container(source_pos, destination_pos, source_list,
end end
-- Normalize double container by forcing to always use the left segment first -- Normalize double container by forcing to always use the left segment first
local normalize_double_container = function(pos, node, ctype) local function normalize_double_container(pos, node, ctype)
if ctype == 6 then if ctype == 6 then
pos = mcl_util.get_double_container_neighbor_pos(pos, node.param2, "right") pos = mcl_util.get_double_container_neighbor_pos(pos, node.param2, "right")
if not pos then if not pos then
@ -456,14 +456,7 @@ function mcl_util.calculate_durability(itemstack)
end end
end end
end end
if not uses then uses = uses or (next(itemstack:get_tool_capabilities().groupcaps) or {}).uses
local toolcaps = itemstack:get_tool_capabilities()
local groupcaps = toolcaps.groupcaps
for _, v in pairs(groupcaps) do
uses = v.uses
break
end
end
end end
return uses or 0 return uses or 0
@ -535,3 +528,12 @@ function mcl_util.get_object_name(object)
return luaentity.nametag and luaentity.nametag ~= "" and luaentity.nametag or luaentity.description or luaentity.name return luaentity.nametag and luaentity.nametag ~= "" and luaentity.nametag or luaentity.description or luaentity.name
end end
end end
function mcl_util.replace_mob(obj, mob)
local rot = obj:get_yaw()
local pos = obj:get_pos()
obj:remove()
obj = minetest.add_entity(pos, mob)
obj:set_yaw(rot)
return obj
end

@ -61,20 +61,21 @@ In mc, you cant use clock in the nether and the end.
* pos: position * pos: position
## mcl_worlds.register_on_dimension_change(function(player, dimension)) ## mcl_worlds.register_on_dimension_change(function(player, dimension, last_dimension))
Register a callback function func(player, dimension). Register a callback function func(player, dimension).
It will be called whenever a player changes between dimensions. It will be called whenever a player changes between dimensions.
The void counts as dimension. The void counts as dimension.
* player: player, the player who changed the dimension * player: player, the player who changed of dimension
* dimension: position, The new dimension of the player ("overworld", "nether", "end", "void"). * dimension: string, The new dimension of the player ("overworld", "nether", "end", "void").
* last_dimension: string, The dimension where the player was ("overworld", "nether", "end", "void").
## mcl_worlds.registered_on_dimension_change ## mcl_worlds.registered_on_dimension_change
Table containing all function registered with mcl_worlds.register_on_dimension_change() Table containing all function registered with mcl_worlds.register_on_dimension_change()
## mcl_worlds.dimension_change(player, dimension) ## mcl_worlds.dimension_change(player, dimension)
Notify this mod of a dimmension change of <player> to <dimension> Notify this mod of a dimension change of <player> to <dimension>
* player: player, player who changed the dimension * player: player, player who changed the dimension
* dimension: string, new dimension ("overworld", "nether", "end", "void") * dimension: string, new dimension ("overworld", "nether", "end", "void")

@ -1,5 +1,7 @@
mcl_worlds = {} mcl_worlds = {}
local get_connected_players = minetest.get_connected_players
-- For a given position, returns a 2-tuple: -- For a given position, returns a 2-tuple:
-- 1st return value: true if pos is in void -- 1st return value: true if pos is in void
-- 2nd return value: true if it is in the deadly part of the void -- 2nd return value: true if it is in the deadly part of the void
@ -44,12 +46,16 @@ function mcl_worlds.y_to_layer(y)
end end
end end
local y_to_layer = mcl_worlds.y_to_layer
-- Takes a pos and returns the dimension it belongs to (same as above) -- Takes a pos and returns the dimension it belongs to (same as above)
function mcl_worlds.pos_to_dimension(pos) function mcl_worlds.pos_to_dimension(pos)
local _, dim = mcl_worlds.y_to_layer(pos.y) local _, dim = y_to_layer(pos.y)
return dim return dim
end end
local pos_to_dimension = mcl_worlds.pos_to_dimension
-- Takes a Minecraft layer and a “dimension” name -- Takes a Minecraft layer and a “dimension” name
-- and returns the corresponding Y coordinate for -- and returns the corresponding Y coordinate for
-- MineClone 2. -- MineClone 2.
@ -112,12 +118,15 @@ local last_dimension = {}
-- * player: Player who changed the dimension -- * player: Player who changed the dimension
-- * dimension: New dimension ("overworld", "nether", "end", "void") -- * dimension: New dimension ("overworld", "nether", "end", "void")
function mcl_worlds.dimension_change(player, dimension) function mcl_worlds.dimension_change(player, dimension)
local playername = player:get_player_name()
for i=1, #mcl_worlds.registered_on_dimension_change do for i=1, #mcl_worlds.registered_on_dimension_change do
mcl_worlds.registered_on_dimension_change[i](player, dimension) mcl_worlds.registered_on_dimension_change[i](player, dimension, last_dimension[playername])
last_dimension[player:get_player_name()] = dimension
end end
last_dimension[playername] = dimension
end end
local dimension_change = mcl_worlds.dimension_change
----------------------- INTERNAL STUFF ---------------------- ----------------------- INTERNAL STUFF ----------------------
-- Update the dimension callbacks every DIM_UPDATE seconds -- Update the dimension callbacks every DIM_UPDATE seconds
@ -125,19 +134,19 @@ local DIM_UPDATE = 1
local dimtimer = 0 local dimtimer = 0
minetest.register_on_joinplayer(function(player) minetest.register_on_joinplayer(function(player)
last_dimension[player:get_player_name()] = mcl_worlds.pos_to_dimension(player:get_pos()) last_dimension[player:get_player_name()] = pos_to_dimension(player:get_pos())
end) end)
minetest.register_globalstep(function(dtime) minetest.register_globalstep(function(dtime)
-- regular updates based on iterval -- regular updates based on iterval
dimtimer = dimtimer + dtime; dimtimer = dimtimer + dtime;
if dimtimer >= DIM_UPDATE then if dimtimer >= DIM_UPDATE then
local players = minetest.get_connected_players() local players = get_connected_players()
for p=1, #players do for p = 1, #players do
local dim = mcl_worlds.pos_to_dimension(players[p]:get_pos()) local dim = pos_to_dimension(players[p]:get_pos())
local name = players[p]:get_player_name() local name = players[p]:get_player_name()
if dim ~= last_dimension[name] then if dim ~= last_dimension[name] then
mcl_worlds.dimension_change(players[p], dim) dimension_change(players[p], dim)
end end
end end
dimtimer = 0 dimtimer = 0

@ -4,6 +4,7 @@ local get_connected_players = minetest.get_connected_players
local get_node = minetest.get_node local get_node = minetest.get_node
local vector_add = vector.add local vector_add = vector.add
local ceil = math.ceil local ceil = math.ceil
local pairs = pairs
walkover = {} walkover = {}
walkover.registered_globals = {} walkover.registered_globals = {}
@ -34,11 +35,9 @@ minetest.register_globalstep(function(dtime)
local pp = player:get_pos() local pp = player:get_pos()
pp.y = ceil(pp.y) pp.y = ceil(pp.y)
local loc = vector_add(pp, {x=0,y=-1,z=0}) local loc = vector_add(pp, {x=0,y=-1,z=0})
if loc ~= nil then if loc then
local nodeiamon = get_node(loc) local nodeiamon = get_node(loc)
if nodeiamon then
if nodeiamon ~= nil then
if on_walk[nodeiamon.name] then if on_walk[nodeiamon.name] then
on_walk[nodeiamon.name](loc, nodeiamon, player) on_walk[nodeiamon.name](loc, nodeiamon, player)
end end
@ -48,7 +47,6 @@ minetest.register_globalstep(function(dtime)
end end
end end
end end
timer = 0 timer = 0
end end
end) end)

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

@ -1,4 +1,4 @@
local S = minetest.get_translator("mcl_boats") local S = minetest.get_translator(minetest.get_current_modname())
local boat_visual_size = {x = 1, y = 1, z = 1} local boat_visual_size = {x = 1, y = 1, z = 1}
local paddling_speed = 22 local paddling_speed = 22
@ -270,10 +270,10 @@ function boat.on_step(self, dtime, moveresult)
p.y = p.y - boat_y_offset p.y = p.y - boat_y_offset
local new_velo local new_velo
local new_acce = {x = 0, y = 0, z = 0} local new_acce
if not is_water(p) and not on_ice then if not is_water(p) and not on_ice then
-- Not on water or inside water: Free fall -- Not on water or inside water: Free fall
local nodedef = minetest.registered_nodes[minetest.get_node(p).name] --local nodedef = minetest.registered_nodes[minetest.get_node(p).name]
new_acce = {x = 0, y = -9.8, z = 0} new_acce = {x = 0, y = -9.8, z = 0}
new_velo = get_velocity(self._v, self.object:get_yaw(), new_velo = get_velocity(self._v, self.object:get_yaw(),
self.object:get_velocity().y) self.object:get_velocity().y)
@ -412,6 +412,6 @@ minetest.register_craft({
burntime = 20, burntime = 20,
}) })
if minetest.get_modpath("doc_identifier") ~= nil then if minetest.get_modpath("doc_identifier") then
doc.sub.identifier.register_object("mcl_boats:boat", "craftitems", "mcl_boats:boat") doc.sub.identifier.register_object("mcl_boats:boat", "craftitems", "mcl_boats:boat")
end end

@ -6,6 +6,7 @@ Boats are used to travel on the surface of water.=Les bateaux sont utilisés pou
Dark Oak Boat=Bateau en Chêne Noir Dark Oak Boat=Bateau en Chêne Noir
Jungle Boat=Bateau en Acajou Jungle Boat=Bateau en Acajou
Oak Boat=Bateau en Chêne Oak Boat=Bateau en Chêne
Rightclick on a water source to place the boat. Rightclick the boat to enter it. Use [Left] and [Right] to steer, [Forwards] to speed up and [Backwards] to slow down or move backwards. Rightclick the boat again to leave it, punch the boat to make it drop as an item.=Faites un clic droit sur une source d'eau pour placer le bateau. Faites un clic droit sur le bateau pour y entrer. Utilisez [Gauche] et [Droite] pour diriger, [Avant] pour accélérer et [Arrière] pour ralentir ou reculer. Cliquez de nouveau avec le bouton droit sur le bateau pour le quitter, frappez le bateau pour le faire tomber en tant qu'objet. Rightclick on a water source to place the boat. Rightclick the boat to enter it. Use [Left] and [Right] to steer, [Forwards] to speed up and [Backwards] to slow down or move backwards. Use [Sneak] to leave the boat, punch the boat to make it drop as an item.=Faites un clic droit sur une source d'eau pour placer le bateau. Faites un clic droit sur le bateau pour y entrer. Utilisez [Gauche] et [Droite] pour diriger, [Avant] pour accélérer et [Arrière] pour ralentir ou reculer. Utilisez [Sneak] pour le quitter, frappez le bateau pour le faire tomber en tant qu'objet.
Spruce Boat=Bateau en Sapin Spruce Boat=Bateau en Sapin
Water vehicle=Véhicule aquatique Water vehicle=Véhicule aquatique
Sneak to dismount=

@ -0,0 +1,12 @@
# textdomain: mcl_boats
Acacia Boat=Akacjowa łódź
Birch Boat=Brzozowa łódź
Boat=Łódź
Boats are used to travel on the surface of water.=Łodzie są wykorzystywane do podróżowania po powierzchni wody.
Dark Oak Boat=Ciemno-dębowa łódź
Jungle Boat=Tropikalna łódź
Oak Boat=Dębowa łódź
Rightclick on a water source to place the boat. Rightclick the boat to enter it. Use [Left] and [Right] to steer, [Forwards] to speed up and [Backwards] to slow down or move backwards. Use [Sneak] to leave the boat, punch the boat to make it drop as an item.=Kliknij prawym przyciskiem myszy na źródło wody by postawić łódź. Kliknij prawym przyciskiem myszy by w nią wsiąść. Użyj przycisków [Lewy] oraz [Prawy] by sterować, [Naprzód] by przyspieszyć i [W tył] by zwolnić lub się cofać. Kliknij [Skradanie] by z niej wyjść, uderz ją by wziąć ją jako przedmiot.
Spruce Boat=Świerkowa łódź
Water vehicle=Pojazd wodny
Sneak to dismount=Skradaj się by opuścić łódź

@ -1,7 +1,7 @@
name = mcl_boats name = mcl_boats
author = PilzAdam author = PilzAdam
description = Adds drivable boats. description = Adds drivable boats.
depends = mcl_player, flowlib depends = mcl_player, flowlib, mcl_title
optional_depends = mcl_core, doc_identifier optional_depends = mcl_core, doc_identifier

@ -1,5 +1,3 @@
local S = minetest.get_translator("mcl_burning")
function mcl_burning.get_storage(obj) function mcl_burning.get_storage(obj)
if obj:is_player() then if obj:is_player() then
return mcl_burning.storage[obj] return mcl_burning.storage[obj]
@ -79,22 +77,15 @@ function mcl_burning.set_on_fire(obj, burn_time)
end end
if not storage.burn_time or burn_time >= storage.burn_time then if not storage.burn_time or burn_time >= storage.burn_time then
if obj:is_player() and not storage.fire_hud_id then if obj:is_player() then
storage.fire_hud_id = obj:hud_add({ mcl_burning.channels[obj]:send_all(tostring(mcl_burning.animation_frames))
hud_elem_type = "image", mcl_burning.channels[obj]:send_all("start")
position = {x = 0.5, y = 0.5},
scale = {x = -100, y = -100},
text = "mcl_burning_entity_flame_animated.png^[opacity:180^[verticalframe:" .. mcl_burning.animation_frames .. ":" .. 1,
z_index = 1000,
})
end end
storage.burn_time = burn_time storage.burn_time = burn_time
storage.fire_damage_timer = 0 storage.fire_damage_timer = 0
local fire_entity = minetest.add_entity(obj:get_pos(), "mcl_burning:fire") local fire_entity = minetest.add_entity(obj:get_pos(), "mcl_burning:fire")
local fire_luaentity = fire_entity:get_luaentity() local fire_luaentity = fire_entity:get_luaentity()
fire_luaentity:update_visual_size(obj, storage)
fire_luaentity:update_frame(obj, storage)
for _, other in pairs(minetest.get_objects_inside_radius(fire_entity:get_pos(), 0)) do for _, other in pairs(minetest.get_objects_inside_radius(fire_entity:get_pos(), 0)) do
local other_luaentity = other:get_luaentity() local other_luaentity = other:get_luaentity()
@ -110,9 +101,7 @@ function mcl_burning.extinguish(obj)
if mcl_burning.is_burning(obj) then if mcl_burning.is_burning(obj) then
local storage = mcl_burning.get_storage(obj) local storage = mcl_burning.get_storage(obj)
if obj:is_player() then if obj:is_player() then
if storage.fire_hud_id then mcl_burning.channels[obj]:send_all("stop")
obj:hud_remove(storage.fire_hud_id)
end
mcl_burning.storage[obj] = {} mcl_burning.storage[obj] = {}
else else
storage.burn_time = nil storage.burn_time = nil

@ -1,15 +1,20 @@
local S = minetest.get_translator("mcl_burning") local modpath = minetest.get_modpath(minetest.get_current_modname())
local modpath = minetest.get_modpath("mcl_burning")
local pairs = pairs
local get_connected_players = minetest.get_connected_players
local get_item_group = minetest.get_item_group
mcl_burning = { mcl_burning = {
storage = {}, storage = {},
channels = {},
animation_frames = tonumber(minetest.settings:get("fire_animation_frames")) or 8 animation_frames = tonumber(minetest.settings:get("fire_animation_frames")) or 8
} }
dofile(modpath .. "/api.lua") dofile(modpath .. "/api.lua")
minetest.register_globalstep(function(dtime) minetest.register_globalstep(function(dtime)
for _, player in pairs(minetest.get_connected_players()) do for _, player in pairs(get_connected_players()) do
local storage = mcl_burning.storage[player] local storage = mcl_burning.storage[player]
if not mcl_burning.tick(player, dtime, storage) and not mcl_burning.is_affected_by_rain(player) then if not mcl_burning.tick(player, dtime, storage) and not mcl_burning.is_affected_by_rain(player) then
local nodes = mcl_burning.get_touching_nodes(player, {"group:puts_out_fire", "group:set_on_fire"}, storage) local nodes = mcl_burning.get_touching_nodes(player, {"group:puts_out_fire", "group:set_on_fire"}, storage)
@ -17,12 +22,12 @@ minetest.register_globalstep(function(dtime)
for _, pos in pairs(nodes) do for _, pos in pairs(nodes) do
local node = minetest.get_node(pos) local node = minetest.get_node(pos)
if minetest.get_item_group(node.name, "puts_out_fire") > 0 then if get_item_group(node.name, "puts_out_fire") > 0 then
burn_time = 0 burn_time = 0
break break
end end
local value = minetest.get_item_group(node.name, "set_on_fire") local value = get_item_group(node.name, "set_on_fire")
if value > burn_time then if value > burn_time then
burn_time = value burn_time = value
end end
@ -65,13 +70,11 @@ minetest.register_on_joinplayer(function(player)
end end
mcl_burning.storage[player] = storage mcl_burning.storage[player] = storage
mcl_burning.channels[player] = minetest.mod_channel_join("mcl_burning:" .. player:get_player_name())
end) end)
minetest.register_on_leaveplayer(function(player) minetest.register_on_leaveplayer(function(player)
local storage = mcl_burning.storage[player] player:get_meta():set_string("mcl_burning:data", minetest.serialize(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 mcl_burning.storage[player] = nil
end) end)
@ -80,28 +83,28 @@ minetest.register_entity("mcl_burning:fire", {
initial_properties = { initial_properties = {
physical = false, physical = false,
collisionbox = {0, 0, 0, 0, 0, 0}, collisionbox = {0, 0, 0, 0, 0, 0},
visual = "cube", visual = "upright_sprite",
textures = {
name = "mcl_burning_entity_flame_animated.png",
animation = {
type = "vertical_frames",
aspect_w = 16,
aspect_h = 16,
length = 1.0,
},
},
spritediv = {x = 1, y = mcl_burning.animation_frames},
pointable = false, pointable = false,
glow = -1, glow = -1,
backface_culling = false,
}, },
animation_frame = 0, animation_frame = 0,
animation_timer = 0, animation_timer = 0,
on_activate = function(self)
on_step = function(self, dtime) self.object:set_sprite({x = 0, y = 0}, mcl_burning.animation_frames, 1.0 / mcl_burning.animation_frames)
local parent, storage = self:sanity_check() end,
on_step = function(self)
if parent then if not self:sanity_check() then
self.animation_timer = self.animation_timer + dtime
if self.animation_timer >= 0.1 then
self.animation_timer = 0
self.animation_frame = self.animation_frame + 1
if self.animation_frame > mcl_burning.animation_frames - 1 then
self.animation_frame = 0
end
self:update_frame(parent, storage)
end
else
self.object:remove() self.object:remove()
end end
end, end,
@ -109,24 +112,16 @@ minetest.register_entity("mcl_burning:fire", {
local parent = self.object:get_attach() local parent = self.object:get_attach()
if not parent then if not parent then
return return false
end end
local storage = mcl_burning.get_storage(parent) local storage = mcl_burning.get_storage(parent)
if not storage or not storage.burn_time then if not storage or not storage.burn_time then
return return false
end end
return parent, storage return true
end,
update_frame = function(self, parent, storage)
local frame_overlay = "^[opacity:180^[verticalframe:" .. mcl_burning.animation_frames .. ":" .. self.animation_frame
local fire_texture = "mcl_burning_entity_flame_animated.png" .. frame_overlay
self.object:set_properties({textures = {"blank.png", "blank.png", fire_texture, fire_texture, fire_texture, fire_texture}})
if parent:is_player() then
parent:hud_change(storage.fire_hud_id, "text", "mcl_burning_hud_flame_animated.png" .. frame_overlay)
end
end, end,
update_visual_size = function(self, parent, storage) update_visual_size = function(self, parent, storage)
parent = parent or self.object:get_attach() parent = parent or self.object:get_attach()

@ -1,7 +1,4 @@
local S = minetest.get_translator("mcl_falling_nodes") local function get_falling_depth(self)
local has_mcl_armor = minetest.get_modpath("mcl_armor")
local get_falling_depth = function(self)
if not self._startpos then if not self._startpos then
-- Fallback -- Fallback
self._startpos = self.object:get_pos() self._startpos = self.object:get_pos()
@ -9,7 +6,7 @@ local get_falling_depth = function(self)
return self._startpos.y - vector.round(self.object:get_pos()).y return self._startpos.y - vector.round(self.object:get_pos()).y
end end
local deal_falling_damage = function(self, dtime) local function deal_falling_damage(self, dtime)
if minetest.get_item_group(self.node.name, "falling_node_damage") == 0 then if minetest.get_item_group(self.node.name, "falling_node_damage") == 0 then
return return
end end
@ -22,7 +19,10 @@ local deal_falling_damage = function(self, dtime)
end end
self._hit = self._hit or {} self._hit = self._hit or {}
for _, obj in ipairs(minetest.get_objects_inside_radius(pos, 1)) do for _, obj in ipairs(minetest.get_objects_inside_radius(pos, 1)) do
if mcl_util.get_hp(obj) > 0 and not self._hit[obj] then local entity = obj:get_luaentity()
if entity and entity.name == "__builtin:item" then
obj:remove()
elseif mcl_util.get_hp(obj) > 0 and not self._hit[obj] then
self._hit[obj] = true self._hit[obj] = true
local way = self._startpos.y - pos.y local way = self._startpos.y - pos.y
local damage = (way - 1) * 2 local damage = (way - 1) * 2
@ -38,7 +38,7 @@ local deal_falling_damage = function(self, dtime)
inv:set_stack("armor", 2, helmet) inv:set_stack("armor", 2, helmet)
end end
end end
local deathmsg, dmg_type local dmg_type
if minetest.get_item_group(self.node.name, "anvil") ~= 0 then if minetest.get_item_group(self.node.name, "anvil") ~= 0 then
dmg_type = "anvil" dmg_type = "anvil"
else else
@ -60,10 +60,8 @@ minetest.register_entity(":__builtin:falling_node", {
collide_with_objects = false, collide_with_objects = false,
collisionbox = {-0.5, -0.5, -0.5, 0.5, 0.5, 0.5}, collisionbox = {-0.5, -0.5, -0.5, 0.5, 0.5, 0.5},
}, },
node = {}, node = {},
meta = {}, meta = {},
set_node = function(self, node, meta) set_node = function(self, node, meta)
local def = minetest.registered_nodes[node.name] local def = minetest.registered_nodes[node.name]
-- Change falling node if definition tells us to -- Change falling node if definition tells us to
@ -90,7 +88,6 @@ minetest.register_entity(":__builtin:falling_node", {
glow = glow, glow = glow,
}) })
end, end,
get_staticdata = function(self) get_staticdata = function(self)
local meta = self.meta local meta = self.meta
-- Workaround: Save inventory seperately from metadata. -- Workaround: Save inventory seperately from metadata.
@ -111,7 +108,6 @@ minetest.register_entity(":__builtin:falling_node", {
} }
return minetest.serialize(ds) return minetest.serialize(ds)
end, end,
on_activate = function(self, staticdata) on_activate = function(self, staticdata)
self.object:set_armor_groups({immortal = 1}) self.object:set_armor_groups({immortal = 1})
@ -134,7 +130,6 @@ minetest.register_entity(":__builtin:falling_node", {
end end
self._startpos = vector.round(self._startpos) self._startpos = vector.round(self._startpos)
end, end,
on_step = function(self, dtime) on_step = function(self, dtime)
-- Set gravity -- Set gravity
local acceleration = self.object:get_acceleration() local acceleration = self.object:get_acceleration()
@ -186,10 +181,9 @@ minetest.register_entity(":__builtin:falling_node", {
return return
end end
local nd = minetest.registered_nodes[n2.name] local nd = minetest.registered_nodes[n2.name]
if n2.name == "mcl_portals:portal_end" then --if n2.name == "mcl_portals:portal_end" then
-- TODO: Teleport falling node. -- TODO: Teleport falling node.
if (nd and nd.buildable_to == true) or minetest.get_item_group(self.node.name, "crush_after_fall") ~= 0 then
elseif (nd and nd.buildable_to == true) or minetest.get_item_group(self.node.name, "crush_after_fall") ~= 0 then
-- Replace destination node if it's buildable to -- Replace destination node if it's buildable to
minetest.remove_node(np) minetest.remove_node(np)
-- Run script hook -- Run script hook
@ -256,7 +250,6 @@ minetest.register_entity(":__builtin:falling_node", {
self.object:set_pos(npos) self.object:set_pos(npos)
end end
end end
deal_falling_damage(self, dtime) deal_falling_damage(self, dtime)
end end
}) })

@ -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 --these are lua locals, used for higher performance
local minetest,math,vector,ipairs = minetest,math,vector,ipairs local minetest, math, vector, ipairs, pairs = minetest, math, vector, ipairs, pairs
--this is used for the player pool in the sound buffer --this is used for the player pool in the sound buffer
local pool = {} local pool = {}
@ -38,7 +38,7 @@ item_drop_settings.drop_single_item = false --if true, the drop control dro
item_drop_settings.magnet_time = 0.75 -- how many seconds an item follows the player before giving up item_drop_settings.magnet_time = 0.75 -- how many seconds an item follows the player before giving up
local get_gravity = function() local function get_gravity()
return tonumber(minetest.settings:get("movement_gravity")) or 9.81 return tonumber(minetest.settings:get("movement_gravity")) or 9.81
end end
@ -60,7 +60,7 @@ mcl_item_entity.register_pickup_achievement("mcl_mobitems:blaze_rod", "mcl:blaze
mcl_item_entity.register_pickup_achievement("mcl_mobitems:leather", "mcl:killCow") mcl_item_entity.register_pickup_achievement("mcl_mobitems:leather", "mcl:killCow")
mcl_item_entity.register_pickup_achievement("mcl_core:diamond", "mcl:diamonds") mcl_item_entity.register_pickup_achievement("mcl_core:diamond", "mcl:diamonds")
local check_pickup_achievements = function(object, player) local function check_pickup_achievements(object, player)
if has_awards then if has_awards then
local itemname = ItemStack(object:get_luaentity().itemstring):get_name() local itemname = ItemStack(object:get_luaentity().itemstring):get_name()
local playername = player:get_player_name() local playername = player:get_player_name()
@ -72,7 +72,7 @@ local check_pickup_achievements = function(object, player)
end end
end end
local enable_physics = function(object, luaentity, ignore_check) local function enable_physics(object, luaentity, ignore_check)
if luaentity.physical_state == false or ignore_check == true then if luaentity.physical_state == false or ignore_check == true then
luaentity.physical_state = true luaentity.physical_state = true
object:set_properties({ object:set_properties({
@ -83,7 +83,7 @@ local enable_physics = function(object, luaentity, ignore_check)
end end
end end
local disable_physics = function(object, luaentity, ignore_check, reset_movement) local function disable_physics(object, luaentity, ignore_check, reset_movement)
if luaentity.physical_state == true or ignore_check == true then if luaentity.physical_state == true or ignore_check == true then
luaentity.physical_state = false luaentity.physical_state = false
object:set_properties({ object:set_properties({
@ -98,13 +98,11 @@ end
minetest.register_globalstep(function(dtime) minetest.register_globalstep(function(dtime)
tick = not tick tick = not tick
for _,player in pairs(minetest.get_connected_players()) do for _,player in pairs(minetest.get_connected_players()) do
if player:get_hp() > 0 or not minetest.settings:get_bool("enable_damage") then if player:get_hp() > 0 or not minetest.settings:get_bool("enable_damage") then
local name = player:get_player_name() local name = player:get_player_name()
local pos = player:get_pos() local pos = player:get_pos()
@ -235,7 +233,7 @@ function minetest.handle_node_drops(pos, drops, digger)
local dug_node = minetest.get_node(pos) local dug_node = minetest.get_node(pos)
local tooldef local tooldef
local tool local tool
if digger ~= nil then if digger then
tool = digger:get_wielded_item() tool = digger:get_wielded_item()
tooldef = minetest.registered_tools[tool:get_name()] tooldef = minetest.registered_tools[tool:get_name()]
@ -316,7 +314,7 @@ function minetest.handle_node_drops(pos, drops, digger)
end end
-- Spawn item and apply random speed -- Spawn item and apply random speed
local obj = minetest.add_item(dpos, drop_item) local obj = minetest.add_item(dpos, drop_item)
if obj ~= nil then if obj then
local x = math.random(1, 5) local x = math.random(1, 5)
if math.random(1,2) == 1 then if math.random(1,2) == 1 then
x = -x x = -x
@ -365,6 +363,17 @@ if not time_to_live then
time_to_live = 300 time_to_live = 300
end end
local function cxcz(o, cw, one, zero)
if cw < 0 then
table.insert(o, { [one]=1, y=0, [zero]=0 })
table.insert(o, { [one]=-1, y=0, [zero]=0 })
else
table.insert(o, { [one]=-1, y=0, [zero]=0 })
table.insert(o, { [one]=1, y=0, [zero]=0 })
end
return o
end
minetest.register_entity(":__builtin:item", { minetest.register_entity(":__builtin:item", {
initial_properties = { initial_properties = {
hp_max = 1, hp_max = 1,
@ -385,7 +394,7 @@ minetest.register_entity(":__builtin:item", {
-- The itemstring MUST be set immediately to a non-empty string after creating the entity. -- The itemstring MUST be set immediately to a non-empty string after creating the entity.
-- The hand is NOT permitted as dropped item. ;-) -- The hand is NOT permitted as dropped item. ;-)
-- Item entities will be deleted if they still have an empty itemstring on their first on_step tick. -- Item entities will be deleted if they still have an empty itemstring on their first on_step tick.
itemstring = '', itemstring = "",
-- If true, item will fall -- If true, item will fall
physical_state = true, physical_state = true,
@ -426,13 +435,9 @@ minetest.register_entity(":__builtin:item", {
if itemtable then if itemtable then
itemname = stack:to_table().name itemname = stack:to_table().name
end end
local item_texture = nil
local item_type = ""
local glow local glow
local def = minetest.registered_items[itemname] local def = minetest.registered_items[itemname]
if def then if def then
item_texture = def.inventory_image
item_type = def.type
description = def.description description = def.description
glow = def.light_source glow = def.light_source
end end
@ -475,7 +480,7 @@ minetest.register_entity(":__builtin:item", {
end, end,
get_staticdata = function(self) get_staticdata = function(self)
return minetest.serialize({ local data = minetest.serialize({
itemstring = self.itemstring, itemstring = self.itemstring,
always_collect = self.always_collect, always_collect = self.always_collect,
age = self.age, age = self.age,
@ -483,6 +488,39 @@ minetest.register_entity(":__builtin:item", {
_flowing = self._flowing, _flowing = self._flowing,
_removed = self._removed, _removed = self._removed,
}) })
-- sfan5 guessed that the biggest serializable item
-- entity would have a size of 65530 bytes. This has
-- been experimentally verified to be still too large.
--
-- anon5 has calculated that the biggest serializable
-- item entity has a size of exactly 65487 bytes:
--
-- 1. serializeString16 can handle max. 65535 bytes.
-- 2. The following engine metadata is always saved:
-- • 1 byte (version)
-- • 2 byte (length prefix)
-- • 14 byte “__builtin:item”
-- • 4 byte (length prefix)
-- • 2 byte (health)
-- • 3 × 4 byte = 12 byte (position)
-- • 4 byte (yaw)
-- • 1 byte (version 2)
-- • 2 × 4 byte = 8 byte (pitch and roll)
-- 3. This leaves 65487 bytes for the serialization.
if #data > 65487 then -- would crash the engine
local stack = ItemStack(self.itemstring)
stack:get_meta():from_table(nil)
self.itemstring = stack:to_string()
minetest.log(
"warning",
"Overlong item entity metadata removed: “" ..
self.itemstring ..
"” had serialized length of " ..
#data
)
return self:get_staticdata()
end
return data
end, end,
on_activate = function(self, staticdata, dtime_s) on_activate = function(self, staticdata, dtime_s)
@ -570,7 +608,7 @@ minetest.register_entity(":__builtin:item", {
return true return true
end, end,
on_step = function(self, dtime) on_step = function(self, dtime, moveresult)
if self._removed then if self._removed then
self.object:set_properties({ self.object:set_properties({
physical = false physical = false
@ -580,7 +618,7 @@ minetest.register_entity(":__builtin:item", {
return return
end end
self.age = self.age + dtime self.age = self.age + dtime
if self._collector_timer ~= nil then if self._collector_timer then
self._collector_timer = self._collector_timer + dtime self._collector_timer = self._collector_timer + dtime
end end
if time_to_live > 0 and self.age > time_to_live then if time_to_live > 0 and self.age > time_to_live then
@ -637,6 +675,18 @@ minetest.register_entity(":__builtin:item", {
end end
end end
-- Destroy item when it collides with a cactus
if moveresult and moveresult.collides then
for _, collision in pairs(moveresult.collisions) do
local pos = collision.node_pos
if collision.type == "node" and minetest.get_node(pos).name == "mcl_core:cactus" then
self._removed = true
self.object:remove()
return
end
end
end
-- Push item out when stuck inside solid opaque node -- Push item out when stuck inside solid opaque node
if def and def.walkable and def.groups and def.groups.opaque == 1 then if def and def.walkable and def.groups and def.groups.opaque == 1 then
local shootdir local shootdir
@ -648,16 +698,6 @@ minetest.register_entity(":__builtin:item", {
-- 1st: closest -- 1st: closest
-- 2nd: other direction -- 2nd: other direction
-- 3rd and 4th: other axis -- 3rd and 4th: other axis
local cxcz = function(o, cw, one, zero)
if cw < 0 then
table.insert(o, { [one]=1, y=0, [zero]=0 })
table.insert(o, { [one]=-1, y=0, [zero]=0 })
else
table.insert(o, { [one]=-1, y=0, [zero]=0 })
table.insert(o, { [one]=1, y=0, [zero]=0 })
end
return o
end
if math.abs(cx) < math.abs(cz) then if math.abs(cx) < math.abs(cz) then
order = cxcz(order, cx, "x", "z") order = cxcz(order, cx, "x", "z")
order = cxcz(order, cz, "z", "x") order = cxcz(order, cz, "z", "x")

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

@ -1,9 +1,10 @@
local S = minetest.get_translator("mcl_minecarts") local modname = minetest.get_current_modname()
local S = minetest.get_translator(modname)
local has_mcl_wip = minetest.get_modpath("mcl_wip") local has_mcl_wip = minetest.get_modpath("mcl_wip")
mcl_minecarts = {} mcl_minecarts = {}
mcl_minecarts.modpath = minetest.get_modpath("mcl_minecarts") mcl_minecarts.modpath = minetest.get_modpath(modname)
mcl_minecarts.speed_max = 10 mcl_minecarts.speed_max = 10
mcl_minecarts.check_float_time = 15 mcl_minecarts.check_float_time = 15
@ -204,7 +205,7 @@ local function register_entity(entity_id, mesh, textures, drop, on_rightclick, o
rou_pos = vector.round(pos) rou_pos = vector.round(pos)
node = minetest.get_node(rou_pos) node = minetest.get_node(rou_pos)
local g = minetest.get_item_group(node.name, "connect_to_raillike") local g = minetest.get_item_group(node.name, "connect_to_raillike")
if g ~= self._railtype and self._railtype ~= nil then if g ~= self._railtype and self._railtype then
-- Detach driver -- Detach driver
if player then if player then
if self._old_pos then if self._old_pos then
@ -486,7 +487,6 @@ local function register_entity(entity_id, mesh, textures, drop, on_rightclick, o
if update.pos then if update.pos then
self.object:set_pos(pos) self.object:set_pos(pos)
end end
update = nil
end end
function cart:get_staticdata() function cart:get_staticdata()
@ -497,7 +497,7 @@ local function register_entity(entity_id, mesh, textures, drop, on_rightclick, o
end end
-- Place a minecart at pointed_thing -- Place a minecart at pointed_thing
mcl_minecarts.place_minecart = function(itemstack, pointed_thing, placer) function mcl_minecarts.place_minecart(itemstack, pointed_thing, placer)
if not pointed_thing.type == "node" then if not pointed_thing.type == "node" then
return return
end end
@ -524,7 +524,7 @@ mcl_minecarts.place_minecart = function(itemstack, pointed_thing, placer)
local cart = minetest.add_entity(railpos, entity_id) local cart = minetest.add_entity(railpos, entity_id)
local railtype = minetest.get_item_group(node.name, "connect_to_raillike") local railtype = minetest.get_item_group(node.name, "connect_to_raillike")
local le = cart:get_luaentity() local le = cart:get_luaentity()
if le ~= nil then if le then
le._railtype = railtype le._railtype = railtype
end end
local cart_dir = mcl_minecarts:get_rail_direction(railpos, {x=1, y=0, z=0}, nil, nil, railtype) local cart_dir = mcl_minecarts:get_rail_direction(railpos, {x=1, y=0, z=0}, nil, nil, railtype)
@ -541,7 +541,7 @@ mcl_minecarts.place_minecart = function(itemstack, pointed_thing, placer)
end end
local register_craftitem = function(itemstring, entity_id, description, tt_help, longdesc, usagehelp, icon, creative) local function register_craftitem(itemstring, entity_id, description, tt_help, longdesc, usagehelp, icon, creative)
entity_mapping[itemstring] = entity_id entity_mapping[itemstring] = entity_id
local groups = { minecart = 1, transport = 1 } local groups = { minecart = 1, transport = 1 }
@ -607,7 +607,7 @@ Register a minecart
local function register_minecart(itemstring, entity_id, description, tt_help, longdesc, usagehelp, mesh, textures, icon, drop, on_rightclick, on_activate_by_rail, creative) local function register_minecart(itemstring, entity_id, description, tt_help, longdesc, usagehelp, mesh, textures, icon, drop, on_rightclick, on_activate_by_rail, creative)
register_entity(entity_id, mesh, textures, drop, on_rightclick, on_activate_by_rail) register_entity(entity_id, mesh, textures, drop, on_rightclick, on_activate_by_rail)
register_craftitem(itemstring, entity_id, description, tt_help, longdesc, usagehelp, icon, creative) register_craftitem(itemstring, entity_id, description, tt_help, longdesc, usagehelp, icon, creative)
if minetest.get_modpath("doc_identifier") ~= nil then if minetest.get_modpath("doc_identifier") then
doc.sub.identifier.register_object(entity_id, "craftitems", itemstring) doc.sub.identifier.register_object(entity_id, "craftitems", itemstring)
end end
end end
@ -646,7 +646,7 @@ register_minecart(
if player then if player then
mcl_player.player_set_animation(player, "sit" , 30) mcl_player.player_set_animation(player, "sit" , 30)
player:set_eye_offset({x=0, y=-5.5, z=0},{x=0, y=-4, z=0}) player:set_eye_offset({x=0, y=-5.5, z=0},{x=0, y=-4, z=0})
mcl_tmp_message.message(clicker, S("Sneak to dismount")) mcl_title.set(clicker, "actionbar", {text=S("Sneak to dismount"), color="white", stay=60})
end end
end, name) end, name)
end end
@ -817,31 +817,30 @@ minetest.register_craft({
}) })
-- TODO: Re-enable crafting of special minecarts when they have been implemented -- TODO: Re-enable crafting of special minecarts when they have been implemented
if false then --[[minetest.register_craft({
minetest.register_craft({
output = "mcl_minecarts:furnace_minecart", output = "mcl_minecarts:furnace_minecart",
recipe = { recipe = {
{"mcl_furnaces:furnace"}, {"mcl_furnaces:furnace"},
{"mcl_minecarts:minecart"}, {"mcl_minecarts:minecart"},
}, },
}) })
minetest.register_craft({ minetest.register_craft({
output = "mcl_minecarts:hopper_minecart", output = "mcl_minecarts:hopper_minecart",
recipe = { recipe = {
{"mcl_hoppers:hopper"}, {"mcl_hoppers:hopper"},
{"mcl_minecarts:minecart"}, {"mcl_minecarts:minecart"},
}, },
}) })
minetest.register_craft({ minetest.register_craft({
output = "mcl_minecarts:chest_minecart", output = "mcl_minecarts:chest_minecart",
recipe = { recipe = {
{"mcl_chests:chest"}, {"mcl_chests:chest"},
{"mcl_minecarts:minecart"}, {"mcl_minecarts:minecart"},
}, },
}) })]]
end
if has_mcl_wip then if has_mcl_wip then
mcl_wip.register_wip_item("mcl_minecarts:chest_minecart") mcl_wip.register_wip_item("mcl_minecarts:chest_minecart")

@ -33,3 +33,4 @@ Activates minecarts when powered=Active les wagonnets lorsqu'il est alimenté
Emits redstone power when a minecart is detected=Émet de l'énergie redstone lorsqu'un wagonnet est détecté Emits redstone power when a minecart is detected=Émet de l'énergie redstone lorsqu'un wagonnet est détecté
Vehicle for fast travel on rails=Véhicule pour voyager rapidement sur rails Vehicle for fast travel on rails=Véhicule pour voyager rapidement sur rails
Can be ignited by tools or powered activator rail=Peut être allumé par des outils ou un rail d'activation motorisé Can be ignited by tools or powered activator rail=Peut être allumé par des outils ou un rail d'activation motorisé
Sneak to dismount=

@ -0,0 +1,36 @@
# textdomain: mcl_minecarts
Minecart=Wagonik
Minecarts can be used for a quick transportion on rails.=Wagoniki mogą być użyte do szybkiego transportu po torach.
Minecarts only ride on rails and always follow the tracks. At a T-junction with no straight way ahead, they turn left. The speed is affected by the rail type.=Wagoniki mogą jeździć tylko po torach i zawsze podążają za wytyczoną ścieżką. W przypadku skrzyżowań typu T, gdzie nie ma prostej ścieżki, skręcają w lew. Ich szybkość zależy od typu torów.
You can place the minecart on rails. Right-click it to enter it. Punch it to get it moving.=Możesz postawić wagonik na torach. Kliknij prawym przyciskiem myszy aby do niego wejść. Uderz go by zaczął się poruszać.
To obtain the minecart, punch it while holding down the sneak key.=Aby odzyskać wagonik uderz go podczas skradania.
A minecart with TNT is an explosive vehicle that travels on rail.=Wagonik z TNT jest wybuchowym pojazdem podróżującym po torach.
Place it on rails. Punch it to move it. The TNT is ignited with a flint and steel or when the minecart is on an powered activator rail.=Postaw go na torach. Uderz by zaczął się poruszać. TNT zapala się krzesiwem lub gdy wagonik jest na zasilonych torach aktywacyjnych.
To obtain the minecart and TNT, punch them while holding down the sneak key. You can't do this if the TNT was ignited.=Aby odzyskać wagonik z TNT uderz go podczas skradania. Nie możesz tego zrobić gdy TNT jest zapalone.
A minecart with furnace is a vehicle that travels on rails. It can propel itself with fuel.=Wagonik z piecem jest pojazdem podróżującym na torach. Napędza on samego siebie za pomocą paliwa.
Place it on rails. If you give it some coal, the furnace will start burning for a long time and the minecart will be able to move itself. Punch it to get it moving.=Postaw go na torach. Jeśli dasz mu nieco węgla piec zacznie palić przez długi czas, a wagonik będzie się sam poruszał. Uderz go by zaczął się poruszać.
To obtain the minecart and furnace, punch them while holding down the sneak key.=Aby odzyskać wagonik z piecem uderz go podczas skradania.
Minecart with Chest=Wagonik ze skrzynią
Minecart with Furnace=Wagonik z piecem
Minecart with Command Block=Wagonik z blokiem poleceń
Minecart with Hopper=Wagonik z lejem
Minecart with TNT=Wagonik z TNT
Place them on the ground to build your railway, the rails will automatically connect to each other and will turn into curves, T-junctions, crossings and slopes as needed.=Postaw je na ziemi by zbudować ścieżkę z torów. Tory automatycznie połączą się ze sobą i zamienią się w zakręty, skrzyżowania typu T, skrzyżowania i równie w zależności od potrzeb.
Rail=Tor
Rails can be used to build transport tracks for minecarts. Normal rails slightly slow down minecarts due to friction.=Tory mogą być wykorzystane do zbudowania torów dla wagoników. Zwyczajne tory nieco spowalniają wagoniki ze względu na tarcie.
Powered Rail=Zasilane tory
Rails can be used to build transport tracks for minecarts. Powered rails are able to accelerate and brake minecarts.=Tory mogą być wykorzystane do zbudowania torów dla wagoników. Zasilane tory mogą przyspieszać lub spowalniać wagoniki.
Without redstone power, the rail will brake minecarts. To make this rail accelerate minecarts, power it with redstone power.=Bez zasilania czerwienitem tory będą spowalniać wagoniki. Aby sprawić by je przyspieszały zasil je czerwienitem.
Activator Rail=Tory aktywacyjne
Rails can be used to build transport tracks for minecarts. Activator rails are used to activate special minecarts.=Tory mogą być wykorzystane do zbudowania torów dla wagoników. Tory aktywacyjne są wykorzystywane do aktywacji specjalnych wagoników.
To make this rail activate minecarts, power it with redstone power and send a minecart over this piece of rail.=Aby ten tor aktywował wagonik, zasil go czerwienitem i spraw by wagonik po nim przejechał.
Detector Rail=Tory z czujnikiem
Rails can be used to build transport tracks for minecarts. A detector rail is able to detect a minecart above it and powers redstone mechanisms.=Tory mogą być wykorzystane do zbudowania torów dla wagoników. Tory z czujnikiem są w stanie wykryć kiedy wagonik po nich przejeżdża i wysłać sygnał do czerwienitowych mechanizmów.
To detect a minecart and provide redstone power, connect it to redstone trails or redstone mechanisms and send any minecart over the rail.=Aby wykryć wagonik i dostarczyć zasilanie czerwienitem podłącz go czerwienitem to mechanizmu i spraw by wagonik po nim przejechał.
Track for minecarts=Tor dla wagoników
Speed up when powered, slow down when not powered=Przyspiesza gdy zasilane, spowalnia gdy nie
Activates minecarts when powered=Aktywuje wagoniki gdy zasilane
Emits redstone power when a minecart is detected=Emituje zasilanie czerwienitem gdy wagonik jest wykryty
Vehicle for fast travel on rails=Pojazd do szybkiej podróży na torach
Can be ignited by tools or powered activator rail=Może być zapalony przez narzędzia, lub zasilane tor aktywacyjne
Sneak to dismount=Zacznij się skradać by zejść

@ -1,6 +1,6 @@
name = mcl_minecarts name = mcl_minecarts
author = Krock author = Krock
description = Minecarts are vehicles to move players quickly on rails. description = Minecarts are vehicles to move players quickly on rails.
depends = mcl_explosions, mcl_core, mcl_sounds, mcl_player, mcl_achievements, mcl_chests, mcl_furnaces, mesecons_commandblock, mcl_hoppers, mcl_tnt, mesecons depends = mcl_title, mcl_explosions, mcl_core, mcl_sounds, mcl_player, mcl_achievements, mcl_chests, mcl_furnaces, mesecons_commandblock, mcl_hoppers, mcl_tnt, mesecons
optional_depends = doc_identifier, mcl_wip optional_depends = doc_identifier, mcl_wip

@ -1,7 +1,7 @@
local S = minetest.get_translator("mcl_minecarts") local S = minetest.get_translator(minetest.get_current_modname())
-- Template rail function -- Template rail function
local register_rail = function(itemstring, tiles, def_extras, creative) local function register_rail(itemstring, tiles, def_extras, creative)
local groups = {handy=1,pickaxey=1, attached_node=1,rail=1,connect_to_raillike=minetest.raillike_group("rail"),dig_by_water=1,destroy_by_lava_flow=1, transport=1} local groups = {handy=1,pickaxey=1, attached_node=1,rail=1,connect_to_raillike=minetest.raillike_group("rail"),dig_by_water=1,destroy_by_lava_flow=1, transport=1}
if creative == false then if creative == false then
groups.not_in_creative_inventory = 1 groups.not_in_creative_inventory = 1
@ -206,11 +206,11 @@ register_rail("mcl_minecarts:detector_rail_on",
-- Crafting -- Crafting
minetest.register_craft({ minetest.register_craft({
output = 'mcl_minecarts:rail 16', output = "mcl_minecarts:rail 16",
recipe = { recipe = {
{'mcl_core:iron_ingot', '', 'mcl_core:iron_ingot'}, {"mcl_core:iron_ingot", "", "mcl_core:iron_ingot"},
{'mcl_core:iron_ingot', 'mcl_core:stick', 'mcl_core:iron_ingot'}, {"mcl_core:iron_ingot", "mcl_core:stick", "mcl_core:iron_ingot"},
{'mcl_core:iron_ingot', '', 'mcl_core:iron_ingot'}, {"mcl_core:iron_ingot", "", "mcl_core:iron_ingot"},
} }
}) })

@ -190,9 +190,10 @@ Origin of those models:
* [Spennnyyy](https://freesound.org/people/Spennnyyy/) (CC0) * [Spennnyyy](https://freesound.org/people/Spennnyyy/) (CC0)
* `mcl_totems_totem.ogg` * `mcl_totems_totem.ogg`
* Source: <https://freesound.org/people/Spennnyyy/sounds/323502/> * Source: <https://freesound.org/people/Spennnyyy/sounds/323502/>
* [Baŝto](https://opengameart.org/users/ba%C5%9Dto) * [Baŝto](https://opengameart.org/users/ba%C5%9Dto) (remixer) and [kantouth](https://freesound.org/people/kantouth/) (original author)
* `mobs_mc_skeleton_random.*.ogg` (CC BY 3.0) * `mobs_mc_skeleton_random.*.ogg` (CC BY 3.0)
* Source: <https://opengameart.org/content/walking-skeleton> * Source: <https://opengameart.org/content/walking-skeleton>
* Based on: <https://freesound.org/people/kantouth/sounds/115113/>
* [spookymodem](https://freesound.org/people/spookymodem/) * [spookymodem](https://freesound.org/people/spookymodem/)
* `mobs_mc_skeleton_death.ogg` (CC0) * `mobs_mc_skeleton_death.ogg` (CC0)
* <https://freesound.org/people/spookymodem/sounds/202091/> * <https://freesound.org/people/spookymodem/sounds/202091/>
@ -306,4 +307,4 @@ Origin of those models:
Note: Many of these sounds have been more or less modified to fit the game. Note: Many of these sounds have been more or less modified to fit the game.
Sounds not mentioned hre are licensed under CC0. Sounds not mentioned here are licensed under CC0.

@ -1,33 +1,74 @@
# MineClone2 Mobs
This is a merged version of Mobs redo MineClone2 Edition (API) and mobs_mc (Mobs content). Mobs Redo: MineClone 2 Edition
The API was rewritten by jordan4ibanez and later Fleckenstein from Mobs redo MineClone2 Edition and merged with mobs_mc by Fleckenstein.
Mobs redo MineClone2 Edition was built by Wuzzy2 and contributors from Mobs Redo. Mobs redo was built by TenPlus1 from Simple Mobs by PilzAdam and mobs_mc was built by maikerumine.
Seems like we've come a long way since 2012. Based on Mobs Redo from TenPlus1
Built from PilzAdam's original Simple Mobs with additional mobs by KrupnoPavel, Zeg9, ExeterDad and AspireMint.
## Credits
* Fleckenstein: Rewrite of jordan's work, merged mobs_mc and mcl_mobs This mod contains the API only for adding your own mobs into the world, so please use the additional modpacks to add animals, monsters etc.
* jordan4ibanez: Rewrite of the mcl_mobs API
* [maikerumine](https://github.com/maikerumine): Creator of mobs_mc (Coding behaviour, spawning, drops, and misc)
* TenPlus1: Built the original Mobs Redo API
* PilzAdam: Created Simple Mobs which Mobs Redo is based on together with KrupnoPavel, Zeg9, ExeterDad and AspireMint
* [Wuzzy2](https://github.com/Wuzzy2): Zombies, husks, item textures, and code, created Mobs redo MineClone2 Edition
* [toby109tt](https://github.com/tobyplowy): Mapping fixes - better 2D planes
* [22i](https://github.com/22i): Models (done in Blender) and mob icons for spawn eggs
* [XSSheep](https://www.planetminecraft.com/member/xssheep/): Mob and item textures (from [Pixel Perfection](https://www.planetminecraft.com/texture_pack/131pixel-perfection/))
* MysticTempest: More mob textures
* See `LICENSE-MEDIA.md` for detailed credits about each file
## Licensing
* Media: MIT, CC0, CC BY 3.0 CC BY-SA 4.0, LGPLv2.1, GPLv3. See `LICENSE-MEDIA.md` for details https://forum.minetest.net/viewtopic.php?f=11&t=9917
* License of mobs_mc code: GPLv3
* Mobs Redo: See `LICENSE-API.txt`
### Links ------------
Credits:
* [`mobs_mc`](https://github.com/maikerumine/mobs_mc) mcl_mobs_mob_poof.ogg:
* [Blender models](https://github.com/22i/minecraft-voxel-blender-models) - by Planman (license: Creative Commons Zero)
* [How to recreate mobs from textures with Blender and Gimp](http://imgur.com/a/Iqg88) - Source: <https://freesound.org/people/Planman/sounds/208111/>
------------
Changelog from original Mobs Redo mod:
- 1.41- Mob pathfinding has been updated thanks to Elkien3
- 1.40- Updated to use newer functions, requires Minetest 0.4.16+ to work.
- 1.39- Added 'on_breed', 'on_grown' and 'do_punch' custom functions per mob
- 1.38- Better entity checking, nametag setting and on_spawn function added to mob registry, tweaked light damage
- 1.37- Added support for Raymoo's CMI (common mob interface) mod: https://forum.minetest.net/viewtopic.php?f=9&t=15448
- 1.36- Death check added, if mob dies in fire/lava/with lava pick then drops are cooked
- 1.35- Added owner_loyal flag for owned mobs to attack player enemies, also fixed group_attack
- 1.34- Added function to fly mob using directional movement (thanks D00Med for flying code)
- 1.33- Added functions to mount ride mobs (mobs.attach, mobs.detach, mobs.drive) many thanks to Blert2112
- 1.32- Added new spawn check to count specific mobs AND new minetest.conf setting to chance spawn chance and numbers, added ability to protect tamed mobs
- 1.31- Added 'attack_animals' and 'specific_attack' flags for custom monster attacks, also 'mob_difficulty' .conf setting to make mobs harder.
- 1.30- Added support for invisibility mod (mobs cant attack what they cant see), tweaked and tidied code
- 1.29- Split original Mobs Redo into a modpack to make it easier to disable mob sets (animal, monster, npc) or simply use the Api itself for your own mod
- 1.28- New damage system added with ability for mob to be immune to weapons or healed by them :)
- 1.27- Added new sheep, lava flan and spawn egg textures. New Lava Pick tool smelts what you dig. New atan checking function.
- 1.26- Pathfinding feature added thanks to rnd, when monsters attack they become scary smart in finding you :) also, beehive produces honey now :)
- 1.25- Mobs no longer spawn within 12 blocks of player or despawn within same range, spawners now have player detection, Code tidy and tweak.
- 1.24- Added feature where certain animals run away when punched (runaway = true in mob definition)
- 1.23- Added mob spawner block for admin to setup spawners in-game (place and right click to enter settings)
- 1.22- Added ability to name tamed animals and npc using nametags, also npc will attack anyone who punches them apart from owner
- 1.21- Added some more error checking to reduce serialize.h error and added height checks for falling off cliffs (thanks cmdskp)
- 1.20- Error checking added to remove bad mobs, out of map limit mobs and stop serialize.h error
- 1.19- Chickens now drop egg items instead of placing the egg, also throwing eggs result in 1/8 chance of spawning chick
- 1.18- Added docile_by_day flag so that monsters will not attack automatically during daylight hours unless hit first
- 1.17- Added 'dogshoot' attack type, shoots when out of reach, melee attack when in reach, also api tweaks and self.reach added
- 1.16- Mobs follow multiple items now, Npc's can breed
- 1.15- Added Feeding/Taming/Breeding function, right-click to pick up any sheep with X mark on them and replace with new one to fix compatibility.
- 1.14- All .self variables saved in staticdata, Fixed self.health bug
- 1.13- Added capture function (thanks blert2112) chance of picking up mob with hand; net; magic lasso, replaced some .x models with newer .b3d one's
- 1.12- Added animal ownership so that players cannot steal your tamed animals
- 1.11- Added flying mobs (and swimming), fly=true and fly_in="air" or "deafult:water_source" for fishy
- 1,10- Footstep removed (use replace), explosion routine added for exploding mobs.
- 1.09- reworked breeding routine, added mob rotation value, added footstep feature, added jumping mobs with sounds feature, added magic lasso for picking up animals
- 1.08- Mob throwing attack has been rehauled so that they can damage one another, also drops and on_die function added
- 1.07- Npc's can now be set to follow player or stand by using self.order and self.owner variables
- beta- Npc mob added, kills monsters, attacks player when punched, right click with food to heal or gold lump for drop
- 1.06- Changed recovery times after breeding, and time taken to grow up (can be sped up by feeding baby animal)
- 1.05- Added ExeterDad's bunny's which can be picked up and tamed with 4 carrots from farming redo or farming_plus, also shears added to get wool from sheep and lastly Jordach/BSD's kitten
- 1.04- Added mating for sheep, cows and hogs... feed animals to make horny and hope for a baby which is half size, will grow up quick though :)
- 1.03- Added mob drop/replace feature so that chickens can drop eggs, cow/sheep can eat grass/wheat etc.
- 1.02- Sheared sheep are remembered and spawn shaven, Warthogs will attack when threatened, Api additions
- 1.01- Mobs that suffer fall damage or die in water/lava/sunlight will now drop items
- 1.0 - more work on Api so that certain mobs can float in water while some sink like a brick :)
- 0.9 - Spawn eggs added for all mobs (admin only, cannot be placed in protected areas)... Api tweaked
- 0.8 - Added sounds to monster mobs (thanks Cyberpangolin for the sfx) and also chicken sound
- 0.7 - mobs.protected switch added to api.lua, when set to 1 mobs no longer spawn in protected areas, also bug fixes
- 0.6 - Api now supports multi-textured mobs, e.g oerkki, dungeon master, rats and chickens have random skins when spawning (sheep fix TODO), also new Honey block
- 0.5 - Mobs now float in water, die from falling, and some code improvements
- 0.4 - Dungeon Masters and Mese Monsters have much better aim due to shoot_offset, also they can both shoot through nodes that aren't walkable (flowers, grass etc) plus new sheep sound :)
- 0.3 - Added LOTT's Spider mob, made Cobwebs, added KPavel's Bee with Honey and Beehives (made texture), Warthogs now have sound and can be tamed, taming of shaved sheep or milked cow with 8 wheat so it will not despawn, many bug fixes :)
- 0.2 - Cooking bucket of milk into cheese now returns empty bucket
- 0.1 - Initial Release

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

@ -0,0 +1,78 @@
--this is from https://github.com/HybridDog/builtin_item/blob/e6dfd9dce86503b3cbd1474257eca5f6f6ca71c2/init.lua#L50
local
minetest,vector,math,pairs,minetest_get_node,vector_subtract,minetest_registered_nodes
=
minetest,vector,math,pairs,minetest.get_node,vector.subtract,minetest.registered_nodes
local tab
local n
local function get_nodes(pos)
tab,n = {},1
for i = -1,1,2 do
for _,p in pairs({
{x=pos.x+i, y=pos.y, z=pos.z},
{x=pos.x, y=pos.y, z=pos.z+i}
}) do
tab[n] = {p, minetest_get_node(p)}
n = n+1
end
end
return tab
end
local data
local param2
local nd
local par2
local name
local tmp
local c_node
function mobs.get_flowing_dir(pos)
c_node = minetest_get_node(pos).name
if c_node ~= "mcl_core:water_flowing" and c_node ~= "mcl_core:water" then
return nil
end
data = get_nodes(pos)
param2 = minetest_get_node(pos).param2
if param2 > 7 then
return nil
end
if c_node == "mcl_core:water" then
for _,i in pairs(data) do
nd = i[2]
name = nd.name
par2 = nd.param2
if name == "mcl_core:water_flowing" and par2 == 7 then
return(vector_subtract(i[1],pos))
end
end
end
for _,i in pairs(data) do
nd = i[2]
name = nd.name
par2 = nd.param2
if name == "mcl_core:water_flowing" and par2 < param2 then
return(vector_subtract(i[1],pos))
end
end
for _,i in pairs(data) do
nd = i[2]
name = nd.name
par2 = nd.param2
if name == "mcl_core:water_flowing" and par2 >= 11 then
return(vector_subtract(i[1],pos))
end
end
for _,i in pairs(data) do
nd = i[2]
name = nd.name
par2 = nd.param2
tmp = minetest_registered_nodes[name]
if tmp and not tmp.walkable and name ~= "mcl_core:water_flowing" and name ~= "mcl_core:water" then
return(vector_subtract(i[1],pos))
end
end
return nil
end

@ -0,0 +1,85 @@
# textdomain: mcl_mobs
Peaceful mode active! No monsters will spawn.=Tryb pokojowy aktywowany! Potwory nie będą się pojawiać.
This allows you to place a single mob.=To pozwala na przywołanie jednego moba.
Just place it where you want the mob to appear. Animals will spawn tamed, unless you hold down the sneak key while placing. If you place this on a mob spawner, you change the mob it spawns.=Postaw to w miejscu w którym chcesz aby pojawił się mob. Zwierzęta pojawią się jako oswojone chyba, że będziesz się skradał podczas stawiania. Jeśli postawisz to na spawnerze to zmienisz którego moba przywołuje.
You need the “maphack” privilege to change the mob spawner.=Potrzebujesz przywileju "maphack", aby zmienić spawner.
Name Tag=Znacznik
A name tag is an item to name a mob.=Znacznik jest przedmiotem pozwalającym nazwać moba.
Before you use the name tag, you need to set a name at an anvil. Then you can use the name tag to name a mob. This uses up the name tag.=Zanim użyjesz znacznika musisz wybrać imię przy kowadle. Następnie możesz użyć znacznika by nazwać moba. To zużywa znacznik.
Only peaceful mobs allowed!=Tylko pokojowe moby są dozwolone!
Give names to mobs=Nazwij moby
Set name at anvil=Wybierz imię przy kowadle
Totem of Undying=Token nieśmiertelności
A totem of undying is a rare artifact which may safe you from certain death.=Totem nieśmiertelności to rzadki artefakt, który może uchronić cię przed pewną śmiercią.
The totem only works while you hold it in your hand. If you receive fatal damage, you are saved from death and you get a second chance with 1 HP. The totem is destroyed in the process, however.=Totem działa tylko kiedy trzymasz go w dłoni. Jeśli otrzymasz obrażenia od upadku zostaniesz oszczędzony i pozostanie ci 1 HP, jednak totem zostanie wtedy zniszczony.
Iron Horse Armor=Żelazna zbroja dla konia
Iron horse armor can be worn by horses to increase their protection from harm a bit.=Żelazna zbroja dla konia może być noszona przez konie aby nieco zwiększyć ich odporność na obrażenia.
Golden Horse Armor=Złota zbroja dla konia
Golden horse armor can be worn by horses to increase their protection from harm.=Złota zbroja dla konia może być noszona przez konie aby zwiększyć ich odporność na obrażenia.
Diamond Horse Armor=Diamentowa zbroja dla konia
Diamond horse armor can be worn by horses to greatly increase their protection from harm.=Diamentowa zbroja dla konia może być noszona przez konie aby istotnie zwiększyć ich odporność na obrażenia.
Place it on a horse to put on the horse armor. Donkeys and mules can't wear horse armor.=Połóż ją na koniu aby założyć zbroję dla konia. Osły i muły nie mogą nosić zbroi dla konia.
Farmer=Rolnik
Fisherman=Rybak
Fletcher=Łuczarz
Shepherd=Pasterz
Librarian=Bibliotekarz
Cartographer=Kartograf
Armorer=Płatnerz
Leatherworker=Rymarz
Butcher=Rzeźnik
Weapon Smith=Zbrojmistrz
Tool Smith=Narzędziarz
Cleric=Kapłan
Nitwit=Głupiec
Protects you from death while wielding it=Chroni przed śmiercią gdy go trzymasz
Agent=Agent
Bat=Nietoperz
Blaze=Płomyk
Chicken=Kurczak
Cow=Krowa
Mooshroom=Muuuchomor
Creeper=Creeper
Ender Dragon=Smok kresu
Enderman=Enderman
Endermite=Endermit
Ghast=Ghast
Elder Guardian=Prastrażnik
Guardian=Strażnik
Horse=Koń
Skeleton Horse=Koń szkielet
Zombie Horse=Koń zombie
Donkey=Osioł
Mule=Muł
Iron Golem=Żelazny golem
Llama=Lama
Ocelot=Ocelot
Parrot=Papuga
Pig=Świnia
Polar Bear=Niedźwiedź polarny
Rabbit=Królik
Killer Bunny=Królik zabójca
Sheep=Owca
Shulker=Shulker
Silverfish=Rybik cukrowy
Skeleton=Szkielet
Stray=Tułacz
Wither Skeleton=Witherowy szkielet
Magma Cube=Kostka magmy
Slime=Szlam
Snow Golem=Śnieżny golem
Spider=Pająk
Cave Spider=Pająk jaskiniowy
Squid=Kałamarnica
Vex=Dręczyciel
Evoker=Przywoływacz
Illusioner=Iluzjonista
Villager=Osadnik
Vindicator=Obrońca
Zombie Villager=Osadnik zombie
Witch=Wiedźma
Wither=Wither
Wolf=Wilk
Husk=Posuch
Zombie=Zombie
Zombie Pigman=Świniak zombie

@ -29,6 +29,7 @@ Pig=
Polar Bear= Polar Bear=
Rabbit= Rabbit=
Killer Bunny= Killer Bunny=
The Killer Bunny=
Sheep= Sheep=
Shulker= Shulker=
Silverfish= Silverfish=

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

@ -6,7 +6,7 @@
-- NOTE: Strings intentionally not marked for translation, other mods already have these items. -- NOTE: Strings intentionally not marked for translation, other mods already have these items.
-- TODO: Remove this file eventually, all items here are already outsourced in other mods. -- TODO: Remove this file eventually, all items here are already outsourced in other mods.
local S = minetest.get_translator("mobs_mc") --local S = minetest.get_translator(minetest.get_current_modname())
--maikerumines throwing code --maikerumines throwing code
--arrow (weapon) --arrow (weapon)
@ -83,7 +83,7 @@ THROWING_ARROW_ENTITY.on_step = function(self, dtime)
if self.timer>0.2 then if self.timer>0.2 then
local objs = minetest.get_objects_inside_radius({x=pos.x,y=pos.y,z=pos.z}, 1.5) local objs = minetest.get_objects_inside_radius({x=pos.x,y=pos.y,z=pos.z}, 1.5)
for k, obj in pairs(objs) do for k, obj in pairs(objs) do
if obj:get_luaentity() ~= nil then if obj:get_luaentity() then
if obj:get_luaentity().name ~= "mobs_mc:arrow_entity" and obj:get_luaentity().name ~= "__builtin:item" then if obj:get_luaentity().name ~= "mobs_mc:arrow_entity" and obj:get_luaentity().name ~= "__builtin:item" then
local damage = 3 local damage = 3
minetest.sound_play("damage", {pos = pos}, true) minetest.sound_play("damage", {pos = pos}, true)
@ -108,7 +108,7 @@ THROWING_ARROW_ENTITY.on_step = function(self, dtime)
if self.lastpos.x~=nil then if self.lastpos.x~=nil then
if node.name ~= "air" then if node.name ~= "air" then
minetest.sound_play("bowhit1", {pos = pos}, true) minetest.sound_play("bowhit1", {pos = pos}, true)
minetest.add_item(self.lastpos, 'mobs_mc:arrow') minetest.add_item(self.lastpos, "mobs_mc:arrow")
self.object:remove() self.object:remove()
end end
end end
@ -155,7 +155,7 @@ end
if c("arrow") and c("flint") and c("feather") and c("stick") then if c("arrow") and c("flint") and c("feather") and c("stick") then
minetest.register_craft({ minetest.register_craft({
output = 'mobs_mc:arrow 4', output = "mobs_mc:arrow 4",
recipe = { recipe = {
{mobs_mc.items.flint}, {mobs_mc.items.flint},
{mobs_mc.items.stick}, {mobs_mc.items.stick},
@ -181,11 +181,11 @@ if c("bow") then
}) })
minetest.register_craft({ minetest.register_craft({
output = 'mobs_mc:bow_wood', output = "mobs_mc:bow_wood",
recipe = { recipe = {
{mobs_mc.items.string, mobs_mc.items.stick, ''}, {mobs_mc.items.string, mobs_mc.items.stick, ""},
{mobs_mc.items.string, '', mobs_mc.items.stick}, {mobs_mc.items.string, "", mobs_mc.items.stick},
{mobs_mc.items.string, mobs_mc.items.stick, ''}, {mobs_mc.items.string, mobs_mc.items.stick, ""},
} }
}) })
end end
@ -259,7 +259,7 @@ if c("egg") then
}) })
-- shoot egg -- shoot egg
local mobs_shoot_egg = function (item, player, pointed_thing) local function mobs_shoot_egg(item, player, pointed_thing)
local playerpos = player:get_pos() local playerpos = player:get_pos()
@ -349,7 +349,7 @@ mobs:register_arrow("mobs_mc:snowball_entity", {
if c("snowball") then if c("snowball") then
-- shoot snowball -- shoot snowball
local mobs_shoot_snowball = function (item, player, pointed_thing) local function mobs_shoot_snowball(item, player, pointed_thing)
local playerpos = player:get_pos() local playerpos = player:get_pos()

@ -1,5 +1,5 @@
--License for code WTFPL and otherwise stated in readmes --License for code WTFPL and otherwise stated in readmes
local S = minetest.get_translator("mcl_mobs") local S = minetest.get_translator(minetest.get_current_modname())
mcl_mobs.register_mob("mcl_mobs:bat", { mcl_mobs.register_mob("mcl_mobs:bat", {
description = S("Bat"), description = S("Bat"),

@ -1,8 +1,13 @@
-- daufinsyd -- daufinsyd
-- My work is under the LGPL terms -- My work is under the LGPL terms
-- Model and mcl_mobs_blaze.png see https://github.com/22i/minecraft-voxel-blender-models -hi 22i ~jordan4ibanez -- Model and mobs_blaze.png see https://github.com/22i/minecraft-voxel-blender-models -hi 22i ~jordan4ibanez
-- blaze.lua partial copy of ghast.lua -- blaze.lua partial copy of mobs_mc/ghast.lua
local S = minetest.get_translator("mcl_mobs")
local S = minetest.get_translator(minetest.get_current_modname())
--###################
--################### BLAZE
--###################
local smokedef = mcl_particles.get_smoke_def({ local smokedef = mcl_particles.get_smoke_def({
amount = 0.009, amount = 0.009,
@ -25,7 +30,7 @@ mcl_mobs.register_mob("mcl_mobs:blaze", {
xp_max = 10, xp_max = 10,
tilt_fly = false, tilt_fly = false,
hostile = true, hostile = true,
rotate = 270, --rotate = 270,
collisionbox = {-0.3, -0.01, -0.3, 0.3, 1.79, 0.3}, collisionbox = {-0.3, -0.01, -0.3, 0.3, 1.79, 0.3},
rotate = -180, rotate = -180,
model = "mcl_mobs_blaze.b3d", model = "mcl_mobs_blaze.b3d",

@ -1,6 +1,6 @@
--License for code WTFPL and otherwise stated in readmes --License for code WTFPL and otherwise stated in readmes
local S = minetest.get_translator("mobs_mc") local S = minetest.get_translator(minetest.get_current_modname())
--################### --###################
--################### CHICKEN --################### CHICKEN

@ -1,6 +1,6 @@
--License for code WTFPL and otherwise stated in readmes --License for code WTFPL and otherwise stated in readmes
local S = minetest.get_translator("mobs_mc") local S = minetest.get_translator(minetest.get_current_modname())
local cow_def = { local cow_def = {
description = S("Cow"), description = S("Cow"),

@ -1,6 +1,6 @@
--License for code WTFPL and otherwise stated in readmes --License for code WTFPL and otherwise stated in readmes
local S = minetest.get_translator("mobs_mc") local S = minetest.get_translator(minetest.get_current_modname())
--################### --###################
--################### CREEPER --################### CREEPER
@ -69,7 +69,7 @@ local creeper = {
-- TODO: Make creeper flash after doing this as well. -- TODO: Make creeper flash after doing this as well.
-- TODO: Test and debug this code. -- TODO: Test and debug this code.
on_rightclick = function(self, clicker) on_rightclick = function(self, clicker)
if self._forced_explosion_countdown_timer ~= nil then if self._forced_explosion_countdown_timer then
return return
end end
local item = clicker:get_wielded_item() local item = clicker:get_wielded_item()
@ -89,7 +89,7 @@ local creeper = {
end end
end, end,
do_custom = function(self, dtime) do_custom = function(self, dtime)
if self._forced_explosion_countdown_timer ~= nil then if self._forced_explosion_countdown_timer then
self._forced_explosion_countdown_timer = self._forced_explosion_countdown_timer - dtime self._forced_explosion_countdown_timer = self._forced_explosion_countdown_timer - dtime
if self._forced_explosion_countdown_timer <= 0 then if self._forced_explosion_countdown_timer <= 0 then
mobs:boom(self, mcl_util.get_object_center(self.object), self.explosion_strength) mobs:boom(self, mcl_util.get_object_center(self.object), self.explosion_strength)
@ -139,8 +139,108 @@ local creeper = {
floats = 1, floats = 1,
fear_height = 4, fear_height = 4,
view_range = 16, view_range = 16,
<<<<<<< HEAD:mods/ENTITIES/mcl_mobs/mobs/creeper.lua
} }
mobs:register_mob("mobs_mc:creeper", creeper) mobs:register_mob("mobs_mc:creeper", creeper)
=======
})
mobs:register_mob("mobs_mc:creeper_charged", {
description = S("Charged Creeper"),
type = "monster",
spawn_class = "hostile",
hp_min = 20,
hp_max = 20,
xp_min = 5,
xp_max = 5,
collisionbox = {-0.3, -0.01, -0.3, 0.3, 1.69, 0.3},
pathfinding = 1,
visual = "mesh",
mesh = "mobs_mc_creeper.b3d",
--BOOM
textures = {
{"mobs_mc_creeper.png",
"mobs_mc_creeper_charge.png"},
},
visual_size = {x=3, y=3},
rotate = 270,
sounds = {
attack = "tnt_ignite",
death = "mobs_mc_creeper_death",
damage = "mobs_mc_creeper_hurt",
fuse = "tnt_ignite",
explode = "tnt_explode",
distance = 16,
},
makes_footstep_sound = false,
walk_velocity = 1.05,
run_velocity = 2.1,
runaway_from = { "mobs_mc:ocelot", "mobs_mc:cat" },
attack_type = "explode",
explosion_strength = 6,
--explosion_radius = 3,
--explosion_damage_radius = 6,
--explosiontimer_reset_radius = 3,
reach = 1.5,
defuse_reach = 4,
explosion_timer = 0.3,
allow_fuse_reset = true,
stop_to_explode = true,
-- Force-ignite creeper with flint and steel and explode after 1.5 seconds.
-- TODO: Make creeper flash after doing this as well.
-- TODO: Test and debug this code.
on_rightclick = function(self, clicker)
if self._forced_explosion_countdown_timer then
return
end
local item = clicker:get_wielded_item()
if item:get_name() == mobs_mc.items.flint_and_steel then
if not minetest.is_creative_enabled(clicker:get_player_name()) then
-- Wear tool
local wdef = item:get_definition()
item:add_wear(1000)
-- Tool break sound
if item:get_count() == 0 and wdef.sound and wdef.sound.breaks then
minetest.sound_play(wdef.sound.breaks, {pos = clicker:get_pos(), gain = 0.5}, true)
end
clicker:set_wielded_item(item)
end
self._forced_explosion_countdown_timer = self.explosion_timer
minetest.sound_play(self.sounds.attack, {pos = self.object:get_pos(), gain = 1, max_hear_distance = 16}, true)
end
end,
do_custom = function(self, dtime)
if self._forced_explosion_countdown_timer then
self._forced_explosion_countdown_timer = self._forced_explosion_countdown_timer - dtime
if self._forced_explosion_countdown_timer <= 0 then
mobs:boom(self, mcl_util.get_object_center(self.object), self.explosion_strength)
end
end
end,
on_die = function(self, pos, cmi_cause)
-- Drop a random music disc when killed by skeleton or stray
if cmi_cause and cmi_cause.type == "punch" then
local luaentity = cmi_cause.puncher and cmi_cause.puncher:get_luaentity()
if luaentity and luaentity.name:find("arrow") then
local shooter_luaentity = luaentity._shooter and luaentity._shooter:get_luaentity()
if shooter_luaentity and (shooter_luaentity.name == "mobs_mc:skeleton" or shooter_luaentity.name == "mobs_mc:stray") then
minetest.add_item({x=pos.x, y=pos.y+1, z=pos.z}, mobs_mc.items.music_discs[math.random(1, #mobs_mc.items.music_discs)])
end
end
end
end,
maxdrops = 2,
drops = {
{name = mobs_mc.items.gunpowder,
chance = 1,
min = 0,
max = 2,
looting = "common",},
>>>>>>> master:mods/ENTITIES/mobs_mc/creeper.lua
local creeper_charged = table.copy(creeper) local creeper_charged = table.copy(creeper)
creeper_charged.description = S("Charged Creeper") creeper_charged.description = S("Charged Creeper")

@ -4,7 +4,7 @@
--################### GUARDIAN --################### GUARDIAN
--################### --###################
local S = minetest.get_translator("mobs_mc") local S = minetest.get_translator(minetest.get_current_modname())
mobs:register_mob("mobs_mc:guardian_elder", { mobs:register_mob("mobs_mc:guardian_elder", {
description = S("Elder Guardian"), description = S("Elder Guardian"),
@ -104,7 +104,6 @@ mobs:register_mob("mobs_mc:guardian_elder", {
makes_footstep_sound = false, makes_footstep_sound = false,
fly_in = { mobs_mc.items.water_source, mobs_mc.items.river_water_source }, fly_in = { mobs_mc.items.water_source, mobs_mc.items.river_water_source },
jump = false, jump = false,
view_range = 16,
}) })
-- Spawning disabled due to size issues <- what do you mean? -j4i -- Spawning disabled due to size issues <- what do you mean? -j4i

@ -2,7 +2,7 @@
--################### ENDERDRAGON --################### ENDERDRAGON
--################### --###################
local S = minetest.get_translator("mobs_mc") local S = minetest.get_translator(minetest.get_current_modname())
mobs:register_mob("mobs_mc:enderdragon", { mobs:register_mob("mobs_mc:enderdragon", {
description = S("Ender Dragon"), description = S("Ender Dragon"),
@ -24,7 +24,6 @@ mobs:register_mob("mobs_mc:enderdragon", {
xp_max = 500, xp_max = 500,
collisionbox = {-2, 0, -2, 2, 2, 2}, collisionbox = {-2, 0, -2, 2, 2, 2},
eye_height = 1, eye_height = 1,
physical = false,
visual = "mesh", visual = "mesh",
mesh = "mobs_mc_dragon.b3d", mesh = "mobs_mc_dragon.b3d",
textures = { textures = {
@ -60,8 +59,6 @@ mobs:register_mob("mobs_mc:enderdragon", {
arrow = "mobs_mc:dragon_fireball", arrow = "mobs_mc:dragon_fireball",
shoot_interval = 0.5, shoot_interval = 0.5,
shoot_offset = -1.0, shoot_offset = -1.0,
xp_min = 500,
xp_max = 500,
animation = { animation = {
fly_speed = 8, stand_speed = 8, fly_speed = 8, stand_speed = 8,
stand_start = 0, stand_end = 20, stand_start = 0, stand_end = 20,
@ -114,8 +111,8 @@ mobs:register_mob("mobs_mc:enderdragon", {
fire_resistant = true, fire_resistant = true,
}) })
--TODO: replace this setting by a proper gamerules system
local mobs_griefing = minetest.settings:get_bool("mobs_griefing") ~= false local mobs_griefing = minetest.settings:get_bool("mobs_griefing", true)
-- dragon fireball (projectile) -- dragon fireball (projectile)
mobs:register_arrow("mobs_mc:dragon_fireball", { mobs:register_arrow("mobs_mc:dragon_fireball", {
@ -143,7 +140,9 @@ mobs:register_arrow("mobs_mc:dragon_fireball", {
-- node hit, explode -- node hit, explode
hit_node = function(self, pos, node) hit_node = function(self, pos, node)
--mobs:boom(self, pos, 2) --mobs:boom(self, pos, 2)
mcl_explosions.explode(self.object:get_pos(), 2,{ drop_chance = 1.0 }) if mobs_griefing then
mcl_explosions.explode(self.object:get_pos(), 2, { drop_chance = 1.0 })
end
end end
}) })

@ -24,9 +24,11 @@
-- added rain damage. -- added rain damage.
-- fixed the grass_with_dirt issue. -- fixed the grass_with_dirt issue.
local S = minetest.get_translator("mobs_mc") local S = minetest.get_translator(minetest.get_current_modname())
local telesound = function(pos, is_source) local vector = vector
local function telesound(pos, is_source)
local snd local snd
if is_source then if is_source then
snd = "mobs_mc_enderman_teleport_src" snd = "mobs_mc_enderman_teleport_src"
@ -302,7 +304,7 @@ mobs:register_mob("mobs_mc:enderman", {
if self.attacking then if self.attacking then
local target = self.attacking local target = self.attacking
local pos = target:get_pos() local pos = target:get_pos()
if pos ~= nil then if pos then
if vector.distance(self.object:get_pos(), target:get_pos()) > 10 then if vector.distance(self.object:get_pos(), target:get_pos()) > 10 then
self:teleport(target) self:teleport(target)
end end
@ -318,12 +320,12 @@ mobs:register_mob("mobs_mc:enderman", {
for n = 1, #objs do for n = 1, #objs do
local obj = objs[n] local obj = objs[n]
if obj then if obj then
if minetest.is_player(obj) then --if minetest.is_player(obj) then
-- Warp from players during day. -- Warp from players during day.
--if (minetest.get_timeofday() * 24000) > 5001 and (minetest.get_timeofday() * 24000) < 19000 then --if (minetest.get_timeofday() * 24000) > 5001 and (minetest.get_timeofday() * 24000) < 19000 then
-- self:teleport(nil) -- self:teleport(nil)
--end --end
else if not obj:is_player() then
local lua = obj:get_luaentity() local lua = obj:get_luaentity()
if lua then if lua then
if lua.name == "mcl_bows:arrow_entity" or lua.name == "mcl_throwing:snowball_entity" then if lua.name == "mcl_bows:arrow_entity" or lua.name == "mcl_throwing:snowball_entity" then
@ -341,8 +343,8 @@ mobs:register_mob("mobs_mc:enderman", {
-- self:teleport(nil) -- self:teleport(nil)
-- self.state = "" -- self.state = ""
--else --else
if self.attack ~= nil and not minetest.settings:get_bool("creative_mode") then if self.attack and not minetest.settings:get_bool("creative_mode") then
self.state = 'attack' self.state = "attack"
end end
--end --end
end end
@ -459,7 +461,7 @@ mobs:register_mob("mobs_mc:enderman", {
end end
end end
end end
elseif self._taken_node ~= nil and self._taken_node ~= "" and self._take_place_timer >= self._next_take_place_time then elseif self._taken_node and self._taken_node ~= "" and self._take_place_timer >= self._next_take_place_time then
-- Place taken node -- Place taken node
self._take_place_timer = 0 self._take_place_timer = 0
self._next_take_place_time = math.random(take_frequency_min, take_frequency_max) self._next_take_place_time = math.random(take_frequency_min, take_frequency_max)
@ -485,12 +487,12 @@ mobs:register_mob("mobs_mc:enderman", {
end end
end, end,
do_teleport = function(self, target) do_teleport = function(self, target)
if target ~= nil then if target then
local target_pos = target:get_pos() local target_pos = target:get_pos()
-- Find all solid nodes below air in a 10×10×10 cuboid centered on the target -- Find all solid nodes below air in a 10×10×10 cuboid centered on the target
local nodes = minetest.find_nodes_in_area_under_air(vector.subtract(target_pos, 5), vector.add(target_pos, 5), {"group:solid", "group:cracky", "group:crumbly"}) local nodes = minetest.find_nodes_in_area_under_air(vector.subtract(target_pos, 5), vector.add(target_pos, 5), {"group:solid", "group:cracky", "group:crumbly"})
local telepos local telepos
if nodes ~= nil then if nodes then
if #nodes > 0 then if #nodes > 0 then
-- Up to 64 attempts to teleport -- Up to 64 attempts to teleport
for n=1, math.min(64, #nodes) do for n=1, math.min(64, #nodes) do
@ -525,7 +527,7 @@ mobs:register_mob("mobs_mc:enderman", {
-- We need to add (or subtract) different random numbers to each vector component, so it couldn't be done with a nice single vector.add() or .subtract(): -- We need to add (or subtract) different random numbers to each vector component, so it couldn't be done with a nice single vector.add() or .subtract():
local randomCube = vector.new( pos.x + 8*(pr:next(0,16)-8), pos.y + 8*(pr:next(0,16)-8), pos.z + 8*(pr:next(0,16)-8) ) local randomCube = vector.new( pos.x + 8*(pr:next(0,16)-8), pos.y + 8*(pr:next(0,16)-8), pos.z + 8*(pr:next(0,16)-8) )
local nodes = minetest.find_nodes_in_area_under_air(vector.subtract(randomCube, 4), vector.add(randomCube, 4), {"group:solid", "group:cracky", "group:crumbly"}) local nodes = minetest.find_nodes_in_area_under_air(vector.subtract(randomCube, 4), vector.add(randomCube, 4), {"group:solid", "group:cracky", "group:crumbly"})
if nodes ~= nil then if nodes then
if #nodes > 0 then if #nodes > 0 then
-- Up to 8 low-level (in total up to 8*8 = 64) attempts to teleport -- Up to 8 low-level (in total up to 8*8 = 64) attempts to teleport
for n=1, math.min(8, #nodes) do for n=1, math.min(8, #nodes) do
@ -557,13 +559,13 @@ mobs:register_mob("mobs_mc:enderman", {
end, end,
on_die = function(self, pos) on_die = function(self, pos)
-- Drop carried node on death -- Drop carried node on death
if self._taken_node ~= nil and self._taken_node ~= "" then if self._taken_node and self._taken_node ~= "" then
minetest.add_item(pos, self._taken_node) minetest.add_item(pos, self._taken_node)
end end
end, end,
do_punch = function(self, hitter, tflp, tool_caps, dir) do_punch = function(self, hitter, tflp, tool_caps, dir)
-- damage from rain caused by itself so we don't want it to attack itself. -- damage from rain caused by itself so we don't want it to attack itself.
if hitter ~= self.object and hitter ~= nil then if hitter ~= self.object and hitter then
--if (minetest.get_timeofday() * 24000) > 5001 and (minetest.get_timeofday() * 24000) < 19000 then --if (minetest.get_timeofday() * 24000) > 5001 and (minetest.get_timeofday() * 24000) < 19000 then
-- self:teleport(nil) -- self:teleport(nil)
--else --else

@ -2,7 +2,7 @@
--################### ENDERMITE --################### ENDERMITE
--################### --###################
local S = minetest.get_translator("mobs_mc") local S = minetest.get_translator(minetest.get_current_modname())
mobs:register_mob("mobs_mc:endermite", { mobs:register_mob("mobs_mc:endermite", {
description = S("Endermite"), description = S("Endermite"),

@ -3,7 +3,7 @@
--made for MC like Survival game --made for MC like Survival game
--License for code WTFPL and otherwise stated in readmes --License for code WTFPL and otherwise stated in readmes
local S = minetest.get_translator("mobs_mc") local S = minetest.get_translator(minetest.get_current_modname())
--################### --###################
--################### EVOKER --################### EVOKER

@ -3,7 +3,7 @@
--made for MC like Survival game --made for MC like Survival game
--License for code WTFPL and otherwise stated in readmes --License for code WTFPL and otherwise stated in readmes
local S = minetest.get_translator("mobs_mc") local S = minetest.get_translator(minetest.get_current_modname())
--################### --###################
--################### GHAST --################### GHAST

@ -2,7 +2,7 @@
--################### GUARDIAN --################### GUARDIAN
--################### --###################
local S = minetest.get_translator("mobs_mc") local S = minetest.get_translator(minetest.get_current_modname())
mobs:register_mob("mobs_mc:guardian", { mobs:register_mob("mobs_mc:guardian", {
description = S("Guardian"), description = S("Guardian"),
@ -94,7 +94,6 @@ mobs:register_mob("mobs_mc:guardian", {
makes_footstep_sound = false, makes_footstep_sound = false,
fly_in = { mobs_mc.items.water_source, mobs_mc.items.river_water_source }, fly_in = { mobs_mc.items.water_source, mobs_mc.items.river_water_source },
jump = false, jump = false,
view_range = 16,
}) })
-- Spawning disabled due to size issues -- Spawning disabled due to size issues

@ -3,7 +3,7 @@
--made for MC like Survival game --made for MC like Survival game
--License for code WTFPL and otherwise stated in readmes --License for code WTFPL and otherwise stated in readmes
local S = minetest.get_translator("mobs_mc") local S = minetest.get_translator(minetest.get_current_modname())
--################### --###################
--################### HORSE --################### HORSE
@ -38,9 +38,9 @@ end
local can_equip_horse_armor = function(entity_id) local can_equip_horse_armor = function(entity_id)
return entity_id == "mobs_mc:horse" or entity_id == "mobs_mc:skeleton_horse" or entity_id == "mobs_mc:zombie_horse" return entity_id == "mobs_mc:horse" or entity_id == "mobs_mc:skeleton_horse" or entity_id == "mobs_mc:zombie_horse"
end end
local can_equip_chest = function(entity_id) --[[local can_equip_chest = function(entity_id)
return entity_id == "mobs_mc:mule" or entity_id == "mobs_mc:donkey" return entity_id == "mobs_mc:mule" or entity_id == "mobs_mc:donkey"
end end]]
local can_breed = function(entity_id) local can_breed = function(entity_id)
return entity_id == "mobs_mc:horse" or "mobs_mc:mule" or entity_id == "mobs_mc:donkey" return entity_id == "mobs_mc:horse" or "mobs_mc:mule" or entity_id == "mobs_mc:donkey"
end end
@ -313,7 +313,7 @@ local horse = {
-- Make sure tamed horse is mature and being clicked by owner only -- Make sure tamed horse is mature and being clicked by owner only
if self.tamed and not self.child and self.owner == clicker:get_player_name() then if self.tamed and not self.child and self.owner == clicker:get_player_name() then
local inv = clicker:get_inventory() --local inv = clicker:get_inventory()
-- detatch player already riding horse -- detatch player already riding horse
if self.driver and clicker == self.driver then if self.driver and clicker == self.driver then

@ -3,8 +3,8 @@
--made for MC like Survival game --made for MC like Survival game
--License for code WTFPL and otherwise stated in readmes --License for code WTFPL and otherwise stated in readmes
local S = minetest.get_translator("mobs_mc") local S = minetest.get_translator(minetest.get_current_modname())
local mod_bows = minetest.get_modpath("mcl_bows") ~= nil local mod_bows = minetest.get_modpath("mcl_bows")
mobs:register_mob("mobs_mc:illusioner", { mobs:register_mob("mobs_mc:illusioner", {
description = S("Illusioner"), description = S("Illusioner"),

@ -3,7 +3,7 @@
--made for MC like Survival game --made for MC like Survival game
--License for code WTFPL and otherwise stated in readmes --License for code WTFPL and otherwise stated in readmes
local S = minetest.get_translator("mobs_mc") local S = minetest.get_translator(minetest.get_current_modname())
--################### --###################
--################### IRON GOLEM --################### IRON GOLEM
@ -158,11 +158,11 @@ mobs_mc.tools.check_iron_golem_summon = function(pos)
if ok then if ok then
-- Remove the nodes -- Remove the nodes
minetest.remove_node(pos) minetest.remove_node(pos)
core.check_for_falling(pos) minetest.check_for_falling(pos)
for i=1, 4 do for i=1, 4 do
local cpos = vector.add(pos, checks[c][i]) local cpos = vector.add(pos, checks[c][i])
minetest.remove_node(cpos) minetest.remove_node(cpos)
core.check_for_falling(cpos) minetest.check_for_falling(cpos)
end end
-- Summon iron golem -- Summon iron golem
local place local place

@ -1,4 +1,4 @@
local S = minetest.get_translator("mobs_mc") local S = minetest.get_translator(minetest.get_current_modname())
--################### --###################
--################### LLAMA --################### LLAMA
@ -306,9 +306,9 @@ mobs:register_arrow("mobs_mc:spit", {
tail_distance_divider = 4, tail_distance_divider = 4,
hit_player = function(self, player) hit_player = function(self, player)
if rawget(_G, "armor") and armor.last_damage_types then --[[if rawget(_G, "armor") and armor.last_damage_types then
armor.last_damage_types[player:get_player_name()] = "spit" armor.last_damage_types[player:get_player_name()] = "spit"
end end]]
player:punch(self.object, 1.0, { player:punch(self.object, 1.0, {
full_punch_interval = 1.0, full_punch_interval = 1.0,
damage_groups = {fleshy = self._damage}, damage_groups = {fleshy = self._damage},
@ -318,7 +318,7 @@ mobs:register_arrow("mobs_mc:spit", {
hit_mob = function(self, mob) hit_mob = function(self, mob)
mob:punch(self.object, 1.0, { mob:punch(self.object, 1.0, {
full_punch_interval = 1.0, full_punch_interval = 1.0,
damage_groups = {fleshy = _damage}, damage_groups = {fleshy = self._damage},
}, nil) }, nil)
end, end,

@ -3,7 +3,7 @@
--made for MC like Survival game --made for MC like Survival game
--License for code WTFPL and otherwise stated in readmes --License for code WTFPL and otherwise stated in readmes
local S = minetest.get_translator("mobs_mc") local S = minetest.get_translator(minetest.get_current_modname())
--################### --###################
--################### OCELOT AND CAT --################### OCELOT AND CAT
@ -151,7 +151,7 @@ end
mobs:register_mob("mobs_mc:cat", cat) mobs:register_mob("mobs_mc:cat", cat)
local base_spawn_chance = 5000 --local base_spawn_chance = 5000
-- Spawn ocelot -- Spawn ocelot
--they get the same as the llama because I'm trying to rework so much of this code right now -j4i --they get the same as the llama because I'm trying to rework so much of this code right now -j4i

@ -3,7 +3,7 @@
--made for MC like Survival game --made for MC like Survival game
--License for code WTFPL and otherwise stated in readmes --License for code WTFPL and otherwise stated in readmes
local S = minetest.get_translator("mobs_mc") local S = minetest.get_translator(minetest.get_current_modname())
--################### --###################
--################### PARROT --################### PARROT

@ -1,6 +1,6 @@
--License for code WTFPL and otherwise stated in readmes --License for code WTFPL and otherwise stated in readmes
local S = minetest.get_translator("mobs_mc") local S = minetest.get_translator(minetest.get_current_modname())
mobs:register_mob("mobs_mc:pig", { mobs:register_mob("mobs_mc:pig", {
description = S("Pig"), description = S("Pig"),
@ -162,7 +162,7 @@ mobs:register_mob("mobs_mc:pig", {
end end
-- Mount or detach player -- Mount or detach player
local name = clicker:get_player_name() --local name = clicker:get_player_name()
if self.driver and clicker == self.driver then if self.driver and clicker == self.driver then
-- Detach if already attached -- Detach if already attached
mobs.detach(clicker, {x=1, y=0, z=0}) mobs.detach(clicker, {x=1, y=0, z=0})

@ -1,6 +1,6 @@
--License for code WTFPL and otherwise stated in readmes --License for code WTFPL and otherwise stated in readmes
local S = minetest.get_translator("mobs_mc") local S = minetest.get_translator(minetest.get_current_modname())
--################### --###################
--################### POLARBEAR --################### POLARBEAR

@ -1,6 +1,6 @@
--License for code WTFPL and otherwise stated in readmes --License for code WTFPL and otherwise stated in readmes
local S = minetest.get_translator("mobs_mc") local S = minetest.get_translator(minetest.get_current_modname())
local rabbit = { local rabbit = {
description = S("Rabbit"), description = S("Rabbit"),
@ -233,4 +233,4 @@ mobs:spawn(spawn_grass)
mobs:register_egg("mobs_mc:rabbit", S("Rabbit"), "mobs_mc_spawn_icon_rabbit.png", 0) mobs:register_egg("mobs_mc:rabbit", S("Rabbit"), "mobs_mc_spawn_icon_rabbit.png", 0)
-- Note: This spawn egg does not exist in Minecraft -- Note: This spawn egg does not exist in Minecraft
mobs:register_egg("mobs_mc:killer_bunny", S("Killer Bunny"), "mobs_mc_spawn_icon_rabbit.png^[colorize:#FF0000:192", 0) -- TODO: Update inventory image mobs:register_egg("mobs_mc:killer_bunny", S("Killer Bunny"), "mobs_mc_spawn_icon_rabbit_caerbannog.png", 0)

@ -1,6 +1,6 @@
--License for code WTFPL and otherwise stated in readmes --License for code WTFPL and otherwise stated in readmes
local S = minetest.get_translator("mobs_mc") local S = minetest.get_translator(minetest.get_current_modname())
--################### --###################
--################### SHEEP --################### SHEEP
@ -142,7 +142,6 @@ mobs:register_mob("mobs_mc:sheep", {
do_custom = function(self, dtime) do_custom = function(self, dtime)
if not self.initial_color_set then if not self.initial_color_set then
local r = math.random(0,100000) local r = math.random(0,100000)
local textures
if r <= 81836 then if r <= 81836 then
-- 81.836% -- 81.836%
self.color = "unicolor_white" self.color = "unicolor_white"

@ -3,7 +3,7 @@
--made for MC like Survival game --made for MC like Survival game
--License for code WTFPL and otherwise stated in readmes --License for code WTFPL and otherwise stated in readmes
local S = minetest.get_translator("mobs_mc") local S = minetest.get_translator(minetest.get_current_modname())
--################### --###################
--################### SHULKER --################### SHULKER

@ -2,7 +2,7 @@
--################### SILVERFISH --################### SILVERFISH
--################### --###################
local S = minetest.get_translator("mobs_mc") local S = minetest.get_translator(minetest.get_current_modname())
mobs:register_mob("mobs_mc:silverfish", { mobs:register_mob("mobs_mc:silverfish", {
description = S("Silverfish"), description = S("Silverfish"),
@ -46,7 +46,6 @@ mobs:register_mob("mobs_mc:silverfish", {
view_range = 16, view_range = 16,
attack_type = "punch", attack_type = "punch",
damage = 1, damage = 1,
reach = 1,
}) })
mobs:register_egg("mobs_mc:silverfish", S("Silverfish"), "mobs_mc_spawn_icon_silverfish.png", 0) mobs:register_egg("mobs_mc:silverfish", S("Silverfish"), "mobs_mc_spawn_icon_silverfish.png", 0)
@ -62,7 +61,7 @@ if minetest.get_modpath("default") and mobs_mc.create_monster_egg_nodes then
description = "Stone Monster Egg", description = "Stone Monster Egg",
tiles = {"default_stone.png"}, tiles = {"default_stone.png"},
groups = {oddly_breakable_by_hand = 2, spawns_silverfish = 1}, groups = {oddly_breakable_by_hand = 2, spawns_silverfish = 1},
drop = '', drop = "",
is_ground_content = true, is_ground_content = true,
sounds = default.node_sound_stone_defaults(), sounds = default.node_sound_stone_defaults(),
after_dig_node = spawn_silverfish, after_dig_node = spawn_silverfish,
@ -73,7 +72,7 @@ if minetest.get_modpath("default") and mobs_mc.create_monster_egg_nodes then
tiles = {"default_cobble.png"}, tiles = {"default_cobble.png"},
is_ground_content = false, is_ground_content = false,
groups = {oddly_breakable_by_hand = 2, spawns_silverfish = 1}, groups = {oddly_breakable_by_hand = 2, spawns_silverfish = 1},
drop = '', drop = "",
sounds = default.node_sound_stone_defaults(), sounds = default.node_sound_stone_defaults(),
after_dig_node = spawn_silverfish, after_dig_node = spawn_silverfish,
}) })
@ -83,7 +82,7 @@ if minetest.get_modpath("default") and mobs_mc.create_monster_egg_nodes then
tiles = {"default_mossycobble.png"}, tiles = {"default_mossycobble.png"},
is_ground_content = false, is_ground_content = false,
groups = {oddly_breakable_by_hand = 2, spawns_silverfish = 1}, groups = {oddly_breakable_by_hand = 2, spawns_silverfish = 1},
drop = '', drop = "",
sounds = default.node_sound_stone_defaults(), sounds = default.node_sound_stone_defaults(),
after_dig_node = spawn_silverfish, after_dig_node = spawn_silverfish,
}) })
@ -95,7 +94,7 @@ if minetest.get_modpath("default") and mobs_mc.create_monster_egg_nodes then
tiles = {"default_stone_brick.png"}, tiles = {"default_stone_brick.png"},
is_ground_content = false, is_ground_content = false,
groups = {oddly_breakable_by_hand = 2, spawns_silverfish = 1}, groups = {oddly_breakable_by_hand = 2, spawns_silverfish = 1},
drop = '', drop = "",
sounds = default.node_sound_stone_defaults(), sounds = default.node_sound_stone_defaults(),
after_dig_node = spawn_silverfish, after_dig_node = spawn_silverfish,
}) })
@ -105,7 +104,7 @@ if minetest.get_modpath("default") and mobs_mc.create_monster_egg_nodes then
tiles = {"default_stone_block.png"}, tiles = {"default_stone_block.png"},
is_ground_content = false, is_ground_content = false,
groups = {oddly_breakable_by_hand = 2, spawns_silverfish = 1}, groups = {oddly_breakable_by_hand = 2, spawns_silverfish = 1},
drop = '', drop = "",
sounds = default.node_sound_stone_defaults(), sounds = default.node_sound_stone_defaults(),
after_dig_node = spawn_silverfish, after_dig_node = spawn_silverfish,
}) })

@ -3,8 +3,8 @@
--made for MC like Survival game --made for MC like Survival game
--License for code WTFPL and otherwise stated in readmes --License for code WTFPL and otherwise stated in readmes
local S = minetest.get_translator("mobs_mc") local S = minetest.get_translator(minetest.get_current_modname())
local mod_bows = minetest.get_modpath("mcl_bows") ~= nil local mod_bows = minetest.get_modpath("mcl_bows")
--################### --###################
--################### SKELETON --################### SKELETON
@ -31,10 +31,6 @@ local skeleton = {
group_attack = true, group_attack = true,
visual = "mesh", visual = "mesh",
mesh = "mobs_mc_skeleton.b3d", mesh = "mobs_mc_skeleton.b3d",
textures = { {
"mcl_bows_bow_0.png", -- bow
"mobs_mc_skeleton.png", -- skeleton
} },
--head code --head code
has_head = false, has_head = false,

@ -1,6 +1,6 @@
--License for code WTFPL and otherwise stated in readmes --License for code WTFPL and otherwise stated in readmes
local S = minetest.get_translator("mobs_mc") local S = minetest.get_translator(minetest.get_current_modname())
-- Returns a function that spawns children in a circle around pos. -- Returns a function that spawns children in a circle around pos.
-- To be used as on_die callback. -- To be used as on_die callback.
@ -41,10 +41,10 @@ local spawn_children_on_die = function(child_mob, children_count, spawn_distance
-- If mother was murdered, children attack the killer after 1 second -- If mother was murdered, children attack the killer after 1 second
if self.state == "attack" then if self.state == "attack" then
minetest.after(1.0, function(children, enemy) minetest.after(1.0, function(children, enemy)
for c=1, #children do for c = 1, #children do
local child = children[c] local child = children[c]
local le = child:get_luaentity() local le = child:get_luaentity()
if le ~= nil then if le then
le.state = "attack" le.state = "attack"
le.attack = enemy le.attack = enemy
end end

@ -3,12 +3,12 @@
--made for MC like Survival game --made for MC like Survival game
--License for code WTFPL and otherwise stated in readmes --License for code WTFPL and otherwise stated in readmes
local S = minetest.get_translator("mobs_mc") local S = minetest.get_translator(minetest.get_current_modname())
local snow_trail_frequency = 0.5 -- Time in seconds for checking to add a new snow trail local snow_trail_frequency = 0.5 -- Time in seconds for checking to add a new snow trail
local mobs_griefing = minetest.settings:get_bool("mobs_griefing") ~= false local mobs_griefing = minetest.settings:get_bool("mobs_griefing") ~= false
local mod_throwing = minetest.get_modpath("mcl_throwing") ~= nil local mod_throwing = minetest.get_modpath("mcl_throwing")
local gotten_texture = { local gotten_texture = {
"mobs_mc_snowman.png", "mobs_mc_snowman.png",
@ -179,9 +179,9 @@ mobs_mc.tools.check_snow_golem_summon = function(pos)
minetest.remove_node(pos) minetest.remove_node(pos)
minetest.remove_node(b1) minetest.remove_node(b1)
minetest.remove_node(b2) minetest.remove_node(b2)
core.check_for_falling(pos) minetest.check_for_falling(pos)
core.check_for_falling(b1) minetest.check_for_falling(b1)
core.check_for_falling(b2) minetest.check_for_falling(b2)
local obj = minetest.add_entity(place, "mobs_mc:snowman") local obj = minetest.add_entity(place, "mobs_mc:snowman")
if obj then if obj then
summon_particles(obj) summon_particles(obj)

@ -3,7 +3,7 @@
--made for MC like Survival game --made for MC like Survival game
--License for code WTFPL and otherwise stated in readmes --License for code WTFPL and otherwise stated in readmes
local S = minetest.get_translator("mobs_mc") local S = minetest.get_translator(minetest.get_current_modname())
--################### --###################
--################### SPIDER --################### SPIDER

@ -4,7 +4,7 @@
--################### SQUID --################### SQUID
--################### --###################
local S = minetest.get_translator("mobs_mc") local S = minetest.get_translator(minetest.get_current_modname())
mobs:register_mob("mobs_mc:squid", { mobs:register_mob("mobs_mc:squid", {
description = S("Squid"), description = S("Squid"),

@ -3,7 +3,7 @@
--made for MC like Survival game --made for MC like Survival game
--License for code WTFPL and otherwise stated in readmes --License for code WTFPL and otherwise stated in readmes
local S = minetest.get_translator("mobs_mc") local S = minetest.get_translator(minetest.get_current_modname())
--################### --###################
--################### VEX --################### VEX
@ -15,7 +15,7 @@ mobs:register_mob("mobs_mc:vex", {
spawn_class = "hostile", spawn_class = "hostile",
pathfinding = 1, pathfinding = 1,
passive = false, passive = false,
attack_type = "punch", attack_type = "dogfight",
physical = false, physical = false,
hp_min = 14, hp_min = 14,
hp_max = 14, hp_max = 14,
@ -36,7 +36,6 @@ mobs:register_mob("mobs_mc:vex", {
view_range = 16, view_range = 16,
walk_velocity = 3.2, walk_velocity = 3.2,
run_velocity = 5.9, run_velocity = 5.9,
attack_type = "dogfight",
sounds = { sounds = {
-- TODO: random -- TODO: random
death = "mobs_mc_vex_death", death = "mobs_mc_vex_death",

@ -19,7 +19,7 @@
-- TODO: Internal inventory, pick up items, trade with other villagers -- TODO: Internal inventory, pick up items, trade with other villagers
-- TODO: Farm stuff -- TODO: Farm stuff
local S = minetest.get_translator("mobs_mc") local S = minetest.get_translator(minetest.get_current_modname())
local N = function(s) return s end local N = function(s) return s end
local F = minetest.formspec_escape local F = minetest.formspec_escape

@ -3,7 +3,7 @@
--made for MC like Survival game --made for MC like Survival game
--License for code WTFPL and otherwise stated in readmes --License for code WTFPL and otherwise stated in readmes
local S = minetest.get_translator("mobs_mc") local S = minetest.get_translator(minetest.get_current_modname())
--################### --###################
--################### VINDICATOR --################### VINDICATOR

@ -3,7 +3,7 @@
--made for MC like Survival game --made for MC like Survival game
--License for code WTFPL and otherwise stated in readmes --License for code WTFPL and otherwise stated in readmes
local S = minetest.get_translator("mobs_mc") local S = minetest.get_translator(minetest.get_current_modname())
--################### --###################
--################### WITCH --################### WITCH

@ -3,7 +3,7 @@
--made for MC like Survival game --made for MC like Survival game
--License for code WTFPL and otherwise stated in readmes --License for code WTFPL and otherwise stated in readmes
local S = minetest.get_translator("mobs_mc") local S = minetest.get_translator(minetest.get_current_modname())
--################### --###################
--################### WITHER --################### WITHER
@ -26,7 +26,6 @@ mobs:register_mob("mobs_mc:wither", {
{"mobs_mc_wither.png"}, {"mobs_mc_wither.png"},
}, },
visual_size = {x=4, y=4}, visual_size = {x=4, y=4},
makes_footstep_sound = true,
view_range = 16, view_range = 16,
fear_height = 4, fear_height = 4,
walk_velocity = 2, walk_velocity = 2,
@ -80,7 +79,7 @@ mobs:register_mob("mobs_mc:wither", {
end, end,
}) })
local mobs_griefing = minetest.settings:get_bool("mobs_griefing") ~= false --local mobs_griefing = minetest.settings:get_bool("mobs_griefing") ~= false
mobs:register_arrow("mobs_mc:wither_skull", { mobs:register_arrow("mobs_mc:wither_skull", {
visual = "sprite", visual = "sprite",

@ -3,7 +3,7 @@
--made for MC like Survival game --made for MC like Survival game
--License for code WTFPL and otherwise stated in readmes --License for code WTFPL and otherwise stated in readmes
local S = minetest.get_translator("mobs_mc") local S = minetest.get_translator(minetest.get_current_modname())
--################### --###################
--################### WITHER SKELETON --################### WITHER SKELETON

@ -1,6 +1,6 @@
--License for code WTFPL and otherwise stated in readmes --License for code WTFPL and otherwise stated in readmes
local S = minetest.get_translator("mobs_mc") local S = minetest.get_translator(minetest.get_current_modname())
local default_walk_chance = 50 local default_walk_chance = 50
@ -186,7 +186,7 @@ dog.on_rightclick = function(self, clicker)
if is_food(item:get_name()) then if is_food(item:get_name()) then
-- Feed to increase health -- Feed to increase health
local hp = self.health local hp = self.health
local hp_add = 0 local hp_add
-- Use eatable group to determine health boost -- Use eatable group to determine health boost
local eatable = minetest.get_item_group(item, "eatable") local eatable = minetest.get_item_group(item, "eatable")
if eatable > 0 then if eatable > 0 then

@ -3,7 +3,7 @@
--made for MC like Survival game --made for MC like Survival game
--License for code WTFPL and otherwise stated in readmes --License for code WTFPL and otherwise stated in readmes
local S = minetest.get_translator("mobs_mc") local S = minetest.get_translator(minetest.get_current_modname())
--################### --###################
--################### ZOMBIE --################### ZOMBIE

@ -3,7 +3,7 @@
--made for MC like Survival game --made for MC like Survival game
--License for code WTFPL and otherwise stated in readmes --License for code WTFPL and otherwise stated in readmes
local S = minetest.get_translator("mobs_mc") local S = minetest.get_translator(minetest.get_current_modname())
--################### --###################
--################### ZOMBIE PIGMAN --################### ZOMBIE PIGMAN

@ -3,7 +3,7 @@
--made for MC like Survival game --made for MC like Survival game
--License for code WTFPL and otherwise stated in readmes --License for code WTFPL and otherwise stated in readmes
local S = minetest.get_translator("mobs_mc") local S = minetest.get_translator(minetest.get_current_modname())
--################### --###################
--################### ZOMBIE VILLAGER --################### ZOMBIE VILLAGER

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.9 KiB

@ -34,7 +34,7 @@ function mcl_mount.mount(obj, parent, animation)
obj:set_look_horizontal(parent:get_yaw()) obj:set_look_horizontal(parent:get_yaw())
mcl_mount.mounted[obj] = true mcl_mount.mounted[obj] = true
mcl_player.player_set_animation(obj, animation or "sit", 30) mcl_player.player_set_animation(obj, animation or "sit", 30)
mcl_tmp_message.message(obj, S("Sneak to dismount")) mcl_title.set(obj, "actionbar", {text = S("Sneak to dismount"), color = "white", stay = 60})
end end
mcl_mount.update_visual_size(obj) mcl_mount.update_visual_size(obj)

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

@ -0,0 +1,2 @@
# textdomain:mcl_paintings
Painting=Obraz

@ -0,0 +1,31 @@
# lightning
Lightning mod for MineClone2 with the following API:
## lightning.register_on_strike(function(pos, pos2, objects))
Custom function called when a lightning strikes.
* `pos`: impact position
* `pos2`: rounded node position where fire is placed
* `objects`: table with ObjectRefs of all objects within a radius of 3.5 around pos2
## lightning.strike(pos)
Let a lightning strike.
* `pos`: optional, if not given a random pos will be chosen
* `returns`: bool - success if a strike happened
### Examples:
```
lightning.register_on_strike(function(pos, pos2, objects)
for _, obj in pairs(objects) do
obj:remove()
end
minetest.add_entity(pos, "mobs_mc:sheep")
end)
minetest.register_on_respawnplayer(function(player)
lightning.strike(player:get_pos())
end)
```

@ -1,6 +1,7 @@
--[[ --[[
Copyright (C) 2016 - Auke Kok <sofar@foo-projects.org> Copyright (C) 2016 - Auke Kok <sofar@foo-projects.org>
Adapted by MineClone2 contributors
"lightning" is free software; you can redistribute it and/or modify "lightning" is free software; you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as it under the terms of the GNU Lesser General Public License as
@ -9,7 +10,7 @@ of the license, or (at your option) any later version.
--]] --]]
local S = minetest.get_translator("lightning") local S = minetest.get_translator(minetest.get_current_modname())
local get_connected_players = minetest.get_connected_players local get_connected_players = minetest.get_connected_players
local line_of_sight = minetest.line_of_sight local line_of_sight = minetest.line_of_sight
@ -22,22 +23,23 @@ local add_entity = minetest.add_entity
local get_objects_inside_radius = minetest.get_objects_inside_radius local get_objects_inside_radius = minetest.get_objects_inside_radius
local get_item_group = minetest.get_item_group local get_item_group = minetest.get_item_group
lightning = {} lightning = {
interval_low = 17,
lightning.interval_low = 17 interval_high = 503,
lightning.interval_high = 503 range_h = 100,
lightning.range_h = 100 range_v = 50,
lightning.range_v = 50 size = 100,
lightning.size = 100 -- disable this to stop lightning mod from striking
-- disable this to stop lightning mod from striking auto = true,
lightning.auto = true on_strike_functions = {},
}
local rng = PcgRandom(32321123312123) local rng = PcgRandom(32321123312123)
local ps = {} local ps = {}
local ttl = -1 local ttl = -1
local revertsky = function(dtime) local function revertsky(dtime)
if ttl == 0 then if ttl == 0 then
return return
end end
@ -53,6 +55,18 @@ end
minetest.register_globalstep(revertsky) minetest.register_globalstep(revertsky)
-- lightning strike API
-- See API.md
--[[
lightning.register_on_strike(function(pos, pos2, objects)
-- code
end)
]]
function lightning.register_on_strike(func)
table.insert(lightning.on_strike_functions, func)
end
-- select a random strike point, midpoint -- select a random strike point, midpoint
local function choose_pos(pos) local function choose_pos(pos)
if not pos then if not pos then
@ -78,14 +92,14 @@ local function choose_pos(pos)
pos.z = math.floor(pos.z - (lightning.range_h / 2) + rng:next(1, lightning.range_h)) pos.z = math.floor(pos.z - (lightning.range_h / 2) + rng:next(1, lightning.range_h))
end end
local b, pos2 = line_of_sight(pos, {x = pos.x, y = pos.y - lightning.range_v, z = pos.z}, 1) local b, pos2 = line_of_sight(pos, { x = pos.x, y = pos.y - lightning.range_v, z = pos.z }, 1)
-- nothing but air found -- nothing but air found
if b then if b then
return nil, nil return nil, nil
end end
local n = get_node({x = pos2.x, y = pos2.y - 1/2, z = pos2.z}) local n = get_node({ x = pos2.x, y = pos2.y - 1/2, z = pos2.z })
if n.name == "air" or n.name == "ignore" then if n.name == "air" or n.name == "ignore" then
return nil, nil return nil, nil
end end
@ -93,10 +107,9 @@ local function choose_pos(pos)
return pos, pos2 return pos, pos2
end end
-- lightning strike API
-- * pos: optional, if not given a random pos will be chosen -- * pos: optional, if not given a random pos will be chosen
-- * returns: bool - success if a strike happened -- * returns: bool - success if a strike happened
lightning.strike = function(pos) function lightning.strike(pos)
if lightning.auto then if lightning.auto then
after(rng:next(lightning.interval_low, lightning.interval_high), lightning.strike) after(rng:next(lightning.interval_low, lightning.interval_high), lightning.strike)
end end
@ -107,21 +120,28 @@ lightning.strike = function(pos)
if not pos then if not pos then
return false return false
end end
local objects = get_objects_inside_radius(pos2, 3.5)
if lightning.on_strike_functions then
for _, func in pairs(lightning.on_strike_functions) do
func(pos, pos2, objects)
end
end
end
lightning.register_on_strike(function(pos, pos2, objects)
local particle_pos = vector.offset(pos2, 0, (lightning.size / 2) + 0.5, 0)
local particle_size = lightning.size * 10
local time = 0.2
add_particlespawner({ add_particlespawner({
amount = 1, amount = 1,
time = 0.2, time = time,
-- make it hit the top of a block exactly with the bottom -- make it hit the top of a block exactly with the bottom
minpos = {x = pos2.x, y = pos2.y + (lightning.size / 2) + 1/2, z = pos2.z }, minpos = particle_pos,
maxpos = {x = pos2.x, y = pos2.y + (lightning.size / 2) + 1/2, z = pos2.z }, maxpos = particle_pos,
minvel = {x = 0, y = 0, z = 0}, minexptime = time,
maxvel = {x = 0, y = 0, z = 0}, maxexptime = time,
minacc = {x = 0, y = 0, z = 0}, minsize = particle_size,
maxacc = {x = 0, y = 0, z = 0}, maxsize = particle_size,
minexptime = 0.2,
maxexptime = 0.2,
minsize = lightning.size * 10,
maxsize = lightning.size * 10,
collisiondetection = true, collisiondetection = true,
vertical = true, vertical = true,
-- to make it appear hitting the node that will get set on fire, make sure -- to make it appear hitting the node that will get set on fire, make sure
@ -134,43 +154,27 @@ lightning.strike = function(pos)
sound_play({ name = "lightning_thunder", gain = 10 }, { pos = pos, max_hear_distance = 500 }, true) sound_play({ name = "lightning_thunder", gain = 10 }, { pos = pos, max_hear_distance = 500 }, true)
-- damage nearby objects, transform mobs -- damage nearby objects, transform mobs
local objs = get_objects_inside_radius(pos2, 3.5) for _, obj in pairs(objects) do
for o=1, #objs do
local obj = objs[o]
local lua = obj:get_luaentity() local lua = obj:get_luaentity()
-- pig → zombie pigman (no damage) if lua and lua._on_strike then
lua._on_strike(lua, pos, pos2, objects)
end
-- remove this when mob API is done
if lua and lua.name == "mcl_mobs:pig" then if lua and lua.name == "mcl_mobs:pig" then
local rot = obj:get_yaw() mcl_util.replace_mob(obj, "mobs_mc:pigman")
obj:remove()
obj = add_entity(pos2, "mcl_mobs:pigman")
obj:set_yaw(rot)
-- mooshroom: toggle color red/brown (no damage)
elseif lua and lua.name == "mcl_mobs:mooshroom" then elseif lua and lua.name == "mcl_mobs:mooshroom" then
if lua.base_texture[1] == "mcl_mobs_mooshroom.png" then if lua.base_texture[1] == "mcl_mobs_mooshroom.png" then
lua.base_texture = { "mcl_mobs_mooshroom_brown.png", "mcl_mobs_mushroom_brown.png" } lua.base_texture = { "mcl_mobs_mooshroom_brown.png", "mcl_mobs_mushroom_brown.png" }
else else
lua.base_texture = { "mcl_mobs_mooshroom.png", "mcl_mobs_mushroom_red.png" } lua.base_texture = { "mcl_mobs_mooshroom.png", "mcl_mobs_mushroom_red.png" }
end end
obj:set_properties({textures = lua.base_texture}) obj:set_properties({ textures = lua.base_texture })
-- villager → witch (no damage)
elseif lua and lua.name == "mcl_mobs:villager" then elseif lua and lua.name == "mcl_mobs:villager" then
-- Witches are incomplete, this code is unused mcl_util.replace_mob(obj, "mcl_mobs:witch")
-- TODO: Enable this code when witches are working.
--[[
local rot = obj:get_yaw()
obj:remove()
obj = minetest.add_entity(pos2, "mcl_mobs:witch")
obj:set_yaw(rot)
]]
-- charged creeper
elseif lua and lua.name == "mcl_mobs:creeper" then elseif lua and lua.name == "mcl_mobs:creeper" then
local rot = obj:get_yaw() mcl_util.replace_mob(obj, "mcl_mobs:creeper_charged")
obj:remove()
obj = add_entity(pos2, "mcl_mobs:creeper_charged")
obj:set_yaw(rot)
-- Other objects: Just damage
else else
mcl_util.deal_damage(obj, 5, {type = "lightning_bolt"}) mcl_util.deal_damage(obj, 5, { type = "lightning_bolt" })
end end
end end
@ -184,7 +188,7 @@ lightning.strike = function(pos)
local name = player:get_player_name() local name = player:get_player_name()
if ps[name] == nil then if ps[name] == nil then
ps[name] = {p = player, sky = sky} ps[name] = {p = player, sky = sky}
mcl_weather.skycolor.add_layer("lightning", {{r=255,g=255,b=255}}, true) mcl_weather.skycolor.add_layer("lightning", { { r = 255, g = 255, b = 255 } }, true)
mcl_weather.skycolor.active = true mcl_weather.skycolor.active = true
end end
end end
@ -199,7 +203,7 @@ lightning.strike = function(pos)
if rng:next(1,100) <= 3 then if rng:next(1,100) <= 3 then
skeleton_lightning = true skeleton_lightning = true
end end
if get_item_group(get_node({x = pos2.x, y = pos2.y - 1, z = pos2.z}).name, "liquid") < 1 then if get_item_group(get_node({ x = pos2.x, y = pos2.y - 1, z = pos2.z }).name, "liquid") < 1 then
if get_node(pos2).name == "air" then if get_node(pos2).name == "air" then
-- Low chance for a lightning to spawn skeleton horse + skeletons -- Low chance for a lightning to spawn skeleton horse + skeletons
if skeleton_lightning then if skeleton_lightning then
@ -208,7 +212,7 @@ lightning.strike = function(pos)
local angle, posadd local angle, posadd
angle = math.random(0, math.pi*2) angle = math.random(0, math.pi*2)
for i=1,3 do for i=1,3 do
posadd = {x=math.cos(angle),y=0,z=math.sin(angle)} posadd = { x=math.cos(angle),y=0,z=math.sin(angle) }
posadd = vector.normalize(posadd) posadd = vector.normalize(posadd)
local mob = add_entity(vector.add(pos2, posadd), "mcl_mobs:skeleton") local mob = add_entity(vector.add(pos2, posadd), "mcl_mobs:skeleton")
mob:set_yaw(angle-math.pi/2) mob:set_yaw(angle-math.pi/2)
@ -217,12 +221,11 @@ lightning.strike = function(pos)
-- Cause a fire -- Cause a fire
else else
set_node(pos2, {name = "mcl_fire:fire"}) set_node(pos2, { name = "mcl_fire:fire" })
end end
end end
end end
end)
end
-- if other mods disable auto lightning during initialization, don't trigger the first lightning. -- if other mods disable auto lightning during initialization, don't trigger the first lightning.
after(5, function(dtime) after(5, function(dtime)

@ -0,0 +1,4 @@
# textdomain: lightning
@1 was struck by lightning.=@1 została trafiona przez piorun.
Let lightning strike at the specified position or yourself=Pozwala by piorun uderzył we wskazaną pozycję lub ciebie
No position specified and unknown player=Nie wskazano pozycji i nieznany gracz

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